[RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

STALE4341d

Revision v2 of 5 in this series.

25 messages, 4 authors, 2014-09-26 · open the first message on its own page

[RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:26:43

The goal of this serie is to be able to multicast netlink messages with an
attribute that identify a peer netns.
This is needed by the userland to interpret some informations contained in
netlink messages (like IFLA_LINK value, but also some other attributes in case
of x-netns netdevice (see also
http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).

Ids are stored in the parent user namespace. These ids are valid only inside
this user namespace. The user can retrieve these ids via a new netlink messages,
but only if peer netns are in the same user namespace.

Patch 1/5 and 2/5 introduce the netlink API mechanism to exports these ids to
the userland.
Patch 3/5 and 4/5 shows an example of how to use these ids in rtnetlink
messages. And patch 5/5 shows that the netlink messages can be symetric between
a GET and a SET.

iproute2 patches are available, I can send them on demand.

Here is a small screenshot to show how it can be used by userland:
$ ip netns add foo
$ ip netns del foo
$ ip netns
$ touch /var/run/netns/init_net
$ mount --bind /proc/1/ns/net /var/run/netns/init_net
$ ip netns add foo
$ ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote 10.16.0.121 local 10.16.0.249
$ ip netns exec foo ip l ls ipip1
6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default 
    link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1

The parameter link-netnsid shows us where the interface sends and receives
packets (and thus we know where encapsulated addresses are set).

RFCv1 -> RFCv2:
  remove useless ()
  ids are now stored in the user ns. It's possible to get an id for a peer netns
  only if the current netns and the peer netns have the same user ns parent.

 MAINTAINERS                    |   1 +
 include/linux/user_namespace.h |   4 ++
 include/net/ip_tunnels.h       |   1 +
 include/net/net_namespace.h    |  12 +++++
 include/net/rtnetlink.h        |   2 +
 include/uapi/linux/Kbuild      |   1 +
 include/uapi/linux/if_link.h   |   1 +
 include/uapi/linux/netns.h     |  29 ++++++++++
 kernel/user_namespace.c        |   6 +++
 net/core/net_namespace.c       | 119 ++++++++++++++++++++++++++++++++++++++++-
 net/core/rtnetlink.c           |  47 ++++++++++++++--
 net/ipv4/ip_gre.c              |   2 +
 net/ipv4/ip_tunnel.c           |   8 +++
 net/ipv4/ip_vti.c              |   1 +
 net/ipv4/ipip.c                |   1 +
 net/ipv6/sit.c                 |   1 +
 net/netlink/genetlink.c        |   4 ++
 17 files changed, 236 insertions(+), 4 deletions(-)

Comments are welcome.

Regards,
Nicolas

[RFC PATCH net-next v2 5/5] rtnl: allow to create device with IFLA_LINK_NETNSID set

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:26:41

This patch adds the ability to create a netdevice in a specified netns and
then move it into the final netns. In fact, it allows to have a symetry between
get and set rtnl messages.

Signed-off-by: Nicolas Dichtel <redacted>
---
 net/core/rtnetlink.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 99ed83c62685..34b894ae79b4 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1220,6 +1220,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
 	[IFLA_NUM_RX_QUEUES]	= { .type = NLA_U32 },
 	[IFLA_PHYS_PORT_ID]	= { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
 	[IFLA_CARRIER_CHANGES]	= { .type = NLA_U32 },  /* ignored */
+	[IFLA_LINK_NETNSID]	= { .type = NLA_U32 },
 };
 
 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
@@ -1992,7 +1993,7 @@ replay:
 		struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 0];
 		struct nlattr **data = NULL;
 		struct nlattr **slave_data = NULL;
-		struct net *dest_net;
+		struct net *dest_net, *link_net = NULL;
 
 		if (ops) {
 			if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
@@ -2098,7 +2099,18 @@ replay:
 		if (IS_ERR(dest_net))
 			return PTR_ERR(dest_net);
 
-		dev = rtnl_create_link(dest_net, ifname, name_assign_type, ops, tb);
+		if (tb[IFLA_LINK_NETNSID]) {
+			int id = nla_get_u32(tb[IFLA_LINK_NETNSID]);
+
+			link_net = get_net_from_netnsid(dest_net, id);
+			if (link_net == NULL) {
+				err =  -EINVAL;
+				goto out;
+			}
+		}
+
+		dev = rtnl_create_link(link_net ? : dest_net, ifname,
+				       name_assign_type, ops, tb);
 		if (IS_ERR(dev)) {
 			err = PTR_ERR(dev);
 			goto out;
@@ -2126,9 +2138,16 @@ replay:
 			}
 		}
 		err = rtnl_configure_link(dev, ifm);
-		if (err < 0)
+		if (err < 0) {
 			unregister_netdevice(dev);
+			goto out;
+		}
+
+		if (link_net)
+			err = dev_change_net_namespace(dev, net, ifname);
 out:
+		if (link_net)
+			put_net(link_net);
 		put_net(dest_net);
 		return err;
 	}
-- 
2.1.0

[RFC PATCH net-next v2 4/5] iptunnels: advertise link netns via netlink

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:26:44

Implement rtnl_link_ops->get_link_net() callback so that IFLA_LINK_NETNSID is
added to rtnetlink messages.

Signed-off-by: Nicolas Dichtel <redacted>
---
 include/net/ip_tunnels.h | 1 +
 net/ipv4/ip_gre.c        | 2 ++
 net/ipv4/ip_tunnel.c     | 8 ++++++++
 net/ipv4/ip_vti.c        | 1 +
 net/ipv4/ipip.c          | 1 +
 net/ipv6/sit.c           | 1 +
 6 files changed, 14 insertions(+)
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 7f538ba6e267..c92a99b5b77e 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -119,6 +119,7 @@ struct ip_tunnel_net {
 int ip_tunnel_init(struct net_device *dev);
 void ip_tunnel_uninit(struct net_device *dev);
 void  ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
+struct net *ip_tunnel_get_link_net(const struct net_device *dev);
 int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
 		       struct rtnl_link_ops *ops, char *devname);
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 829aff8bf723..05157427d8f0 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -825,6 +825,7 @@ static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
 	.dellink	= ip_tunnel_dellink,
 	.get_size	= ipgre_get_size,
 	.fill_info	= ipgre_fill_info,
+	.get_link_net	= ip_tunnel_get_link_net,
 };
 
 static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
