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/ipv4/udp_diag.c | |
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/ipv4/udp_diag.c')
-rw-r--r-- | net/ipv4/udp_diag.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index a7f86a3cd502..16d0960062be 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c | |||
@@ -34,15 +34,16 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, | |||
34 | int err = -EINVAL; | 34 | int err = -EINVAL; |
35 | struct sock *sk; | 35 | struct sock *sk; |
36 | struct sk_buff *rep; | 36 | struct sk_buff *rep; |
37 | struct net *net = sock_net(in_skb->sk); | ||
37 | 38 | ||
38 | if (req->sdiag_family == AF_INET) | 39 | if (req->sdiag_family == AF_INET) |
39 | sk = __udp4_lib_lookup(&init_net, | 40 | sk = __udp4_lib_lookup(net, |
40 | req->id.idiag_src[0], req->id.idiag_sport, | 41 | req->id.idiag_src[0], req->id.idiag_sport, |
41 | req->id.idiag_dst[0], req->id.idiag_dport, | 42 | req->id.idiag_dst[0], req->id.idiag_dport, |
42 | req->id.idiag_if, tbl); | 43 | req->id.idiag_if, tbl); |
43 | #if IS_ENABLED(CONFIG_IPV6) | 44 | #if IS_ENABLED(CONFIG_IPV6) |
44 | else if (req->sdiag_family == AF_INET6) | 45 | else if (req->sdiag_family == AF_INET6) |
45 | sk = __udp6_lib_lookup(&init_net, | 46 | sk = __udp6_lib_lookup(net, |
46 | (struct in6_addr *)req->id.idiag_src, | 47 | (struct in6_addr *)req->id.idiag_src, |
47 | req->id.idiag_sport, | 48 | req->id.idiag_sport, |
48 | (struct in6_addr *)req->id.idiag_dst, | 49 | (struct in6_addr *)req->id.idiag_dst, |
@@ -75,7 +76,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, | |||
75 | kfree_skb(rep); | 76 | kfree_skb(rep); |
76 | goto out; | 77 | goto out; |
77 | } | 78 | } |
78 | err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, | 79 | err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid, |
79 | MSG_DONTWAIT); | 80 | MSG_DONTWAIT); |
80 | if (err > 0) | 81 | if (err > 0) |
81 | err = 0; | 82 | err = 0; |
@@ -90,6 +91,7 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin | |||
90 | struct inet_diag_req_v2 *r, struct nlattr *bc) | 91 | struct inet_diag_req_v2 *r, struct nlattr *bc) |
91 | { | 92 | { |
92 | int num, s_num, slot, s_slot; | 93 | int num, s_num, slot, s_slot; |
94 | struct net *net = sock_net(skb->sk); | ||
93 | 95 | ||
94 | s_slot = cb->args[0]; | 96 | s_slot = cb->args[0]; |
95 | num = s_num = cb->args[1]; | 97 | num = s_num = cb->args[1]; |
@@ -106,6 +108,8 @@ static void udp_dump(struct udp_table *table, struct sk_buff *skb, struct netlin | |||
106 | sk_nulls_for_each(sk, node, &hslot->head) { | 108 | sk_nulls_for_each(sk, node, &hslot->head) { |
107 | struct inet_sock *inet = inet_sk(sk); | 109 | struct inet_sock *inet = inet_sk(sk); |
108 | 110 | ||
111 | if (!net_eq(sock_net(sk), net)) | ||
112 | continue; | ||
109 | if (num < s_num) | 113 | if (num < s_num) |
110 | goto next; | 114 | goto next; |
111 | if (!(r->idiag_states & (1 << sk->sk_state))) | 115 | if (!(r->idiag_states & (1 << sk->sk_state))) |