[lxc-devel] [PATCH 1/1] lxc-user-nic: compute first available nic name in container

Serge Hallyn serge.hallyn at ubuntu.com
Mon Jul 21 21:44:21 UTC 2014


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Mon, Jul 21, 2014 at 07:27:02PM +0000, Serge Hallyn wrote:
> > Rather than always using eth0.  Otherwise unpriv containers cannot have
> > multiple lxc.network.type = veth's without manually setting
> > lxc.network.name =.
> > 
> > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> > ---
> >  src/lxc/lxc_user_nic.c | 31 ++++++++++++++++++++++++++-----
> >  1 file changed, 26 insertions(+), 5 deletions(-)
> > 
> > diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
> > index 1105b3d..75e4851 100644
> > --- a/src/lxc/lxc_user_nic.c
> > +++ b/src/lxc/lxc_user_nic.c
> > @@ -470,7 +470,7 @@ again:
> >  	goto again;
> >  }
> >  
> > -static int rename_in_ns(int pid, char *oldname, char *newname)
> > +static int rename_in_ns(int pid, char *oldname, char **newnamep)
> >  {
> >  	char nspath[MAXPATHLEN];
> >  	int fd = -1, ofd = -1, ret;
> > @@ -495,8 +495,29 @@ static int rename_in_ns(int pid, char *oldname, char *newname)
> >  		goto out_err;
> >  	}
> >  	close(fd); fd = -1;
> > -	if ((ret = lxc_netdev_rename_by_name(oldname, newname)) < 0) {
> > -		fprintf(stderr, "Error %d renaming netdev %s to %s in container\n", ret, oldname, newname);
> > +
> > +	if (!*newnamep) {
> > +		int i = 0;
> > +		char nicname[10];
> > +		while (i < 100) {
> > +			ret = snprintf(nicname, 10, "eth%d", i);
> > +			if (ret < 0 || ret >= 10)
> > +				return -1;
> > +			if (if_nametoindex(nicname) == 0)
> > +				break;
> > +			i++;
> > +		}
> > +		if (i == 100) {
> > +			fprintf(stderr, "too many nics in container\n");
> > +			return -1;
> > +		}
> > +		*newnamep = strdup(nicname);
> > +		if (!*newnamep)
> > +			return -1;
> > +	}
> 
> As I said on IRC, are you sure we can't somehow get rid of all of that
> code and just somehow pass 'eth%d' to the kernel through netlink which
> will then make it use the next available ethX device (we already use
> that trick for privileged networking).

>From 01950a5f05c6a9d1a6aed05c993ba2d1952c65a9 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn at ubuntu.com>
Date: Mon, 21 Jul 2014 16:36:44 -0500
Subject: [PATCH 1/1] unprivileged containers: use next available nic name if
 unspecified

Rather than always using eth0.  Otherwise unpriv containers cannot have
multiple lxc.network.type = veth's without manually setting
lxc.network.name =.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/lxc_user_nic.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
index 1105b3d..5a1f6db 100644
--- a/src/lxc/lxc_user_nic.c
+++ b/src/lxc/lxc_user_nic.c
@@ -470,10 +470,13 @@ again:
 	goto again;
 }
 
-static int rename_in_ns(int pid, char *oldname, char *newname)
+#define VETH_DEF_NAME "eth%d"
+
+static int rename_in_ns(int pid, char *oldname, char **newnamep)
 {
 	char nspath[MAXPATHLEN];
-	int fd = -1, ofd = -1, ret;
+	int fd = -1, ofd = -1, ret, ifindex;
+	bool grab_newname = false;
 
 	ret = snprintf(nspath, MAXPATHLEN, "/proc/%d/ns/net", getpid());
 	if (ret < 0 || ret >= MAXPATHLEN)
@@ -495,10 +498,28 @@ static int rename_in_ns(int pid, char *oldname, char *newname)
 		goto out_err;
 	}
 	close(fd); fd = -1;
-	if ((ret = lxc_netdev_rename_by_name(oldname, newname)) < 0) {
-		fprintf(stderr, "Error %d renaming netdev %s to %s in container\n", ret, oldname, newname);
+	if (!*newnamep) {
+		grab_newname = true;
+		*newnamep = VETH_DEF_NAME;
+		if (!(ifindex = if_nametoindex(oldname))) {
+			fprintf(stderr, "failed to get netdev index\n");
+			goto out_err;
+		}
+	}
+	if ((ret = lxc_netdev_rename_by_name(oldname, *newnamep)) < 0) {
+		fprintf(stderr, "Error %d renaming netdev %s to %s in container\n", ret, oldname, *newnamep);
 		goto out_err;
 	}
+	if (grab_newname) {
+		char ifname[IFNAMSIZ], *namep = ifname;
+		if (!if_indextoname(ifindex, namep)) {
+			fprintf(stderr, "Failed to get new netdev name\n");
+			goto out_err;
+		}
+		*newnamep = strdup(namep);
+		if (!*newnamep)
+			goto out_err;
+	}
 	if (setns(ofd, 0) < 0) {
 		fprintf(stderr, "Error returning to original netns\n");
 		close(ofd);
@@ -566,7 +587,7 @@ int main(int argc, char *argv[])
 	char *me;
 	char *nicname = alloca(40);
 	char *cnic = NULL; // created nic name in container is returned here.
-	char *vethname;
+	char *vethname = NULL;
 	int pid;
 
 	if ((me = get_username()) == NULL) {
@@ -578,8 +599,6 @@ int main(int argc, char *argv[])
 		usage(argv[0], true);
 	if (argc >= 5)
 		vethname = argv[4];
-	else
-		vethname = "eth0";
 
 	errno = 0;
 	pid = (int) strtol(argv[1], NULL, 10);
@@ -614,7 +633,7 @@ int main(int argc, char *argv[])
 	}
 
 	// Now rename the link
-	if (rename_in_ns(pid, cnic, vethname) < 0) {
+	if (rename_in_ns(pid, cnic, &vethname) < 0) {
 		fprintf(stderr, "Failed to rename the link\n");
 		exit(1);
 	}
-- 
1.9.1



More information about the lxc-devel mailing list