@@ -839,6 +840,7 @@ static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
 	.dellink	= ip_tunnel_dellink,
 	.get_size	= ipgre_get_size,
 	.fill_info	= ipgre_fill_info,
+	.get_link_net	= ip_tunnel_get_link_net,
 };
 
 static int __net_init ipgre_tap_init_net(struct net *net)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index e3a3dc91e49c..da5a2b6fed81 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -954,6 +954,14 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
 
+struct net *ip_tunnel_get_link_net(const struct net_device *dev)
+{
+	struct ip_tunnel *tunnel = netdev_priv(dev);
+
+	return tunnel->net;
+}
+EXPORT_SYMBOL(ip_tunnel_get_link_net);
+
 int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
 				  struct rtnl_link_ops *ops, char *devname)
 {
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index e453cb724a95..93862411669c 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -530,6 +530,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = {
 	.changelink	= vti_changelink,
 	.get_size	= vti_get_size,
 	.fill_info	= vti_fill_info,
+	.get_link_net	= ip_tunnel_get_link_net,
 };
 
 static int __init vti_init(void)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index bfec31df8b21..fd423e65d6df 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -496,6 +496,7 @@ static struct rtnl_link_ops ipip_link_ops __read_mostly = {
 	.dellink	= ip_tunnel_dellink,
 	.get_size	= ipip_get_size,
 	.fill_info	= ipip_fill_info,
+	.get_link_net	= ip_tunnel_get_link_net,
 };
 
 static struct xfrm_tunnel ipip_handler __read_mostly = {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index db75809ab843..5c227cc13170 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1761,6 +1761,7 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = {
 	.get_size	= ipip6_get_size,
 	.fill_info	= ipip6_fill_info,
 	.dellink	= ipip6_dellink,
+	.get_link_net	= ip_tunnel_get_link_net,
 };
 
 static struct xfrm_tunnel sit_handler __read_mostly = {
-- 
2.1.0

[RFC PATCH net-next v2 2/5] netns: add genl cmd to get the id of a netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:26:45

This patch allows a user to get an id of a peer netns. It will be usefull for
userland to be able to associate a netns file descriptor with a netns id.

Note: to be able to got an id, both netns should be in the same user ns.

Signed-off-by: Nicolas Dichtel <redacted>
---
 MAINTAINERS                 |  1 +
 include/net/net_namespace.h |  1 +
 include/uapi/linux/Kbuild   |  1 +
 include/uapi/linux/netns.h  | 29 +++++++++++++
 net/core/net_namespace.c    | 99 +++++++++++++++++++++++++++++++++++++++++++++
 net/netlink/genetlink.c     |  4 ++
 6 files changed, 135 insertions(+)
 create mode 100644 include/uapi/linux/netns.h
diff --git a/MAINTAINERS b/MAINTAINERS
index b4e23acc6441..dbf691c68473 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6278,6 +6278,7 @@ F:	include/linux/netdevice.h
 F:	include/uapi/linux/in.h
 F:	include/uapi/linux/net.h
 F:	include/uapi/linux/netdevice.h
+F:	include/uapi/linux/netns.h
 F:	tools/net/
 F:	tools/testing/selftests/net/
 F:	lib/random32.c
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 92b5f94e2842..1b65f5ccacf5 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -299,6 +299,7 @@ static inline int peernet2id(struct net *net, struct net *peer)
 }
 
 struct net *get_net_from_netnsid(struct net *net, int id);
+int netns_genl_register(void);
 
 struct pernet_operations {
 	struct list_head list;
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index fb3f7b675229..840f049c48fa 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -275,6 +275,7 @@ header-y += netfilter_decnet.h
 header-y += netfilter_ipv4.h
 header-y += netfilter_ipv6.h
 header-y += netlink.h
+header-y += netns.h
 header-y += netrom.h
 header-y += nfc.h
 header-y += nfs.h
diff --git a/include/uapi/linux/netns.h b/include/uapi/linux/netns.h
new file mode 100644
index 000000000000..72537e31d7d2
--- /dev/null
+++ b/include/uapi/linux/netns.h
@@ -0,0 +1,29 @@
+#ifndef _UAPI_LINUX_NETNS_H_
+#define _UAPI_LINUX_NETNS_H_
+
+/* Generic netlink messages */
+
+#define NETNS_GENL_NAME			"netns"
+#define NETNS_GENL_VERSION		0x1
+
+/* Commands */
+enum {
+	NETNS_CMD_UNSPEC,
+	NETNS_CMD_GET,
+	__NETNS_CMD_MAX,
+};
+
+#define NETNS_CMD_MAX		(__NETNS_CMD_MAX - 1)
+
+/* Attributes */
+enum {
+	NETNSA_NONE,
+	NETNSA_NSINDEX,
+	NETNSA_PID,
+	NETNSA_FD,
+	__NETNSA_MAX,
+};
+
+#define NETNSA_MAX		(__NETNSA_MAX - 1)
+
+#endif /* _UAPI_LINUX_NETNS_H_ */
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index f44378de7831..a60f2bbf4302 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -15,6 +15,8 @@
 #include <linux/file.h>
 #include <linux/export.h>
 #include <linux/user_namespace.h>
+#include <linux/netns.h>
+#include <net/genetlink.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -417,6 +419,103 @@ static struct pernet_operations __net_initdata net_ns_ops = {
 	.exit = net_ns_net_exit,
 };
 
+static struct genl_family netns_nl_family = {
+	.id		= GENL_ID_GENERATE,
+	.name		= NETNS_GENL_NAME,
+	.version	= NETNS_GENL_VERSION,
+	.hdrsize	= 0,
+	.maxattr	= NETNSA_MAX,
+	.netnsok	= true,
+};
+
+static struct nla_policy netns_nl_policy[NETNSA_MAX + 1] = {
+	[NETNSA_NONE]		= { .type = NLA_UNSPEC, },
+	[NETNSA_NSINDEX]	= { .type = NLA_U32, },
+	[NETNSA_PID]		= { .type = NLA_U32 },
+	[NETNSA_FD]		= { .type = NLA_U32 },
+};
+
+static int netns_nl_get_size(void)
+{
+	return nla_total_size(sizeof(u32)) /* NETNSA_NSINDEX */
+	       ;
+}
+
+static int netns_nl_fill(struct sk_buff *skb, u32 portid, u32 seq, int flags,
+			 int cmd, struct net *net, struct net *peer)
+{
+	void *hdr;
+	int id;
+
+	hdr = genlmsg_put(skb, portid, seq, &netns_nl_family, flags, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	id = peernet2id(net, peer);
+	if (id < 0)
+		return id;
+	if (nla_put_u32(skb, NETNSA_NSINDEX, id))
+		goto nla_put_failure;
+
+	return genlmsg_end(skb, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(skb, hdr);
+	return -EMSGSIZE;
+}
+
+static int netns_nl_cmd_getid(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct net *peer;
+	struct sk_buff *msg;
+	int err = -ENOBUFS;
+
+	if (info->attrs[NETNSA_PID])
+		peer = get_net_ns_by_pid(nla_get_u32(info->attrs[NETNSA_PID]));
+	else if (info->attrs[NETNSA_FD])
+		peer = get_net_ns_by_fd(nla_get_u32(info->attrs[NETNSA_FD]));
+	else
+		return -EINVAL;
+
+	if (IS_ERR(peer))
+		return PTR_ERR(peer);
+
+	msg = genlmsg_new(netns_nl_get_size(), GFP_KERNEL);
+	if (!msg) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = netns_nl_fill(msg, info->snd_portid, info->snd_seq,
+			    NLM_F_ACK, NETNS_CMD_GETID, net, peer);
+	if (err < 0)
+		goto err_out;
+
+	err = genlmsg_unicast(net, msg, info->snd_portid);
+	goto out;
+
+err_out:
+	nlmsg_free(msg);
+out:
+	put_net(peer);
+	return err;
+}
+
+static struct genl_ops netns_nl_ops[] = {
+	{
+		.cmd = NETNS_CMD_GETID,
+		.policy = netns_nl_policy,
+		.doit = netns_nl_cmd_getid,
+		.flags = GENL_ADMIN_PERM,
+	},
+};
+
+int netns_genl_register(void)
+{
+	return genl_register_family_with_ops(&netns_nl_family, netns_nl_ops);
+}
+
 static int __init net_ns_init(void)
 {
 	struct net_generic *ng;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 76393f2f4b22..c6f39e40c9f3 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1029,6 +1029,10 @@ static int __init genl_init(void)
 	if (err)
 		goto problem;
 
+	err = netns_genl_register();
+	if (err < 0)
+		goto problem;
+
 	return 0;
 
 problem:
-- 
2.1.0

[RFC PATCH net-next v2 3/5] rtnl: add link netns id to interface messages

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:26:46

This patch adds a new attribute (IFLA_LINK_NETNSID) which contains the 'link'
netns id when this netns is different from the netns where the interface
stands (for example for x-net interfaces like ip tunnels). When there is no id,
because user ns of link netns and interface netns is not the same, we put 0
into this attribute (id 0 is not valid) to indicate to userland that the link
netns is different from the interface netns. Hence, userland knows that some
information like IFLA_LINK are not interpretable.

Signed-off-by: Nicolas Dichtel <redacted>
---
 include/net/rtnetlink.h      |  2 ++
 include/uapi/linux/if_link.h |  1 +
 net/core/rtnetlink.c         | 22 ++++++++++++++++++++++
 3 files changed, 25 insertions(+)
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index e21b9f9653c0..6c6d5393fc34 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -46,6 +46,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
  *			    to create when creating a new device.
  *	@get_num_rx_queues: Function to determine number of receive queues
  *			    to create when creating a new device.
+ *	@get_link_net: Function to get the i/o netns of the device
  */
 struct rtnl_link_ops {
 	struct list_head	list;
@@ -93,6 +94,7 @@ struct rtnl_link_ops {
 	int			(*fill_slave_info)(struct sk_buff *skb,
 						   const struct net_device *dev,
 						   const struct net_device *slave_dev);
+	struct net		*(*get_link_net)(const struct net_device *dev);
 };
 
 int __rtnl_link_register(struct rtnl_link_ops *ops);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index c80f95f6ee78..21dd2bcb295f 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -145,6 +145,7 @@ enum {
 	IFLA_CARRIER,
 	IFLA_PHYS_PORT_ID,
 	IFLA_CARRIER_CHANGES,
+	IFLA_LINK_NETNSID,
 	__IFLA_MAX
 };
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a6882686ca3a..99ed83c62685 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -862,6 +862,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
+	       + nla_total_size(4) /* IFLA_LINK_NETNSID */
 	       + nla_total_size(ext_filter_mask
 			        & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
 	       + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1134,6 +1135,27 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 			goto nla_put_failure;
 	}
 
+	if (dev->rtnl_link_ops &&
+	    dev->rtnl_link_ops->get_link_net) {
+		struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
+
+		if (!net_eq(dev_net(dev), link_net)) {
+			int id = peernet2id(dev_net(dev), link_net);
+
+			/* If the link netns is not in the same user ns, put id
+			 * 0 in IFLA_LINK_NETNSID to indicate to userland that
+			 * the link netns is not the current netns, but that it
+			 * don't have access to it.
+			 */
+			if (id == -EPERM)
+				id = 0;
+
+			if (id >= 0 &&
+			    nla_put_u32(skb, IFLA_LINK_NETNSID, id))
+				goto nla_put_failure;
+		}
+	}
+
 	if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
 		goto nla_put_failure;
 
-- 
2.1.0

[RFC PATCH net-next v2 1/5] netns: allocate netns ids

From: Nicolas Dichtel <hidden>
Date: 2014-09-23 13:31:43

With this patch, an id is allocated for each netns. Id database is stored in the
user namespace. It's allowed to get an id of a peer netns only if they share the
same user ns.

Signed-off-by: Nicolas Dichtel <redacted>
---
 include/linux/user_namespace.h |  4 ++++
 include/net/net_namespace.h    | 11 +++++++++++
 kernel/user_namespace.c        |  6 ++++++
 net/core/net_namespace.c       | 20 +++++++++++++++++++-
 4 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index e95372654f09..9d122b540422 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -5,6 +5,7 @@
 #include <linux/nsproxy.h>
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <linux/idr.h>
 
 #define UID_GID_MAP_MAX_EXTENTS 5
 
@@ -33,6 +34,9 @@ struct user_namespace {
 	struct key		*persistent_keyring_register;
 	struct rw_semaphore	persistent_keyring_register_sem;
 #endif
+#ifdef CONFIG_NET_NS
+	struct idr		netns_ids;
+#endif
 };
 
 extern struct user_namespace init_user_ns;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 361d26077196..92b5f94e2842 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -59,6 +59,7 @@ struct net {
 	struct list_head	exit_list;	/* Use only net_mutex */
 
 	struct user_namespace   *user_ns;	/* Owning user namespace */
+	int			netnsid;
 
 	unsigned int		proc_inum;
 
@@ -289,6 +290,16 @@ static inline struct net *read_pnet(struct net * const *pnet)
 #define __net_initconst	__initconst
 #endif
 
+static inline int peernet2id(struct net *net, struct net *peer)
+{
+	if (net->user_ns != peer->user_ns)
+		return -EPERM;
+
+	return peer->netnsid;
+}
+
+struct net *get_net_from_netnsid(struct net *net, int id);
+
 struct pernet_operations {
 	struct list_head list;
 	int (*init)(struct net *net);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index aa312b0dc3ec..30316a2eed49 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -104,6 +104,9 @@ int create_user_ns(struct cred *new)
 #ifdef CONFIG_PERSISTENT_KEYRINGS
 	init_rwsem(&ns->persistent_keyring_register_sem);
 #endif
+#ifdef CONFIG_NET_NS
+	idr_init(&ns->netns_ids);
+#endif
 	return 0;
 }
 
@@ -133,6 +136,9 @@ void free_user_ns(struct user_namespace *ns)
 
 	do {
 		parent = ns->parent;
+#ifdef CONFIG_NET_NS
+		idr_destroy(&ns->netns_ids);
+#endif
 #ifdef CONFIG_PERSISTENT_KEYRINGS
 		key_put(ns->persistent_keyring_register);
 #endif
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 7f155175bba8..f44378de7831 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -144,6 +144,19 @@ static void ops_free_list(const struct pernet_operations *ops,
 	}
 }
 
+struct net *get_net_from_netnsid(struct net *net, int id)
+{
+	struct net *peer;
+
+	rcu_read_lock();
+	peer = idr_find(&net->user_ns->netns_ids, id);
+	if (peer)
+		get_net(peer);
+	rcu_read_unlock();
+
+	return peer;
+}
+
 /*
  * setup_net runs the initializers for the network namespace object.
  */
@@ -151,13 +164,16 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
 {
 	/* Must be called with net_mutex held */
 	const struct pernet_operations *ops, *saved_ops;
-	int error = 0;
+	int error = 0, id;
 	LIST_HEAD(net_exit_list);
 
 	atomic_set(&net->count, 1);
 	atomic_set(&net->passive, 1);
 	net->dev_base_seq = 1;
 	net->user_ns = user_ns;
+	id = idr_alloc_cyclic(&user_ns->netns_ids, net, 1, 0, GFP_KERNEL);
+	if (id > 0)
+		net->netnsid = id;
 
 #ifdef NETNS_REFCNT_DEBUG
 	atomic_set(&net->use_count, 0);
@@ -288,6 +304,8 @@ static void cleanup_net(struct work_struct *work)
 	list_for_each_entry(net, &net_kill_list, cleanup_list) {
 		list_del_rcu(&net->list);
 		list_add_tail(&net->exit_list, &net_exit_list);
+		if (net->netnsid)
+			idr_remove(&net->user_ns->netns_ids, net->netnsid);
 	}
 	rtnl_unlock();
 
-- 
2.1.0

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-23 19:22:06

On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
Here is a small screenshot to show how it can be used by userland:
$ ip netns add foo
$ ip netns del foo
$ ip netns
$ touch /var/run/netns/init_net
$ mount --bind /proc/1/ns/net /var/run/netns/init_net
$ ip netns add foo
$ ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote 10.16.0.121 local 10.16.0.249
$ ip netns exec foo ip l ls ipip1
6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default
    link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1

The parameter link-netnsid shows us where the interface sends and receives
packets (and thus we know where encapsulated addresses are set).
So ipip1 is shown in netns foo but functioning in netns init_net? Getting the
id of init_net in foo depends on your mount namespace, /var/run/netns/ may
not visible inside foo, in this case, link-netnsid is meaningless. It
is not your
fault, network namespace already heavily relies on mount namespace (sysfs
needs to be remount otherwise you can not create device with the same name.)

On the other hand, what's the problem you are trying to solve? AFAIK,
the ifindex
issue is purely in output, IOW, the device still functions correctly
even through
its link ifindex is not correct after moving to another namespace. If
not, it is bug
we need to fix.

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Andy Lutomirski <luto@amacapital.net>
Date: 2014-09-23 19:27:01

On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
The goal of this serie is to be able to multicast netlink messages with an
attribute that identify a peer netns.
This is needed by the userland to interpret some informations contained in
netlink messages (like IFLA_LINK value, but also some other attributes in case
of x-netns netdevice (see also
http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).

Ids are stored in the parent user namespace. These ids are valid only inside
this user namespace. The user can retrieve these ids via a new netlink messages,
but only if peer netns are in the same user namespace.
What about the parent / ancestors of the owning userns?  Can processes
in those usernses see any form of netns id?

--Andy

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-24 09:23:27

Le 23/09/2014 21:22, Cong Wang a écrit :
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Here is a small screenshot to show how it can be used by userland:
$ ip netns add foo
$ ip netns del foo
$ ip netns
$ touch /var/run/netns/init_net
$ mount --bind /proc/1/ns/net /var/run/netns/init_net
$ ip netns add foo
$ ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote 10.16.0.121 local 10.16.0.249
$ ip netns exec foo ip l ls ipip1
6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default
     link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1

The parameter link-netnsid shows us where the interface sends and receives
packets (and thus we know where encapsulated addresses are set).
So ipip1 is shown in netns foo but functioning in netns init_net? Getting the
id of init_net in foo depends on your mount namespace, /var/run/netns/ may
not visible inside foo, in this case, link-netnsid is meaningless. It
is not your
fault, network namespace already heavily relies on mount namespace (sysfs
needs to be remount otherwise you can not create device with the same name.)

On the other hand, what's the problem you are trying to solve? AFAIK,
the ifindex
issue is purely in output, IOW, the device still functions correctly
even through
its link ifindex is not correct after moving to another namespace. If
not, it is bug
we need to fix.
The problem is explained here:
http://thread.gmane.org/gmane.linux.network/315933/focus=316064
and here:
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239


Regards,
Nicolas
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-24 09:32:36

Le 23/09/2014 21:26, Andy Lutomirski a écrit :
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
The goal of this serie is to be able to multicast netlink messages with an
attribute that identify a peer netns.
This is needed by the userland to interpret some informations contained in
netlink messages (like IFLA_LINK value, but also some other attributes in case
of x-netns netdevice (see also
http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).

Ids are stored in the parent user namespace. These ids are valid only inside
this user namespace. The user can retrieve these ids via a new netlink messages,
but only if peer netns are in the same user namespace.
What about the parent / ancestors of the owning userns?  Can processes
in those usernses see any form of netns id?
With this serie no. I'm not sure if ancestors really needs to be able to
get these ids. What is your opinion?
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-24 16:01:09

On Wed, Sep 24, 2014 at 2:23 AM, Nicolas Dichtel
[off-list ref] wrote:
Le 23/09/2014 21:22, Cong Wang a écrit :
quoted
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted

Here is a small screenshot to show how it can be used by userland:
$ ip netns add foo
$ ip netns del foo
$ ip netns
$ touch /var/run/netns/init_net
$ mount --bind /proc/1/ns/net /var/run/netns/init_net
$ ip netns add foo
$ ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote
10.16.0.121 local 10.16.0.249
$ ip netns exec foo ip l ls ipip1
6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode
DEFAULT group default
     link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1

The parameter link-netnsid shows us where the interface sends and
receives
packets (and thus we know where encapsulated addresses are set).
So ipip1 is shown in netns foo but functioning in netns init_net? Getting
the
id of init_net in foo depends on your mount namespace, /var/run/netns/ may
not visible inside foo, in this case, link-netnsid is meaningless. It
is not your
fault, network namespace already heavily relies on mount namespace (sysfs
needs to be remount otherwise you can not create device with the same
name.)

On the other hand, what's the problem you are trying to solve? AFAIK,
the ifindex
issue is purely in output, IOW, the device still functions correctly
even through
its link ifindex is not correct after moving to another namespace. If
not, it is bug
we need to fix.
The problem is explained here:
http://thread.gmane.org/gmane.linux.network/315933/focus=316064
and here:
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239
Please, summarize the discussion in your changelog, instead of pointing
to a long thread.

And clearly you missed my question above: how do you get netns id
without sharing /var/run/netns/ ?

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-24 16:15:31

On Wed, Sep 24, 2014 at 9:01 AM, Cong Wang [off-list ref] wrote:
And clearly you missed my question above: how do you get netns id
without sharing /var/run/netns/ ?
OK, I found it:
Ids are stored in the parent user namespace. These ids are valid only inside
this user namespace. The user can retrieve these ids via a new netlink messages,
but only if peer netns are in the same user namespace.
So your example is confusing, perhaps you need some other way to show the ID's
instead of binding to ip netns output which is basically ls
/var/run/netns/. We don't
want an inner netns know anything outside, IOW, we don't share /var/run/netns/.
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-24 16:27:37

Le 24/09/2014 18:01, Cong Wang a écrit :
On Wed, Sep 24, 2014 at 2:23 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Le 23/09/2014 21:22, Cong Wang a écrit :
quoted
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted

Here is a small screenshot to show how it can be used by userland:
$ ip netns add foo
$ ip netns del foo
$ ip netns
$ touch /var/run/netns/init_net
$ mount --bind /proc/1/ns/net /var/run/netns/init_net
$ ip netns add foo
$ ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip netns
foo (id: 3)
init_net (id: 1)
$ ip netns exec foo ip link add ipip1 link-netnsid 1 type ipip remote
10.16.0.121 local 10.16.0.249
$ ip netns exec foo ip l ls ipip1
6: ipip1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode
DEFAULT group default
      link/ipip 10.16.0.249 peer 10.16.0.121 link-netnsid 1

The parameter link-netnsid shows us where the interface sends and
receives
packets (and thus we know where encapsulated addresses are set).
So ipip1 is shown in netns foo but functioning in netns init_net? Getting
the
id of init_net in foo depends on your mount namespace, /var/run/netns/ may
not visible inside foo, in this case, link-netnsid is meaningless. It
is not your
fault, network namespace already heavily relies on mount namespace (sysfs
needs to be remount otherwise you can not create device with the same
name.)

On the other hand, what's the problem you are trying to solve? AFAIK,
the ifindex
issue is purely in output, IOW, the device still functions correctly
even through
its link ifindex is not correct after moving to another namespace. If
not, it is bug
we need to fix.
The problem is explained here:
http://thread.gmane.org/gmane.linux.network/315933/focus=316064
and here:
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239
Please, summarize the discussion in your changelog, instead of pointing
to a long thread.
The thread is long, but the mail in focus contains the information. Here is a 
copy and paste:
What I'm trying to solve is to have full info in netlink messages sent by the
kernel, thus beeing able to identify a peer netns (and this is close from what
audit guys are trying to have). Theorically, messages sent by the kernel can be
reused as is to have the same configuration. This is not the case with x-netns
devices. Here is an example, with ip tunnels:

$ ip netns add 1
$ ip link add ipip1 type ipip remote 10.16.0.121 local 10.16.0.249 dev eth0
$ ip -d link ls ipip1
8: ipip1 <at> eth0: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT
group default
      link/ipip 10.16.0.249 peer 10.16.0.121 promiscuity 0
      ipip remote 10.16.0.121 local 10.16.0.249 dev eth0 ttl inherit pmtudisc
$ ip link set ipip1 netns 1
$ ip netns exec 1 ip -d link ls ipip1
8: ipip1 <at> tunl0: <POINTOPOINT,NOARP,M-DOWN> mtu 1480 qdisc noop state DOWN mode
DEFAULT group default
      link/ipip 10.16.0.249 peer 10.16.0.121 promiscuity 0
      ipip remote 10.16.0.121 local 10.16.0.249 dev tunl0 ttl inherit pmtudisc

Now informations got with 'ip link' are wrong and incomplete:
   - the link dev is now tunl0 instead of eth0, because we only got an ifindex
     from the kernel without any netns informations.
   - the encapsulation addresses are not part of this netns but the user doesn't
     known that (still because netns info is missing). These IPv4 addresses may
     exist into this netns.
   - it's not possible to create the same netdevice with these infos.

Hope it's more clear now.
And clearly you missed my question above: how do you get netns id
without sharing /var/run/netns/ ?
You can get an id only if you already have a "pointer" to this netns.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-24 16:31:56

Le 24/09/2014 18:15, Cong Wang a écrit :
On Wed, Sep 24, 2014 at 9:01 AM, Cong Wang [off-list ref] wrote:
quoted
And clearly you missed my question above: how do you get netns id
without sharing /var/run/netns/ ?
OK, I found it:
quoted
Ids are stored in the parent user namespace. These ids are valid only inside
this user namespace. The user can retrieve these ids via a new netlink messages,
but only if peer netns are in the same user namespace.
So your example is confusing, perhaps you need some other way to show the ID's
instead of binding to ip netns output which is basically ls
/var/run/netns/. We don't
want an inner netns know anything outside, IOW, we don't share /var/run/netns/.
Hmm, not sure to understand you. My usecase shares /var/run/netns, because
there is only one user ns and one mount ns.
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?
It's why the ids depend on user ns. Only if user ns are the same we allow to
get an id for a peer netns.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-24 16:45:34

On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
[off-list ref] wrote:
Now informations got with 'ip link' are wrong and incomplete:
  - the link dev is now tunl0 instead of eth0, because we only got an
ifindex
    from the kernel without any netns informations.
This is not new, macvlan has the same problem. This is why I said
it is mostly a display problem, maybe just mark the ifindex as -1 or
something when it is not in this netns. At least I don't expect the inner
netns know anything outside, and I don't think I am the only one using
netns in this way.
  - the encapsulation addresses are not part of this netns but the user
doesn't
    known that (still because netns info is missing). These IPv4 addresses
may
    exist into this netns.
I don't remember your x-netns code, but we have two choices:

1) Lookup the route of the netns which it is in

If the address is not available in this netns, it will fail, this is expected
since tunnel device is not a pure L2 device. Or maybe just fail
early when we move it.

2) Lookup the route of the netns where it was created

Transparent for upper layer, but as you said, the outer address is not
available in this netns therefore hard to display. Just hiding this information
doesn't seem wrong to me.

  - it's not possible to create the same netdevice with these infos.
This is expected, because after all you are already in a different netns.

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-24 16:48:24

On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?
It's why the ids depend on user ns. Only if user ns are the same we allow to
get an id for a peer netns.
Too late, userns is relatively new, relying on it breaks our existing
assumption.

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Andy Lutomirski <luto@amacapital.net>
Date: 2014-09-24 17:06:23

On Wed, Sep 24, 2014 at 2:31 AM, Nicolas Dichtel
[off-list ref] wrote:
Le 23/09/2014 21:26, Andy Lutomirski a écrit :
quoted
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
The goal of this serie is to be able to multicast netlink messages with
an
attribute that identify a peer netns.
This is needed by the userland to interpret some informations contained
in
netlink messages (like IFLA_LINK value, but also some other attributes in
case
of x-netns netdevice (see also
http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).

Ids are stored in the parent user namespace. These ids are valid only
inside
this user namespace. The user can retrieve these ids via a new netlink
messages,
but only if peer netns are in the same user namespace.

What about the parent / ancestors of the owning userns?  Can processes
in those usernses see any form of netns id?
With this serie no. I'm not sure if ancestors really needs to be able to
get these ids. What is your opinion?
I might be missing some consideration here, but I would hope that ip
link would work correctly if I have a veth interface shared with a
netns that's in a child userns.

--Andy

-- 
Andy Lutomirski
AMA Capital Management, LLC

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-25 07:55:05

Le 24/09/2014 19:05, Andy Lutomirski a écrit :
On Wed, Sep 24, 2014 at 2:31 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Le 23/09/2014 21:26, Andy Lutomirski a écrit :
quoted
On Tue, Sep 23, 2014 at 6:20 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
The goal of this serie is to be able to multicast netlink messages with
an
attribute that identify a peer netns.
This is needed by the userland to interpret some informations contained
in
netlink messages (like IFLA_LINK value, but also some other attributes in
case
of x-netns netdevice (see also
http://thread.gmane.org/gmane.linux.network/315933/focus=316064 and
http://thread.gmane.org/gmane.linux.kernel.containers/28301/focus=4239)).

Ids are stored in the parent user namespace. These ids are valid only
inside
this user namespace. The user can retrieve these ids via a new netlink
messages,
but only if peer netns are in the same user namespace.

What about the parent / ancestors of the owning userns?  Can processes
in those usernses see any form of netns id?
With this serie no. I'm not sure if ancestors really needs to be able to
get these ids. What is your opinion?
I might be missing some consideration here, but I would hope that ip
link would work correctly if I have a veth interface shared with a
netns that's in a child userns.
No, you're right. Will send a v3.

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-25 08:53:35

Le 24/09/2014 18:48, Cong Wang a écrit :
On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
quoted
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?
It's why the ids depend on user ns. Only if user ns are the same we allow to
get an id for a peer netns.
Too late, userns is relatively new, relying on it breaks our existing
assumption.
I don't get your point. netns has been added in kernel after user ns:
acce292c82d4 user namespace: add the framework => 2.6.23
5f256becd868 [NET]: Basic network namespace infrastructure. => 2.6.24

In the kernel, each netns is linked with a user ns.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-25 08:53:42

Le 24/09/2014 18:45, Cong Wang a écrit :
On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Now informations got with 'ip link' are wrong and incomplete:
   - the link dev is now tunl0 instead of eth0, because we only got an
ifindex
     from the kernel without any netns informations.
This is not new, macvlan has the same problem. This is why I said
it is mostly a display problem, maybe just mark the ifindex as -1 or
something when it is not in this netns. At least I don't expect the inner
netns know anything outside, and I don't think I am the only one using
netns in this way.
I understand your point but there is several use of netns. Netns can be used
also to instantiate virtual routers. In this case, administrators or daemons
need to be able to monitor and dump the configuration on all netns
(particularly beeing able to identify fully x-netns interfaces). We start to
discuss this in one of the two thread pointed in my cover letter and get the
conclusion that checking user ns is a good way to know if an id should be
disclosed or not for a peer netns.
Can you describe your use case?
quoted
   - the encapsulation addresses are not part of this netns but the user
doesn't
     known that (still because netns info is missing). These IPv4 addresses
may
     exist into this netns.
I don't remember your x-netns code, but we have two choices:

1) Lookup the route of the netns which it is in

If the address is not available in this netns, it will fail, this is expected
since tunnel device is not a pure L2 device. Or maybe just fail
early when we move it.

2) Lookup the route of the netns where it was created

Transparent for upper layer, but as you said, the outer address is not
available in this netns therefore hard to display. Just hiding this information
doesn't seem wrong to me.
Your assumption here is that all dameons were started before the tunnel was
created. But this is not true, a daemon may be started later. Another case is
when a daemon crash: we need to be able to restart it and it should be able to
recover all needed information.
quoted
   - it's not possible to create the same netdevice with these infos.
This is expected, because after all you are already in a different netns.
A different netns only means a different network stack, not a different user ns
or mount ns or PID ns, ...
If you only play with netns, you may want to monitor all activies in all netns
(this is already possible) and beeing able to link information between netns
(this is what I'm trying to solve).
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-26 01:58:42

On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
[off-list ref] wrote:
Le 24/09/2014 18:48, Cong Wang a écrit :
quoted
On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
quoted
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?

It's why the ids depend on user ns. Only if user ns are the same we allow
to
get an id for a peer netns.

Too late, userns is relatively new, relying on it breaks our existing
assumption.
I don't get your point. netns has been added in kernel after user ns:
acce292c82d4 user namespace: add the framework => 2.6.23
5f256becd868 [NET]: Basic network namespace infrastructure. => 2.6.24
Was it complete on 2.6.x? I doubt...

https://lkml.org/lkml/2014/8/20/826

   As at Linux 3.8, most relevant subsystems supported  user  names‐
       paces,  but  a number of filesystems did not have the infrastruc‐
       ture needed to map user and group IDs  between  user  namespaces.
       Linux  3.9  added the required infrastructure support for many of
       the remaining unsupported filesystems (Plan 9 (9P),  Andrew  File
       System  (AFS),  Ceph,  CIFS,  CODA,  NFS, and OCFS2).  Linux 3.11
       added support the last of the unsupported major filesystems, XFS.

In the kernel, each netns is linked with a user ns.
Are you saying every time we create a netns we have a new userns?
This doesn't make sense for me.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Cong Wang <hidden>
Date: 2014-09-26 02:09:41

On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
[off-list ref] wrote:
Le 24/09/2014 18:45, Cong Wang a écrit :
quoted
On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Now informations got with 'ip link' are wrong and incomplete:
   - the link dev is now tunl0 instead of eth0, because we only got an
ifindex
     from the kernel without any netns informations.

This is not new, macvlan has the same problem. This is why I said
it is mostly a display problem, maybe just mark the ifindex as -1 or
something when it is not in this netns. At least I don't expect the inner
netns know anything outside, and I don't think I am the only one using
netns in this way.
I understand your point but there is several use of netns. Netns can be used
also to instantiate virtual routers. In this case, administrators or daemons
need to be able to monitor and dump the configuration on all netns
(particularly beeing able to identify fully x-netns interfaces). We start to
discuss this in one of the two thread pointed in my cover letter and get the
conclusion that checking user ns is a good way to know if an id should be
disclosed or not for a peer netns.
Then you are leaking information, this breaks isolation.
Can you describe your use case?
Yes, too simple: isolation networking, different netns's don't see each other
(including anything inside) and only communicate via veth.

If you only play with netns, you may want to monitor all activies in all
netns
(this is already possible) and beeing able to link information between netns
(this is what I'm trying to solve).

No, I don't want to monitor anything. Even if I wanted, I would just start one
daemon in each netns instead of one for all.

On the other hand, why not exchange the configuration via veth
between different netns? There are many ways to do so with TCP HTTP etc.
This doesn't have to be solved in kernel.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-26 13:39:03

Le 26/09/2014 03:58, Cong Wang a écrit :
On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Le 24/09/2014 18:48, Cong Wang a écrit :
quoted
On Wed, Sep 24, 2014 at 9:31 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
quoted
I think in this case your ID's are still available, but aren't you
providing a new way
for the inner netns device to escape which we are trying to avoid?

It's why the ids depend on user ns. Only if user ns are the same we allow
to
get an id for a peer netns.

Too late, userns is relatively new, relying on it breaks our existing
assumption.
I don't get your point. netns has been added in kernel after user ns:
acce292c82d4 user namespace: add the framework => 2.6.23
5f256becd868 [NET]: Basic network namespace infrastructure. => 2.6.24
Was it complete on 2.6.x? I doubt...

https://lkml.org/lkml/2014/8/20/826

    As at Linux 3.8, most relevant subsystems supported  user  names‐
        paces,  but  a number of filesystems did not have the infrastruc‐
        ture needed to map user and group IDs  between  user  namespaces.
        Linux  3.9  added the required infrastructure support for many of
        the remaining unsupported filesystems (Plan 9 (9P),  Andrew  File
        System  (AFS),  Ceph,  CIFS,  CODA,  NFS, and OCFS2).  Linux 3.11
        added support the last of the unsupported major filesystems, XFS.

quoted
In the kernel, each netns is linked with a user ns.
Are you saying every time we create a netns we have a new userns?
This doesn't make sense for me.
No. I mean that each netns depends on a userns.
See include/net/net_namespace.h:
struct net {
[snip]
         struct user_namespace   *user_ns;       /* Owning user namespace */
[snip]
}
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: Nicolas Dichtel <hidden>
Date: 2014-09-26 13:40:35

Le 26/09/2014 04:09, Cong Wang a écrit :
On Thu, Sep 25, 2014 at 1:53 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Le 24/09/2014 18:45, Cong Wang a écrit :
quoted
On Wed, Sep 24, 2014 at 9:27 AM, Nicolas Dichtel
[off-list ref] wrote:
quoted
Now informations got with 'ip link' are wrong and incomplete:
    - the link dev is now tunl0 instead of eth0, because we only got an
ifindex
      from the kernel without any netns informations.

This is not new, macvlan has the same problem. This is why I said
it is mostly a display problem, maybe just mark the ifindex as -1 or
something when it is not in this netns. At least I don't expect the inner
netns know anything outside, and I don't think I am the only one using
netns in this way.
I understand your point but there is several use of netns. Netns can be used
also to instantiate virtual routers. In this case, administrators or daemons
need to be able to monitor and dump the configuration on all netns
(particularly beeing able to identify fully x-netns interfaces). We start to
discuss this in one of the two thread pointed in my cover letter and get the
conclusion that checking user ns is a good way to know if an id should be
disclosed or not for a peer netns.
Then you are leaking information, this breaks isolation.
quoted
Can you describe your use case?
Yes, too simple: isolation networking, different netns's don't see each other
(including anything inside) and only communicate via veth.
If you are a privileged user and you are able to access a peer netns (move an
interface into this peer netns, move an interface from this peer netns to your
own netns), I don't see any reason to not beeing able to get information about
this peer netns (you are already a privileged user in both netns).
If you want to isolate this peer netns (I think you call it "inner netns"), you
have to create a new user ns for this netns, hence a privileged user into this
peer netns will not be able to act in your own netns. And with this scenario and
my patches, this privileged user will not be able to get an id. Isolation is
preserved.
How do you preserved it in your scenario?
quoted
If you only play with netns, you may want to monitor all activies in all
netns
(this is already possible) and beeing able to link information between netns
(this is what I'm trying to solve).

No, I don't want to monitor anything. Even if I wanted, I would just start one
daemon in each netns instead of one for all.
Ok you don't want, but some other people (not only me) want it! And having one
daemon per netns does not scale: there are scenarii with thousand netns which
are dynamically created and deleted.
On the other hand, why not exchange the configuration via veth
between different netns? There are many ways to do so with TCP HTTP etc.
This doesn't have to be solved in kernel.
The standard way with linux to monitor network configuration is netlink.
_______________________________________________
Containers mailing list
Containers@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/containers

Re: [RFC PATCH net-next v2 0/5] netns: allow to identify peer netns

From: David Ahern <hidden>
Date: 2014-09-26 19:15:18

On 9/26/14, 7:40 AM, Nicolas Dichtel wrote:
quoted

No, I don't want to monitor anything. Even if I wanted, I would just
start one
daemon in each netns instead of one for all.
Ok you don't want, but some other people (not only me) want it! And
having one
daemon per netns does not scale: there are scenarii with thousand netns
which
are dynamically created and deleted.
An example of the scaling problem using quagga (old but still seems to 
be a relevant data point):

 
https://lists.quagga.net/pipermail/quagga-users/2010-February/011351.html

"2k VRFs that would be 2.6G"

And that does not include the overhead of each namespace -- roughly 
200kB/namespace on one kernel I checked (v3.10). So that's a ballpark of 
3G of memory.

David
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help