aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-29 13:22:07 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-29 13:22:07 -0400
commit13ccf043ce85b64802a57bd3e47ca1505b6bf275 (patch)
tree16093300e9da78c1c3e272283ae4886d7b3984e8
parentfdd5f43a1b53a844d04c6eda2cbdbe044b629ae7 (diff)
parente8d9612c181b1a68ba5f71384629343466f1bd13 (diff)
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>
-rw-r--r--include/linux/sock_diag.h3
-rw-r--r--include/uapi/linux/packet_diag.h5
-rw-r--r--net/core/sock_diag.c33
-rw-r--r--net/packet/diag.c27
4 files changed, 63 insertions, 5 deletions
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index e8d702e0fd89..54f91d35e5fd 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -1,6 +1,7 @@
1#ifndef __SOCK_DIAG_H__ 1#ifndef __SOCK_DIAG_H__
2#define __SOCK_DIAG_H__ 2#define __SOCK_DIAG_H__
3 3
4#include <linux/user_namespace.h>
4#include <uapi/linux/sock_diag.h> 5#include <uapi/linux/sock_diag.h>
5 6
6struct sk_buff; 7struct sk_buff;
@@ -22,5 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
22void sock_diag_save_cookie(void *sk, __u32 *cookie); 23void sock_diag_save_cookie(void *sk, __u32 *cookie);
23 24
24int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); 25int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
26int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
27 struct sk_buff *skb, int attrtype);
25 28
26#endif 29#endif
diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h
index afafd703ad92..b2cc0cd9c4d9 100644
--- a/include/uapi/linux/packet_diag.h
+++ b/include/uapi/linux/packet_diag.h
@@ -16,6 +16,8 @@ struct packet_diag_req {
16#define PACKET_SHOW_MCLIST 0x00000002 /* A set of packet_diag_mclist-s */ 16#define PACKET_SHOW_MCLIST 0x00000002 /* A set of packet_diag_mclist-s */
17#define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */ 17#define PACKET_SHOW_RING_CFG 0x00000004 /* Rings configuration parameters */
18#define PACKET_SHOW_FANOUT 0x00000008 18#define PACKET_SHOW_FANOUT 0x00000008
19#define PACKET_SHOW_MEMINFO 0x00000010
20#define PACKET_SHOW_FILTER 0x00000020
19 21
20struct packet_diag_msg { 22struct packet_diag_msg {
21 __u8 pdiag_family; 23 __u8 pdiag_family;
@@ -32,6 +34,9 @@ enum {
32 PACKET_DIAG_RX_RING, 34 PACKET_DIAG_RX_RING,
33 PACKET_DIAG_TX_RING, 35 PACKET_DIAG_TX_RING,
34 PACKET_DIAG_FANOUT, 36 PACKET_DIAG_FANOUT,
37 PACKET_DIAG_UID,
38 PACKET_DIAG_MEMINFO,
39 PACKET_DIAG_FILTER,
35 40
36 __PACKET_DIAG_MAX, 41 __PACKET_DIAG_MAX,
37}; 42};
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index a29e90cf36b7..d5bef0b0f639 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -49,6 +49,39 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
49} 49}
50EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); 50EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
51 51
52int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
53 struct sk_buff *skb, int attrtype)
54{
55 struct nlattr *attr;
56 struct sk_filter *filter;
57 unsigned int len;
58 int err = 0;
59
60 if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
61 nla_reserve(skb, attrtype, 0);
62 return 0;
63 }
64
65 rcu_read_lock();
66
67 filter = rcu_dereference(sk->sk_filter);
68 len = filter ? filter->len * sizeof(struct sock_filter) : 0;
69
70 attr = nla_reserve(skb, attrtype, len);
71 if (attr == NULL) {
72 err = -EMSGSIZE;
73 goto out;
74 }
75
76 if (filter)
77 memcpy(nla_data(attr), filter->insns, len);
78
79out:
80 rcu_read_unlock();
81 return err;
82}
83EXPORT_SYMBOL(sock_diag_put_filterinfo);
84
52void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh)) 85void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh))
53{ 86{
54 mutex_lock(&sock_diag_table_mutex); 87 mutex_lock(&sock_diag_table_mutex);
diff --git a/net/packet/diag.c b/net/packet/diag.c
index d3fcd1ebef7e..a9584a2f6d69 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -125,8 +125,10 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb)
125 return ret; 125 return ret;
126} 126}
127 127
128static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag_req *req, 128static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
129 u32 portid, u32 seq, u32 flags, int sk_ino) 129 struct packet_diag_req *req,
130 struct user_namespace *user_ns,
131 u32 portid, u32 seq, u32 flags, int sk_ino)
130{ 132{
131 struct nlmsghdr *nlh; 133 struct nlmsghdr *nlh;
132 struct packet_diag_msg *rp; 134 struct packet_diag_msg *rp;
@@ -147,6 +149,11 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag
147 pdiag_put_info(po, skb)) 149 pdiag_put_info(po, skb))
148 goto out_nlmsg_trim; 150 goto out_nlmsg_trim;
149 151
152 if ((req->pdiag_show & PACKET_SHOW_INFO) &&
153 nla_put_u32(skb, PACKET_DIAG_UID,
154 from_kuid_munged(user_ns, sock_i_uid(sk))))
155 goto out_nlmsg_trim;
156
150 if ((req->pdiag_show & PACKET_SHOW_MCLIST) && 157 if ((req->pdiag_show & PACKET_SHOW_MCLIST) &&
151 pdiag_put_mclist(po, skb)) 158 pdiag_put_mclist(po, skb))
152 goto out_nlmsg_trim; 159 goto out_nlmsg_trim;
@@ -159,6 +166,14 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct packet_diag
159 pdiag_put_fanout(po, skb)) 166 pdiag_put_fanout(po, skb))
160 goto out_nlmsg_trim; 167 goto out_nlmsg_trim;
161 168
169 if ((req->pdiag_show & PACKET_SHOW_MEMINFO) &&
170 sock_diag_put_meminfo(sk, skb, PACKET_DIAG_MEMINFO))
171 goto out_nlmsg_trim;
172
173 if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
174 sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER))
175 goto out_nlmsg_trim;
176
162 return nlmsg_end(skb, nlh); 177 return nlmsg_end(skb, nlh);
163 178
164out_nlmsg_trim: 179out_nlmsg_trim:
@@ -183,9 +198,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
183 if (num < s_num) 198 if (num < s_num)
184 goto next; 199 goto next;
185 200
186 if (sk_diag_fill(sk, skb, req, NETLINK_CB(cb->skb).portid, 201 if (sk_diag_fill(sk, skb, req,
187 cb->nlh->nlmsg_seq, NLM_F_MULTI, 202 sk_user_ns(NETLINK_CB(cb->skb).sk),
188 sock_i_ino(sk)) < 0) 203 NETLINK_CB(cb->skb).portid,
204 cb->nlh->nlmsg_seq, NLM_F_MULTI,
205 sock_i_ino(sk)) < 0)
189 goto done; 206 goto done;
190next: 207next:
191 num++; 208 num++;