nspawn-network: split out move_back_network_interfaces()

No functional change, just refactoring and preparation for later
commits.
This commit is contained in:
Yu Watanabe
2024-01-19 19:05:25 +09:00
parent d926864073
commit cdd9988e43
3 changed files with 81 additions and 38 deletions
+79
View File
@@ -11,13 +11,16 @@
#include "alloc-util.h"
#include "ether-addr-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
#include "lock-util.h"
#include "missing_network.h"
#include "namespace-util.h"
#include "netif-naming-scheme.h"
#include "netlink-util.h"
#include "nspawn-network.h"
#include "parse-util.h"
#include "process-util.h"
#include "siphash24.h"
#include "socket-netlink.h"
#include "socket-util.h"
@@ -503,6 +506,58 @@ int test_network_interfaces_initialized(char **iface_pairs) {
return 0;
}
static int netns_child_begin(int netns_fd, int *ret_original_netns_fd) {
_cleanup_close_ int original_netns_fd = -EBADF;
int r;
assert(netns_fd >= 0);
if (ret_original_netns_fd) {
r = namespace_open(0,
/* ret_pidns_fd = */ NULL,
/* ret_mntns_fd = */ NULL,
&original_netns_fd,
/* ret_userns_fd = */ NULL,
/* ret_root_fd = */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to open original network namespace: %m");
}
r = namespace_enter(/* pidns_fd = */ -EBADF,
/* mntns_fd = */ -EBADF,
netns_fd,
/* userns_fd = */ -EBADF,
/* root_fd = */ -EBADF);
if (r < 0)
return log_error_errno(r, "Failed to enter child network namespace: %m");
if (ret_original_netns_fd)
*ret_original_netns_fd = TAKE_FD(original_netns_fd);
return 0;
}
static int netns_fork_and_wait(int netns_fd, int *ret_original_netns_fd) {
int r;
assert(netns_fd >= 0);
r = safe_fork("(sd-netns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
if (r < 0)
return log_error_errno(r, "Failed to fork process (sd-netns): %m");
if (r == 0) {
if (netns_child_begin(netns_fd, ret_original_netns_fd) < 0)
_exit(EXIT_FAILURE);
return 0;
}
if (ret_original_netns_fd)
*ret_original_netns_fd = -EBADF;
return 1;
}
int move_network_interfaces(int netns_fd, char **iface_pairs) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
int r;
@@ -544,6 +599,30 @@ int move_network_interfaces(int netns_fd, char **iface_pairs) {
return 0;
}
int move_back_network_interfaces(int child_netns_fd, char **interface_pairs) {
_cleanup_close_ int parent_netns_fd = -EBADF;
int r;
assert(child_netns_fd >= 0);
if (strv_isempty(interface_pairs))
return 0;
r = netns_fork_and_wait(child_netns_fd, &parent_netns_fd);
if (r < 0)
return r;
if (r == 0) {
/* Reverse network interfaces pair list so that interfaces get their initial name back.
* This is about ensuring interfaces get their old name back when being moved back. */
interface_pairs = strv_reverse(interface_pairs);
r = move_network_interfaces(parent_netns_fd, interface_pairs);
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
return 0;
}
int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
unsigned idx = 0;
+1
View File
@@ -19,6 +19,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs);
int setup_ipvlan(const char *machine_name, pid_t pid, char **iface_pairs);
int move_network_interfaces(int netns_fd, char **iface_pairs);
int move_back_network_interfaces(int child_netns_fd, char **interface_pairs);
int veth_extra_parse(char ***l, const char *p);
+1 -38
View File
@@ -5377,46 +5377,9 @@ static int run_container(
fd_kmsg_fifo = safe_close(fd_kmsg_fifo);
if (arg_private_network) {
/* Move network interfaces back to the parent network namespace. We use `safe_fork`
* to avoid having to move the parent to the child network namespace. */
r = safe_fork(NULL, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
r = move_back_network_interfaces(child_netns_fd, arg_network_interfaces);
if (r < 0)
return r;
if (r == 0) {
_cleanup_close_ int parent_netns_fd = -EBADF;
r = namespace_open(0,
/* ret_pidns_fd = */ NULL,
/* ret_mntns_fd = */ NULL,
&parent_netns_fd,
/* ret_userns_fd = */ NULL,
/* ret_root_fd = */ NULL);
if (r < 0) {
log_error_errno(r, "Failed to open parent network namespace: %m");
_exit(EXIT_FAILURE);
}
r = namespace_enter(/* pidns_fd = */ -EBADF,
/* mntns_fd = */ -EBADF,
child_netns_fd,
/* userns_fd = */ -EBADF,
/* root_fd = */ -EBADF);
if (r < 0) {
log_error_errno(r, "Failed to enter child network namespace: %m");
_exit(EXIT_FAILURE);
}
/* Reverse network interfaces pair list so that interfaces get their initial name back.
* This is about ensuring interfaces get their old name back when being moved back. */
arg_network_interfaces = strv_reverse(arg_network_interfaces);
r = move_network_interfaces(parent_netns_fd, arg_network_interfaces);
if (r < 0)
log_error_errno(r, "Failed to move network interfaces back to parent network namespace: %m");
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
}
r = wait_for_container(TAKE_PID(*pid), &container_status);