aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorAndrey Vagin <avagin@openvz.org>2012-07-16 00:28:49 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-17 01:31:34 -0400
commit51d7cccf07238f5236c5b9269231a30dd5f8e714 (patch)
tree1155d43b810d0f163276182be610d69c50e862d9 /net/unix
parentcbc89c8cf279b85edc95b4ae40a9e7e1edf2dfae (diff)
net: make sock diag per-namespace
Before this patch sock_diag works for init_net only and dumps information about sockets from all namespaces. This patch expands sock_diag for all name-spaces. It creates a netlink kernel socket for each netns and filters data during dumping. v2: filter accoding with netns in all places remove an unused variable. Cc: "David S. Miller" <davem@davemloft.net> Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> Cc: James Morris <jmorris@namei.org> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> Cc: Patrick McHardy <kaber@trash.net> Cc: Pavel Emelyanov <xemul@parallels.com> CC: Eric Dumazet <eric.dumazet@gmail.com> Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Andrew Vagin <avagin@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/diag.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/unix/diag.c b/net/unix/diag.c
index a74864eedfcd..750b13408449 100644
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -177,6 +177,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
177{ 177{
178 struct unix_diag_req *req; 178 struct unix_diag_req *req;
179 int num, s_num, slot, s_slot; 179 int num, s_num, slot, s_slot;
180 struct net *net = sock_net(skb->sk);
180 181
181 req = nlmsg_data(cb->nlh); 182 req = nlmsg_data(cb->nlh);
182 183
@@ -192,6 +193,8 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
192 193
193 num = 0; 194 num = 0;
194 sk_for_each(sk, node, &unix_socket_table[slot]) { 195 sk_for_each(sk, node, &unix_socket_table[slot]) {
196 if (!net_eq(sock_net(sk), net))
197 continue;
195 if (num < s_num) 198 if (num < s_num)
196 goto next; 199 goto next;
197 if (!(req->udiag_states & (1 << sk->sk_state))) 200 if (!(req->udiag_states & (1 << sk->sk_state)))
@@ -243,6 +246,7 @@ static int unix_diag_get_exact(struct sk_buff *in_skb,
243 struct sock *sk; 246 struct sock *sk;
244 struct sk_buff *rep; 247 struct sk_buff *rep;
245 unsigned int extra_len; 248 unsigned int extra_len;
249 struct net *net = sock_net(in_skb->sk);
246 250
247 if (req->udiag_ino == 0) 251 if (req->udiag_ino == 0)
248 goto out_nosk; 252 goto out_nosk;
@@ -273,7 +277,7 @@ again:
273 277
274 goto again; 278 goto again;
275 } 279 }
276 err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, 280 err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid,
277 MSG_DONTWAIT); 281 MSG_DONTWAIT);
278 if (err > 0) 282 if (err > 0)
279 err = 0; 283 err = 0;
@@ -287,6 +291,7 @@ out_nosk:
287static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) 291static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
288{ 292{
289 int hdrlen = sizeof(struct unix_diag_req); 293 int hdrlen = sizeof(struct unix_diag_req);
294 struct net *net = sock_net(skb->sk);
290 295
291 if (nlmsg_len(h) < hdrlen) 296 if (nlmsg_len(h) < hdrlen)
292 return -EINVAL; 297 return -EINVAL;
@@ -295,7 +300,7 @@ static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
295 struct netlink_dump_control c = { 300 struct netlink_dump_control c = {
296 .dump = unix_diag_dump, 301 .dump = unix_diag_dump,
297 }; 302 };
298 return netlink_dump_start(sock_diag_nlsk, skb, h, &c); 303 return netlink_dump_start(net->diag_nlsk, skb, h, &c);
299 } else 304 } else
300 return unix_diag_get_exact(skb, h, nlmsg_data(h)); 305 return unix_diag_get_exact(skb, h, nlmsg_data(h));
301} 306}