All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, Nicolas Dichtel <nicolas.dichtel@6wind.com>
Subject: [PATCH net-next 2/4] netns: add support of NETNSA_TARGET_NSID
Date: Wed, 21 Nov 2018 12:01:22 +0100	[thread overview]
Message-ID: <20181121110124.5501-3-nicolas.dichtel@6wind.com> (raw)
In-Reply-To: <20181121110124.5501-1-nicolas.dichtel@6wind.com>

Like it was done for link and address, add the ability to perform get/dump
in another netns by specifying a target nsid attribute.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/uapi/linux/net_namespace.h |  1 +
 net/core/net_namespace.c           | 97 ++++++++++++++++++++++++------
 2 files changed, 80 insertions(+), 18 deletions(-)

diff --git a/include/uapi/linux/net_namespace.h b/include/uapi/linux/net_namespace.h
index 0187c74d8889..0ed9dd61d32a 100644
--- a/include/uapi/linux/net_namespace.h
+++ b/include/uapi/linux/net_namespace.h
@@ -16,6 +16,7 @@ enum {
 	NETNSA_NSID,
 	NETNSA_PID,
 	NETNSA_FD,
+	NETNSA_TARGET_NSID,
 	__NETNSA_MAX,
 };
 
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 3e6af99bbe53..3d02a742155f 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -669,6 +669,7 @@ static const struct nla_policy rtnl_net_policy[NETNSA_MAX + 1] = {
 	[NETNSA_NSID]		= { .type = NLA_S32 },
 	[NETNSA_PID]		= { .type = NLA_U32 },
 	[NETNSA_FD]		= { .type = NLA_U32 },
+	[NETNSA_TARGET_NSID]	= { .type = NLA_S32 },
 };
 
 static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -767,9 +768,9 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
 {
 	struct net *net = sock_net(skb->sk);
 	struct nlattr *tb[NETNSA_MAX + 1];
+	struct net *peer, *target = net;
 	struct nlattr *nla;
 	struct sk_buff *msg;
-	struct net *peer;
 	int err, id;
 
 	err = nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
@@ -793,30 +794,47 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return PTR_ERR(peer);
 	}
 
+	if (tb[NETNSA_TARGET_NSID]) {
+		id = nla_get_s32(tb[NETNSA_TARGET_NSID]);
+		target = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, id);
+		if (IS_ERR(target)) {
+			NL_SET_BAD_ATTR(extack, tb[NETNSA_TARGET_NSID]);
+			NL_SET_ERR_MSG(extack,
+				       "Target netns reference is invalid");
+			err = PTR_ERR(target);
+			goto put_peer;
+		}
+	} else {
+		get_net(target);
+	}
+
 	msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL);
 	if (!msg) {
 		err = -ENOMEM;
-		goto out;
+		goto put_target;
 	}
 
-	id = peernet2id(net, peer);
+	id = peernet2id(target, peer);
 	err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
 			    RTM_NEWNSID, id);
 	if (err < 0)
-		goto err_out;
+		goto free_nlmsg;
 
 	err = rtnl_unicast(msg, net, NETLINK_CB(skb).portid);
-	goto out;
+	goto put_target;
 
-err_out:
+free_nlmsg:
 	nlmsg_free(msg);
-out:
+put_target:
+	put_net(target);
+put_peer:
 	put_net(peer);
 	return err;
 }
 
 struct rtnl_net_dump_cb {
-	struct net *net;
+	struct net *tgt_net;
+	struct net *ref_net;
 	struct sk_buff *skb;
 	struct netlink_callback *cb;
 	int idx;
@@ -842,29 +860,72 @@ static int rtnl_net_dumpid_one(int id, void *peer, void *data)
 	return 0;
 }
 
