aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_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/inet_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/inet_diag.c')
-rw-r--r--net/ipv4/inet_diag.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 38064a285cca..570e61f9611f 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -272,16 +272,17 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
272 int err; 272 int err;
273 struct sock *sk; 273 struct sock *sk;
274 struct sk_buff *rep; 274 struct sk_buff *rep;
275 struct net *net = sock_net(in_skb->sk);
275 276
276 err = -EINVAL; 277 err = -EINVAL;
277 if (req->sdiag_family == AF_INET) { 278 if (req->sdiag_family == AF_INET) {
278 sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0], 279 sk = inet_lookup(net, hashinfo, req->id.idiag_dst[0],
279 req->id.idiag_dport, req->id.idiag_src[0], 280 req->id.idiag_dport, req->id.idiag_src[0],
280 req->id.idiag_sport, req->id.idiag_if); 281 req->id.idiag_sport, req->id.idiag_if);
281 } 282 }
282#if IS_ENABLED(CONFIG_IPV6) 283#if IS_ENABLED(CONFIG_IPV6)
283 else if (req->sdiag_family == AF_INET6) { 284 else if (req->sdiag_family == AF_INET6) {
284 sk = inet6_lookup(&init_net, hashinfo, 285 sk = inet6_lookup(net, hashinfo,
285 (struct in6_addr *)req->id.idiag_dst, 286 (struct in6_addr *)req->id.idiag_dst,
286 req->id.idiag_dport, 287 req->id.idiag_dport,
287 (struct in6_addr *)req->id.idiag_src, 288 (struct in6_addr *)req->id.idiag_src,
@@ -317,7 +318,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
317 nlmsg_free(rep); 318 nlmsg_free(rep);
318 goto out; 319 goto out;
319 } 320 }
320 err = netlink_unicast(sock_diag_nlsk, rep, NETLINK_CB(in_skb).pid, 321 err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).pid,
321 MSG_DONTWAIT); 322 MSG_DONTWAIT);
322 if (err > 0) 323 if (err > 0)
323 err = 0; 324 err = 0;
@@ -724,6 +725,7 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
724{ 725{
725 int i, num; 726 int i, num;
726 int s_i, s_num; 727 int s_i, s_num;
728 struct net *net = sock_net(skb->sk);
727 729
728 s_i = cb->args[1]; 730 s_i = cb->args[1];
729 s_num = num = cb->args[2]; 731 s_num = num = cb->args[2];
@@ -743,6 +745,9 @@ void inet_diag_dump_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *skb,
743 sk_nulls_for_each(sk, node, &ilb->head) { 745 sk_nulls_for_each(sk, node, &ilb->head) {
744 struct inet_sock *inet = inet_sk(sk); 746 struct inet_sock *inet = inet_sk(sk);
745 747
748 if (!net_eq(sock_net(sk), net))
749 continue;
750
746 if (num < s_num) { 751 if (num < s_num) {
747 num++; 752 num++;
748 continue; 753 continue;
@@ -813,6 +818,8 @@ skip_listen_ht:
813 sk_nulls_for_each(sk, node, &head->chain) { 818 sk_nulls_for_each(sk, node, &head->chain) {
814 struct inet_sock *inet = inet_sk(sk); 819 struct inet_sock *inet = inet_sk(sk);
815 820
821 if (!net_eq(sock_net(sk), net))
822 continue;
816 if (num < s_num) 823 if (num < s_num)
817 goto next_normal; 824 goto next_normal;
818 if (!(r->idiag_states & (1 << sk->sk_state))) 825 if (!(r->idiag_states & (1 << sk->sk_state)))
@@ -839,6 +846,8 @@ next_normal:
839 846
840 inet_twsk_for_each(tw, node, 847 inet_twsk_for_each(tw, node,
841 &head->twchain) { 848 &head->twchain) {
849 if (!net_eq(twsk_net(tw), net))
850 continue;
842 851
843 if (num < s_num) 852 if (num < s_num)
844 goto next_dying; 853 goto next_dying;
@@ -943,6 +952,7 @@ static int inet_diag_get_exact_compat(struct sk_buff *in_skb,
943static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh) 952static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
944{ 953{
945 int hdrlen = sizeof(struct inet_diag_req); 954 int hdrlen = sizeof(struct inet_diag_req);
955 struct net *net = sock_net(skb->sk);
946 956
947 if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX || 957 if (nlh->nlmsg_type >= INET_DIAG_GETSOCK_MAX ||
948 nlmsg_len(nlh) < hdrlen) 958 nlmsg_len(nlh) < hdrlen)
@@ -963,7 +973,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
963 struct netlink_dump_control c = { 973 struct netlink_dump_control c = {
964 .dump = inet_diag_dump_compat, 974 .dump = inet_diag_dump_compat,
965 }; 975 };
966 return netlink_dump_start(sock_diag_nlsk, skb, nlh, &c); 976 return netlink_dump_start(net->diag_nlsk, skb, nlh, &c);
967 } 977 }
968 } 978 }
969 979
@@ -973,6 +983,7 @@ static int inet_diag_rcv_msg_compat(struct sk_buff *skb, struct nlmsghdr *nlh)
973static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h) 983static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
974{ 984{
975 int hdrlen = sizeof(struct inet_diag_req_v2); 985 int hdrlen = sizeof(struct inet_diag_req_v2);
986 struct net *net = sock_net(skb->sk);
976 987
977 if (nlmsg_len(h) < hdrlen) 988 if (nlmsg_len(h) < hdrlen)
978 return -EINVAL; 989 return -EINVAL;
@@ -991,7 +1002,7 @@ static int inet_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)
991 struct netlink_dump_control c = { 1002 struct netlink_dump_control c = {
992 .dump = inet_diag_dump, 1003 .dump = inet_diag_dump,
993 }; 1004 };
994 return netlink_dump_start(sock_diag_nlsk, skb, h, &c); 1005 return netlink_dump_start(net->diag_nlsk, skb, h, &c);
995 } 1006 }
996 } 1007 }
997 1008