From: Thomas Parrott Date: Fri, 26 Jul 2019 15:14:18 +0000 (+0100) Subject: lxccontainer: do_lxcapi_detach_interface to support detaching wlan devices X-Git-Tag: lxc-4.0.0~133^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4103cf63f3e24667680544303e7c7230b3d508c;p=thirdparty%2Flxc.git lxccontainer: do_lxcapi_detach_interface to support detaching wlan devices Signed-off-by: Thomas Parrott --- diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 867aa91c0..f63331ede 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -213,7 +213,7 @@ static int lxc_attach_to_ns(pid_t pid, struct lxc_proc_context_info *ctx) return 0; } -static int lxc_attach_remount_sys_proc(void) +int lxc_attach_remount_sys_proc(void) { int ret; diff --git a/src/lxc/attach.h b/src/lxc/attach.h index c576aa9fc..ce7c461b3 100644 --- a/src/lxc/attach.h +++ b/src/lxc/attach.h @@ -45,4 +45,6 @@ extern int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process); +extern int lxc_attach_remount_sys_proc(void); + #endif /* __LXC_ATTACH_H */ diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index d8efdc41c..52c38fd33 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -4793,6 +4793,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, { int ret; pid_t pid, pid_outside; + __do_free char *physname = NULL; /* * TODO - if this is a physical device, then we need am_host_unpriv. @@ -4828,6 +4829,19 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, _exit(EXIT_FAILURE); } + /* create new mount namespace for use with remounting /sys and is_wlan() below. */ + ret = unshare(CLONE_NEWNS); + if (ret < 0) { + ERROR("Failed to unshare mount namespace"); + _exit(EXIT_FAILURE); + } + + /* set / recursively as private so that mount propagation doesn't affect us. */ + if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) < 0) { + ERROR("Failed to recursively set / as private in mount namespace"); + _exit(EXIT_FAILURE); + } + ret = lxc_netdev_isup(ifname); if (ret < 0) { ERROR("Failed to determine whether network device \"%s\" is up", ifname); @@ -4843,7 +4857,14 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, } } - ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname); + /* remount /sys so is_wlan() can check if this device is a wlan device. */ + lxc_attach_remount_sys_proc(); + physname = is_wlan(ifname); + if (physname) + ret = lxc_netdev_move_wlan(physname, ifname, pid_outside, dst_ifname); + else + ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname); + /* -EINVAL means there is no netdev named as ifname. */ if (ret < 0) { if (ret == -EINVAL) diff --git a/src/lxc/network.c b/src/lxc/network.c index 7684f9591..65727f6b5 100644 --- a/src/lxc/network.c +++ b/src/lxc/network.c @@ -1172,7 +1172,7 @@ out: * will be passed to lxc_netdev_move_wlan() which will free it when done. */ #define PHYSNAME "/sys/class/net/%s/phy80211/name" -static char *is_wlan(const char *ifname) +char *is_wlan(const char *ifname) { __do_free char *path = NULL; int i, ret; @@ -1245,7 +1245,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old, _exit(lxc_netdev_rename_by_name(old, new)); } -static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, +int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char *newname) { __do_free char *cmd = NULL; diff --git a/src/lxc/network.h b/src/lxc/network.h index acfd8a053..8a86768d9 100644 --- a/src/lxc/network.h +++ b/src/lxc/network.h @@ -293,4 +293,8 @@ extern int lxc_netns_set_nsid(int netns_fd); extern int lxc_netns_get_nsid(__s32 fd); extern int lxc_create_network(struct lxc_handler *handler); +extern char *is_wlan(const char *ifname); +extern int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, + const char *newname); + #endif /* __LXC_NETWORK_H */