char netns_path[6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1];
bool deleted_all = true;
- if (!am_unpriv())
+ if (handler->root)
return true;
*netns_path = '\0';
int lxc_create_network_priv(struct lxc_handler *handler)
{
- bool am_root;
struct lxc_list *iterator;
struct lxc_list *network = &handler->conf->network;
- /* We need to be root. */
- am_root = (getuid() == 0);
- if (!am_root)
+ if (!handler->root)
return 0;
lxc_list_for_each(iterator, network) {
struct lxc_list *network = &handler->conf->network;
bool deleted_all = true;
- if (am_unpriv())
+ if (!handler->root)
return true;
lxc_list_for_each(iterator, network) {
ret = lxc_netdev_rename_by_index(netdev->ifindex, netdev->link);
if (ret < 0)
WARN("Failed to rename interface with index %d "
- "to its initial name \"%s\"",
- netdev->ifindex, netdev->link);
+ "from \"%s\" to its initial name \"%s\"",
+ netdev->ifindex, netdev->name, netdev->link);
else
TRACE("Renamed interface with index %d to its "
- "initial name \"%s\"",
- netdev->ifindex, netdev->link);
+ "from \"%s\" to its initial name \"%s\"",
+ netdev->ifindex, netdev->name, netdev->link);
continue;
}
}
/* try to move physical nics to the init netns */
-void lxc_restore_phys_nics_to_netns(int netnsfd, struct lxc_conf *conf)
+int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler)
{
int ret;
- int i, oldfd;
+ int oldfd;
char ifname[IFNAMSIZ];
+ struct lxc_list *iterator;
+ int netnsfd = handler->netnsfd;
+ struct lxc_conf *conf = handler->conf;
- if (netnsfd < 0 || conf->num_savednics == 0)
- return;
+ /* We need CAP_NET_ADMIN in the parent namespace in order to setns() to
+ * the parent network namespace. We won't have this capability if we are
+ * unprivileged.
+ */
+ if (!handler->root)
+ return 0;
- INFO("Trying to restore network device names in original namespace for "
- "%d network devices", conf->num_savednics);
+ TRACE("Moving physical network devices back to parent network namespace");
oldfd = lxc_preserve_ns(getpid(), "net");
if (oldfd < 0) {
SYSERROR("Failed to preserve network namespace");
- return;
+ return -1;
}
- ret = setns(netnsfd, 0);
+ ret = setns(netnsfd, CLONE_NEWNET);
if (ret < 0) {
SYSERROR("Failed to enter network namespace");
close(oldfd);
- return;
+ return -1;
}
- for (i = 0; i < conf->num_savednics; i++) {
- struct saved_nic *s = &conf->saved_nics[i];
+ lxc_list_for_each(iterator, &conf->network) {
+ struct lxc_netdev *netdev = iterator->elem;
- /* retrieve the name of the interface */
- if (!if_indextoname(s->ifindex, ifname)) {
+ if (netdev->type != LXC_NET_PHYS)
+ continue;
+
+ /* Retrieve the name of the interface in the container's network
+ * namespace.
+ */
+ if (!if_indextoname(netdev->ifindex, ifname)) {
WARN("No interface corresponding to ifindex %d",
- s->ifindex);
+ netdev->ifindex);
continue;
}
- if (lxc_netdev_move_by_name(ifname, 1, s->orig_name))
+
+ ret = lxc_netdev_move_by_name(ifname, 1, netdev->link);
+ if (ret < 0)
WARN("Error moving network device \"%s\" back to "
"network namespace", ifname);
- free(s->orig_name);
+ else
+ TRACE("Moved network device \"%s\" back to network "
+ "namespace", ifname);
}
- conf->num_savednics = 0;
- ret = setns(oldfd, 0);
- if (ret < 0)
- SYSERROR("Failed to enter network namespace");
+ ret = setns(oldfd, CLONE_NEWNET);
close(oldfd);
+ if (ret < 0) {
+ SYSERROR("Failed to enter network namespace");
+ return -1;
+ }
+
+ return 0;
}
static int setup_hw_addr(char *hwaddr, const char *ifname)
return -1;
}
-static int save_phys_nics(struct lxc_conf *conf)
-{
- struct lxc_list *iterator;
- int am_root = (getuid() == 0);
-
- if (!am_root)
- return 0;
-
- lxc_list_for_each(iterator, &conf->network) {
- struct lxc_netdev *netdev = iterator->elem;
-
- if (netdev->type != LXC_NET_PHYS)
- continue;
- conf->saved_nics = realloc(conf->saved_nics,
- (conf->num_savednics+1)*sizeof(struct saved_nic));
- if (!conf->saved_nics)
- return -1;
- conf->saved_nics[conf->num_savednics].ifindex = netdev->ifindex;
- conf->saved_nics[conf->num_savednics].orig_name = strdup(netdev->link);
- if (!conf->saved_nics[conf->num_savednics].orig_name)
- return -1;
- INFO("Stored saved_nic #%d idx %d name %s.", conf->num_savednics,
- conf->saved_nics[conf->num_savednics].ifindex,
- conf->saved_nics[conf->num_savednics].orig_name);
- conf->num_savednics++;
- }
-
- return 0;
-}
-
static int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler)
{
struct lxc_list *iterator, *network;
return -1;
}
}
-
- if (save_phys_nics(handler->conf)) {
- ERROR("Failed to save physical nic info.");
- goto out_abort;
- }
}
if (!cgroup_init(handler)) {
}
}
- DEBUG("Pushing physical nics back to host namespace");
- lxc_restore_phys_nics_to_netns(handler->netnsfd, handler->conf);
+ err = lxc_restore_phys_nics_to_netns(handler);
+ if (err < 0)
+ ERROR("Failed to move physical network devices back to parent "
+ "network namespace");
if (handler->pinfd >= 0) {
close(handler->pinfd);