Merge branch 'pktdiag'
Nicolas Dichtel says: ==================== The goal of this patchset is to be able to get all infos exported via the /proc/net/packet and also beeing able to get filter associated to af_packet sockets. As usual, the patch against iproute2 will be sent once the patches are included and net-next merged. I can send it on demand. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
13ccf043ce
4 changed files with 63 additions and 5 deletions
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __SOCK_DIAG_H__
|
#ifndef __SOCK_DIAG_H__
|
||||||
#define __SOCK_DIAG_H__
|
#define __SOCK_DIAG_H__
|
||||||
|
|
||||||
|
#include <linux/user_namespace.h>
|
||||||
#include <uapi/linux/sock_diag.h>
|
#include <uapi/linux/sock_diag.h>
|
||||||
|
|
||||||
struct sk_buff;
|
struct sk_buff;
|
||||||
|
@ -22,5 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
|
||||||
void sock_diag_save_cookie(void *sk, __u32 *cookie);
|
void sock_diag_save_cookie(void *sk, __u32 *cookie);
|
||||||
|
|
||||||
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
|
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
|
||||||
|
int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
|
||||||
|
struct sk_buff *skb, int attrtype);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,8 @@ struct packet_diag_req {
|
||||||
#define PACKET_SHOW_MCLIST 0x00000002 /* A set of packet_diag_mclist-s */
|
#define PACKET_SHOW_MCLIST 0x00000002 /* A set of packet_diag_mclist-s */
|
||||||
#define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */
|
#define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */
|
||||||
#define PACKET_SHOW_FANOUT 0x00000008
|
#define PACKET_SHOW_FANOUT 0x00000008
|
||||||
|
#define PACKET_SHOW_MEMINFO 0x00000010
|
||||||
|
#define PACKET_SHOW_FILTER 0x00000020
|
||||||
|
|
||||||
struct packet_diag_msg {
|
struct packet_diag_msg {
|
||||||
__u8 pdiag_family;
|
__u8 pdiag_family;
|
||||||
|
@ -32,6 +34,9 @@ enum {
|
||||||
PACKET_DIAG_RX_RING,
|
PACKET_DIAG_RX_RING,
|
||||||
PACKET_DIAG_TX_RING,
|
PACKET_DIAG_TX_RING,
|
||||||
PACKET_DIAG_FANOUT,
|
PACKET_DIAG_FANOUT,
|
||||||
|
PACKET_DIAG_UID,
|
||||||
|
PACKET_DIAG_MEMINFO,
|
||||||
|
PACKET_DIAG_FILTER,
|
||||||
|
|
||||||
__PACKET_DIAG_MAX,
|
__PACKET_DIAG_MAX,
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,6 +49,39 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
||||||
|
|
||||||
|
int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
|
||||||
|
struct sk_buff *skb, int attrtype)
|
||||||
|
{
|
||||||
|
struct nlattr *attr;
|
||||||
|
struct sk_filter *filter;
|
||||||
|
unsigned int len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
|
||||||
|
nla_reserve(skb, attrtype, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
filter = rcu_dereference(sk->sk_filter);
|
||||||
|
len = filter ? filter->len * sizeof(struct sock_filter) : 0;
|
||||||
|
|
||||||
|
attr = nla_reserve(skb, attrtype, len);
|
||||||
|
if (attr == NULL) {
|
||||||
|
err = -EMSGSIZE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter)
|
||||||
|
memcpy(nla_data(attr), filter->insns, len);
|
||||||
|
|
||||||
|
out:
|
||||||
|
rcu_read_unlock();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(sock_diag_put_filterinfo);
|
||||||
|
|
||||||
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
|
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
|
||||||
{
|
{
|
||||||
mutex_lock(&sock_diag_table_mutex);
|
mutex_lock(&sock_diag_table_mutex);
|
||||||
|
|
|
@ -125,8 +125,10 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req,
|
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
|
||||||
u32 portid, u32 seq, u32 flags, int sk_ino)
|
struct packet_diag_req *req,
|
||||||
|
struct user_namespace *user_ns,
|
||||||
|
u32 portid, u32 seq, u32 flags, int sk_ino)
|
||||||
{
|
{
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
struct packet_diag_msg *rp;
|
struct packet_diag_msg *rp;
|
||||||
|
@ -147,6 +149,11 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag
|
||||||
pdiag_put_info(po, skb))
|
pdiag_put_info(po, skb))
|
||||||
goto out_nlmsg_trim;
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
|
if ((req->pdiag_show & PACKET_SHOW_INFO) &&
|
||||||
|
nla_put_u32(skb, PACKET_DIAG_UID,
|
||||||
|
from_kuid_munged(user_ns, sock_i_uid(sk))))
|
||||||
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
|
if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
|
||||||
pdiag_put_mclist(po, skb))
|
pdiag_put_mclist(po, skb))
|
||||||
goto out_nlmsg_trim;
|
goto out_nlmsg_trim;
|
||||||
|
@ -159,6 +166,14 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag
|
||||||
pdiag_put_fanout(po, skb))
|
pdiag_put_fanout(po, skb))
|
||||||
goto out_nlmsg_trim;
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
|
if ((req->pdiag_show & PACKET_SHOW_MEMINFO) &&
|
||||||
|
sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
|
||||||
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
|
if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
|
||||||
|
sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER))
|
||||||
|
goto out_nlmsg_trim;
|
||||||
|
|
||||||
return nlmsg_end(skb, nlh);
|
return nlmsg_end(skb, nlh);
|
||||||
|
|
||||||
out_nlmsg_trim:
|
out_nlmsg_trim:
|
||||||
|
@ -183,9 +198,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
if (num < s_num)
|
if (num < s_num)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (sk_diag_fill(sk, skb, req, NETLINK_CB(cb->skb).portid,
|
if (sk_diag_fill(sk, skb, req,
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
sk_user_ns(NETLINK_CB(cb->skb).sk),
|
||||||
sock_i_ino(sk)) < 0)
|
NETLINK_CB(cb->skb).portid,
|
||||||
|
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||||
|
sock_i_ino(sk)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
next:
|
next:
|
||||||
num++;
|
num++;
|
||||||
|
|
Loading…
Reference in a new issue