aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp_diag.c
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/ipv4/udp_diag.c
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/ipv4/udp_diag.c')
-rw-r--r--net/ipv4/udp_diag.c10
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)))