From: dlezcano@fr.ibm.com
To: containers@lists.osdl.org
Cc: netdev@vger.kernel.org
Subject: [patch 05/12] net namespace : ioctl to push ifa to net namespace l3
Date: Fri, 19 Jan 2007 16:47:19 +0100 [thread overview]
Message-ID: <20070119155351.915374403@localhost.localdomain> (raw)
In-Reply-To: 20070119154714.439706567@localhost.localdomain
[-- Attachment #1: net-namespace-l3-move-ifaddr-to-net_ns.patch --]
[-- Type: text/plain, Size: 5673 bytes --]
From: Daniel Lezcano <dlezcano@fr.ibm.com>
New ioctl to "push" ifaddr to a container. Actually, the push is done
from the current namespace, so the right word is "pull". That will be
changed to move ifaddr from l2 network namespace to l3.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
include/linux/net_namespace.h | 7 ++
include/linux/sockios.h | 4 +
net/core/net_namespace.c | 118 +++++++++++++++++++++++++++++++++++++++++-
net/ipv4/af_inet.c | 4 +
4 files changed, 132 insertions(+), 1 deletion(-)
Index: 2.6.20-rc4-mm1/include/linux/sockios.h
===================================================================
--- 2.6.20-rc4-mm1.orig/include/linux/sockios.h
+++ 2.6.20-rc4-mm1/include/linux/sockios.h
@@ -122,6 +122,10 @@
#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
#define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
+/* Container calls */
+#define SIOCNETNSPUSHIF 0x89b0 /* add ifaddr to namespace */
+#define SIOCNETNSPULLIF 0x89b1 /* remove ifaddr to namespace */
+
/* Device private ioctl calls */
/*
Index: 2.6.20-rc4-mm1/net/ipv4/af_inet.c
===================================================================
--- 2.6.20-rc4-mm1.orig/net/ipv4/af_inet.c
+++ 2.6.20-rc4-mm1/net/ipv4/af_inet.c
@@ -789,6 +789,10 @@
case SIOCSIFFLAGS:
err = devinet_ioctl(cmd, (void __user *)arg);
break;
+ case SIOCNETNSPUSHIF:
+ case SIOCNETNSPULLIF:
+ err = net_ns_ioctl(cmd, (void __user *)arg);
+ break;
default:
if (sk->sk_prot->ioctl)
err = sk->sk_prot->ioctl(sk, cmd, arg);
Index: 2.6.20-rc4-mm1/include/linux/net_namespace.h
===================================================================
--- 2.6.20-rc4-mm1.orig/include/linux/net_namespace.h
+++ 2.6.20-rc4-mm1/include/linux/net_namespace.h
@@ -91,6 +91,8 @@
#define net_ns_hash(ns) ((ns)->hash)
+extern int net_ns_ioctl(unsigned int cmd, void __user *arg);
+
#else /* CONFIG_NET_NS */
#define INIT_NET_NS(net_ns)
@@ -141,6 +143,11 @@
#define net_ns_hash(ns) (0)
+static inline int net_ns_ioctl(unsigned int cmd, void __user *arg)
+{
+ return -ENOSYS;
+}
+
#endif /* !CONFIG_NET_NS */
#endif /* _LINUX_NET_NAMESPACE_H */
Index: 2.6.20-rc4-mm1/net/core/net_namespace.c
===================================================================
--- 2.6.20-rc4-mm1.orig/net/core/net_namespace.c
+++ 2.6.20-rc4-mm1/net/core/net_namespace.c
@@ -10,7 +10,9 @@
#include <linux/nsproxy.h>
#include <linux/net_namespace.h>
#include <linux/net.h>
+#include <linux/in.h>
#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
#include <net/ip_fib.h>
struct net_namespace init_net_ns = {
@@ -123,6 +125,33 @@
return err;
}
+/*
+ * The function will move the ifaddr to the l2 network namespace
+ * parent.
+ * @net_ns: the related network namespace
+ */
+static void release_ifa_to_parent(const struct net_namespace* net_ns)
+{
+ struct net_device *dev;
+ struct in_device *in_dev;
+
+ read_lock(&dev_base_lock);
+ rcu_read_lock();
+ for (dev = dev_base; dev; dev = dev->next) {
+ in_dev = __in_dev_get_rcu(dev);
+ if (!in_dev)
+ continue;
+
+ for_ifa(in_dev) {
+ if (ifa->ifa_net_ns != net_ns)
+ continue;
+ ifa->ifa_net_ns = net_ns->parent;
+ } endfor_ifa(in_dev);
+ }
+ read_unlock(&dev_base_lock);
+ rcu_read_unlock();
+}
+
void free_net_ns(struct kref *kref)
{
struct net_namespace *ns;
@@ -139,12 +168,99 @@
}
}
- if (ns->level == NET_NS_LEVEL3)
+ if (ns->level == NET_NS_LEVEL3) {
+ release_ifa_to_parent(ns);
put_net_ns(ns->parent);
+ }
printk(KERN_DEBUG "NET_NS: net namespace %p destroyed\n", ns);
kfree(ns);
}
EXPORT_SYMBOL_GPL(free_net_ns);
+/*
+ * This function allows to assign an IP address from a l2 network
+ * namespace to one of his l3 child or to release from an l3 network
+ * namespace to his l2 network namespace parent.
+ * @cmd: a "push" / "pull" command
+ * @arg: an userspace buffer containing an ifreq structure
+ * Returns:
+ * - EPERM : if caller has no CAP_NET_ADMIN capabilities or the
+ * current level of network namespace is not layer 2
+ * - EFAULT : if arg is an invalid buffer
+ * - EADDRNOTAVAIL : if the specified ifaddr does not exists
+ * - EINVAL : if cmd is unknown
+ * - zero on success
+ */
+int net_ns_ioctl(unsigned int cmd, void __user *arg)
+{
+ struct ifreq ifr;
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
+ struct net_namespace *net_ns = current_net_ns;
+ struct net_device *dev;
+ struct in_device *in_dev;
+ struct in_ifaddr **ifap = NULL;
+ struct in_ifaddr *ifa = NULL;
+ char *colon;
+ int err;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (net_ns->level != NET_NS_LEVEL3)
+ return -EPERM;
+
+ if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
+ return -EFAULT;
+
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
+
+
+ colon = strchr(ifr.ifr_name, ':');
+ if (colon)
+ *colon = 0;
+
+ rtnl_lock();
+
+ err = -ENODEV;
+ dev = __dev_get_by_name(ifr.ifr_name);
+ if (!dev)
+ goto out;
+
+ if (colon)
+ *colon = ':';
+
+ err = -EADDRNOTAVAIL;
+ in_dev = __in_dev_get_rtnl(dev);
+ if (!in_dev)
+ goto out;
+
+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
+ ifap = &ifa->ifa_next)
+ if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
+ sin->sin_addr.s_addr == ifa->ifa_local)
+ break;
+ if (!ifa)
+ goto out;
+
+ err = -EINVAL;
+ switch(cmd) {
+
+ case SIOCNETNSPUSHIF:
+ ifa->ifa_net_ns = net_ns;
+ break;
+
+ case SIOCNETNSPULLIF:
+ ifa->ifa_net_ns = net_ns->parent;
+ break;
+ default:
+ goto out;
+ }
+
+ err = 0;
+out:
+ rtnl_unlock();
+ return err;
+}
+
#endif /* CONFIG_NET_NS */
--
next prev parent reply other threads:[~2007-01-19 16:41 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-19 15:47 [patch 00/12] net namespace : L3 namespace - introduction dlezcano
2007-01-19 15:47 ` [patch 01/12] net namespace : initialize init process to level 2 dlezcano
2007-01-19 15:47 ` [patch 02/12] net namespace : store L2 parent namespace dlezcano
2007-01-19 15:47 ` [patch 03/12] net namespace : share network ressources L2 with L3 dlezcano
2007-01-19 15:47 ` [patch 04/12] net namespace : isolate the inet device dlezcano
2007-01-19 15:47 ` dlezcano [this message]
2007-01-20 4:52 ` [patch 05/12] net namespace : ioctl to push ifa to net namespace l3 Herbert Poetzl
2007-01-20 11:48 ` Daniel Lezcano
2007-01-19 15:47 ` [patch 06/12] net namespace : check bind address dlezcano
2007-01-19 15:47 ` [patch 07/12] net namespace: set source addresse dlezcano
2007-01-19 15:47 ` [patch 08/12] net namespace : find namespace by addr dlezcano
2007-01-20 4:56 ` Herbert Poetzl
2007-01-19 15:47 ` [patch 09/12] net namespace : make loopback address always visible dlezcano
2007-01-19 15:47 ` [patch 10/12] net namespace : add the loopback isolation dlezcano
2007-01-19 15:47 ` [patch 11/12] net namespace : debugfs - add net_ns debugfs dlezcano
2007-01-19 15:47 ` [patch 12/12] net namespace : Add broadcasting dlezcano
2007-01-20 4:58 ` Herbert Poetzl
2007-01-20 11:54 ` Daniel Lezcano
2007-01-20 4:48 ` [patch 00/12] net namespace : L3 namespace - introduction Herbert Poetzl
2007-01-20 11:42 ` Daniel Lezcano
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=20070119155351.915374403@localhost.localdomain \
--to=dlezcano@fr.ibm.com \
--cc=containers@lists.osdl.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).