diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2015-04-07 05:51:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-07 17:29:41 -0400 |
commit | a143c40c32bb8a6d6a556920646021d7e96d1f91 (patch) | |
tree | 2c9faf03479b4aaefe193c47b2c66061e95ddfcd /net/core/net_namespace.c | |
parent | 9a9634545c7051f567096117d417e9c3be24706d (diff) |
netns: allow to dump netns ids
Which this patch, it's possible to dump the list of ids allocated for peer
netns.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r-- | net/core/net_namespace.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b3b5f22f0e90..a3abb719221f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -616,6 +616,52 @@ out: | |||
616 | return err; | 616 | return err; |
617 | } | 617 | } |
618 | 618 | ||
619 | struct rtnl_net_dump_cb { | ||
620 | struct net *net; | ||
621 | struct sk_buff *skb; | ||
622 | struct netlink_callback *cb; | ||
623 | int idx; | ||
624 | int s_idx; | ||
625 | }; | ||
626 | |||
627 | static int rtnl_net_dumpid_one(int id, void *peer, void *data) | ||
628 | { | ||
629 | struct rtnl_net_dump_cb *net_cb = (struct rtnl_net_dump_cb *)data; | ||
630 | int ret; | ||
631 | |||
632 | if (net_cb->idx < net_cb->s_idx) | ||
633 | goto cont; | ||
634 | |||
635 | ret = rtnl_net_fill(net_cb->skb, NETLINK_CB(net_cb->cb->skb).portid, | ||
636 | net_cb->cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
637 | RTM_NEWNSID, net_cb->net, peer, id); | ||
638 | if (ret < 0) | ||
639 | return ret; | ||
640 | |||
641 | cont: | ||
642 | net_cb->idx++; | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) | ||
647 | { | ||
648 | struct net *net = sock_net(skb->sk); | ||
649 | struct rtnl_net_dump_cb net_cb = { | ||
650 | .net = net, | ||
651 | .skb = skb, | ||
652 | .cb = cb, | ||
653 | .idx = 0, | ||
654 | .s_idx = cb->args[0], | ||
655 | }; | ||
656 | |||
657 | ASSERT_RTNL(); | ||
658 | |||
659 | idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb); | ||
660 | |||
661 | cb->args[0] = net_cb.idx; | ||
662 | return skb->len; | ||
663 | } | ||
664 | |||
619 | static void rtnl_net_notifyid(struct net *net, struct net *peer, int cmd, | 665 | static void rtnl_net_notifyid(struct net *net, struct net *peer, int cmd, |
620 | int id) | 666 | int id) |
621 | { | 667 | { |
@@ -673,7 +719,8 @@ static int __init net_ns_init(void) | |||
673 | register_pernet_subsys(&net_ns_ops); | 719 | register_pernet_subsys(&net_ns_ops); |
674 | 720 | ||
675 | rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, NULL); | 721 | rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, NULL); |
676 | rtnl_register(PF_UNSPEC, RTM_GETNSID, rtnl_net_getid, NULL, NULL); | 722 | rtnl_register(PF_UNSPEC, RTM_GETNSID, rtnl_net_getid, rtnl_net_dumpid, |
723 | NULL); | ||
677 | 724 | ||
678 | return 0; | 725 | return 0; |
679 | } | 726 | } |