From: Serge Hallyn Date: Wed, 23 Oct 2013 15:52:37 +0000 (-0500) Subject: start: use lxc-user-nic if we are not root X-Git-Tag: lxc-1.0.0.alpha3~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbef6c52bea93130abd8920c4b4dd1780548ac7b;p=thirdparty%2Flxc.git start: use lxc-user-nic if we are not root Note this results in nics named things like 'lxcuser-0p'. We'll likely want to pass the requested name to lxc-user-nic, but let's do that in a separate patch. If we're not root, we can't create new network itnerfaces to pass into the container. Instead wait until the container is started, and call lxc-user-nic to create and assign the nics. Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 043719cde..f579c17db 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2687,6 +2687,10 @@ int lxc_create_network(struct lxc_handler *handler) struct lxc_list *network = &handler->conf->network; struct lxc_list *iterator; struct lxc_netdev *netdev; + int am_root = (getuid() == 0); + + if (!am_root) + return 0; lxc_list_for_each(iterator, network) { @@ -2738,16 +2742,51 @@ void lxc_delete_network(struct lxc_handler *handler) } } +int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t pid) +{ + pid_t child; + + if (netdev->type != LXC_NET_VETH) { + ERROR("nic type %d not support for unprivileged use", + netdev->type); + return -1; + } + + if ((child = fork()) < 0) { + SYSERROR("fork"); + return -1; + } + + if (child > 0) + return wait_for_pid(child); + + // Call lxc-user-nic pid type bridge + char pidstr[20]; + char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, NULL }; + snprintf(pidstr, 19, "%lu", (unsigned long) pid); + pidstr[19] = '\0'; + execvp("lxc-user-nic", args); + SYSERROR("execvp lxc-user-nic"); + exit(1); +} + int lxc_assign_network(struct lxc_list *network, pid_t pid) { struct lxc_list *iterator; struct lxc_netdev *netdev; + int am_root = (getuid() == 0); int err; lxc_list_for_each(iterator, network) { netdev = iterator->elem; + if (!am_root) { + if (unpriv_assign_nic(netdev, pid)) + return -1; + // TODO fill in netdev->ifindex and name + continue; + } /* empty network namespace, nothing to move */ if (!netdev->ifindex) continue;