+static int rtnl_valid_dump_net_req(const struct nlmsghdr *nlh, struct sock *sk,
+				   struct rtnl_net_dump_cb *net_cb,
+				   struct netlink_callback *cb)
+{
+	struct netlink_ext_ack *extack = cb->extack;
+	struct nlattr *tb[NETNSA_MAX + 1];
+	int err, i;
+
+	err = nlmsg_parse_strict(nlh, sizeof(struct rtgenmsg), tb, NETNSA_MAX,
+				 rtnl_net_policy, extack);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i <= NETNSA_MAX; i++) {
+		if (!tb[i])
+			continue;
+
+		if (i == NETNSA_TARGET_NSID) {
+			struct net *net;
+
+			net = rtnl_get_net_ns_capable(sk, nla_get_s32(tb[i]));
+			if (IS_ERR(net)) {
+				NL_SET_BAD_ATTR(extack, tb[i]);
+				NL_SET_ERR_MSG(extack,
+					       "Invalid target network namespace id");
+				return PTR_ERR(net);
+			}
+			net_cb->ref_net = net_cb->tgt_net;
+			net_cb->tgt_net = net;
+		} else {
+			NL_SET_BAD_ATTR(extack, tb[i]);
+			NL_SET_ERR_MSG(extack,
+				       "Unsupported attribute in dump request");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb)
 {
-	struct net *net = sock_net(skb->sk);
 	struct rtnl_net_dump_cb net_cb = {
-		.net = net,
+		.tgt_net = sock_net(skb->sk),
 		.skb = skb,
 		.cb = cb,
 		.idx = 0,
 		.s_idx = cb->args[0],
 	};
+	int err = 0;
 
-	if (cb->strict_check &&
-	    nlmsg_attrlen(cb->nlh, sizeof(struct rtgenmsg))) {
-			NL_SET_ERR_MSG(cb->extack, "Unknown data in network namespace id dump request");
-			return -EINVAL;
+	if (cb->strict_check) {
+		err = rtnl_valid_dump_net_req(cb->nlh, skb->sk, &net_cb, cb);
+		if (err < 0)
+			goto end;
 	}
 
-	spin_lock_bh(&net->nsid_lock);
-	idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb);
-	spin_unlock_bh(&net->nsid_lock);
+	spin_lock_bh(&net_cb.tgt_net->nsid_lock);
+	idr_for_each(&net_cb.tgt_net->netns_ids, rtnl_net_dumpid_one, &net_cb);
+	spin_unlock_bh(&net_cb.tgt_net->nsid_lock);
 
 	cb->args[0] = net_cb.idx;
-	return skb->len;
+end:
+	if (net_cb.ref_net)
+		put_net(net_cb.tgt_net);
+	return err < 0 ? err : skb->len;
 }
 
 static void rtnl_net_notifyid(struct net *net, int cmd, int id)
-- 
2.18.0

  parent reply	other threads:[~2018-11-21 21:35 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-21 11:01 [PATCH net-next 0/4] Ease to interpret net-nsid Nicolas Dichtel
2018-11-21 11:01 ` [PATCH net-next 1/4] netns: remove net arg from rtnl_net_fill() Nicolas Dichtel
2018-11-21 11:01 ` Nicolas Dichtel [this message]
2018-11-21 18:05   ` [PATCH net-next 2/4] netns: add support of NETNSA_TARGET_NSID David Ahern
2018-11-21 20:58     ` Nicolas Dichtel
2018-11-21 21:07       ` David Ahern
2018-11-22  8:06         ` Nicolas Dichtel
2018-11-21 11:01 ` [PATCH net-next 3/4] netns: enable to specify a nsid for a get request Nicolas Dichtel
2018-11-21 11:01 ` [PATCH net-next 4/4] netns: enable to dump full nsid translation table Nicolas Dichtel
2018-11-21 18:09   ` David Ahern
2018-11-21 21:01     ` Nicolas Dichtel
2018-11-21 21:08       ` David Ahern
2018-11-22 15:50 ` [PATCH net-next v2 0/5] Ease to interpret net-nsid Nicolas Dichtel
2018-11-22 15:50   ` [PATCH net-next v2 1/5] netns: remove net arg from rtnl_net_fill() Nicolas Dichtel
2018-11-22 16:18     ` David Ahern
2018-11-22 15:50   ` [PATCH net-next v2 2/5] netns: introduce 'struct net_fill_args' Nicolas Dichtel
2018-11-22 16:23     ` David Ahern
2018-11-22 15:50   ` [PATCH net-next v2 3/5] netns: add support of NETNSA_TARGET_NSID Nicolas Dichtel
2018-11-22 16:32     ` David Ahern
2018-11-22 15:50   ` [PATCH net-next v2 4/5] netns: enable to specify a nsid for a get request Nicolas Dichtel
2018-11-22 16:32     ` David Ahern
2018-11-22 15:50   ` [PATCH net-next v2 5/5] netns: enable to dump full nsid translation table Nicolas Dichtel
2018-11-22 16:40     ` David Ahern
2018-11-22 16:42       ` Nicolas Dichtel
2018-11-22 22:22   ` [PATCH net-next v3 0/5] Ease to interpret net-nsid Nicolas Dichtel
2018-11-22 22:22     ` [PATCH net-next v3 1/5] netns: remove net arg from rtnl_net_fill() Nicolas Dichtel
2018-11-22 22:22     ` [PATCH net-next v3 2/5] netns: introduce 'struct net_fill_args' Nicolas Dichtel
2018-11-22 22:22     ` [PATCH net-next v3 3/5] netns: add support of NETNSA_TARGET_NSID Nicolas Dichtel
2018-11-22 22:22     ` [PATCH net-next v3 4/5] netns: enable to specify a nsid for a get request Nicolas Dichtel
2018-11-22 22:22     ` [PATCH net-next v3 5/5] netns: enable to dump full nsid translation table Nicolas Dichtel
2018-11-24 15:47       ` David Ahern
2018-11-26 10:06       ` kbuild test robot
2018-11-26 14:42     ` [PATCH net-next v4 0/5] Ease to interpret net-nsid Nicolas Dichtel
2018-11-26 14:42       ` [PATCH net-next v4 1/5] netns: remove net arg from rtnl_net_fill() Nicolas Dichtel
2018-11-26 14:42       ` [PATCH net-next v4 2/5] netns: introduce 'struct net_fill_args' Nicolas Dichtel
2018-11-26 14:42       ` [PATCH net-next v4 3/5] netns: add support of NETNSA_TARGET_NSID Nicolas Dichtel
2018-11-26 14:42       ` [PATCH net-next v4 4/5] netns: enable to specify a nsid for a get request Nicolas Dichtel
2018-11-26 14:42       ` [PATCH net-next v4 5/5] netns: enable to dump full nsid translation table Nicolas Dichtel
2018-11-28  0:20       ` [PATCH net-next v4 0/5] Ease to interpret net-nsid David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181121110124.5501-3-nicolas.dichtel@6wind.com \
    --to=nicolas.dichtel@6wind.com \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.