diff options
author | Andrey Vagin <avagin@openvz.org> | 2012-07-16 00:28:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-17 01:31:34 -0400 |
commit | 51d7cccf07238f5236c5b9269231a30dd5f8e714 (patch) | |
tree | 1155d43b810d0f163276182be610d69c50e862d9 /net/unix | |
parent | cbc89c8cf279b85edc95b4ae40a9e7e1edf2dfae (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.c | 9 |
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: | |||
287 | static int unix_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) | 291 | static 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 | } |