]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/nspawn/nspawn-network.c
NEWS: mention backward incompatibility of IP forwarding
[thirdparty/systemd.git] / src / nspawn / nspawn-network.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
9a2a5625 2
edda10f2 3/* Make sure the net/if.h header is included before any linux/ one */
6b50cb5c
YW
4#include <net/if.h>
5#include <linux/if.h>
1c3e5b42 6#include <linux/nl80211.h>
9a2a5625 7#include <linux/veth.h>
fe993888 8#include <sys/file.h>
38475cac 9#include <sys/mount.h>
9a2a5625 10
f55b0d3f 11#include "sd-device.h"
9a2a5625
LP
12#include "sd-id128.h"
13#include "sd-netlink.h"
9a2a5625 14
b5efdb8a 15#include "alloc-util.h"
1c3e5b42 16#include "device-private.h"
38475cac 17#include "device-util.h"
9a2a5625 18#include "ether-addr-util.h"
cdd9988e 19#include "fd-util.h"
130298ba 20#include "hexdecoct.h"
64e89f56 21#include "lock-util.h"
204f52e3 22#include "missing_network.h"
38475cac
YW
23#include "mkdir.h"
24#include "mount-util.h"
cdd9988e 25#include "namespace-util.h"
bc5ea049 26#include "netif-naming-scheme.h"
c50e7dca 27#include "netif-util.h"
9a2a5625 28#include "netlink-util.h"
cf0fbc49 29#include "nspawn-network.h"
a0267b30 30#include "parse-util.h"
cdd9988e 31#include "process-util.h"
07630cea 32#include "siphash24.h"
d308bb99 33#include "socket-netlink.h"
ef76dff2
LP
34#include "socket-util.h"
35#include "stat-util.h"
07630cea 36#include "string-util.h"
f55b0d3f 37#include "strv.h"
26208d5b 38#include "udev-util.h"
9a2a5625
LP
39
40#define HOST_HASH_KEY SD_ID128_MAKE(1a,37,6f,c7,46,ec,45,0b,ad,a3,d5,31,06,60,5d,b1)
41#define CONTAINER_HASH_KEY SD_ID128_MAKE(c3,c4,f9,19,b5,57,b2,1c,e6,cf,14,27,03,9c,ee,a2)
f6d6bad1
LP
42#define VETH_EXTRA_HOST_HASH_KEY SD_ID128_MAKE(48,c7,f6,b7,ea,9d,4c,9e,b7,28,d4,de,91,d5,bf,66)
43#define VETH_EXTRA_CONTAINER_HASH_KEY SD_ID128_MAKE(af,50,17,61,ce,f9,4d,35,84,0d,2b,20,54,be,ce,59)
9a2a5625
LP
44#define MACVLAN_HASH_KEY SD_ID128_MAKE(00,13,6d,bc,66,83,44,81,bb,0c,f9,51,1f,24,a6,6f)
45
22b28dfd
LP
46static int remove_one_link(sd_netlink *rtnl, const char *name) {
47 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
48 int r;
49
50 if (isempty(name))
51 return 0;
52
53 r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, 0);
54 if (r < 0)
55 return log_error_errno(r, "Failed to allocate netlink message: %m");
56
57 r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
58 if (r < 0)
59 return log_error_errno(r, "Failed to add netlink interface name: %m");
60
61 r = sd_netlink_call(rtnl, m, 0, NULL);
62 if (r == -ENODEV) /* Already gone */
63 return 0;
64 if (r < 0)
65 return log_error_errno(r, "Failed to remove interface %s: %m", name);
66
67 return 1;
68}
69
6b50cb5c
YW
70static int set_alternative_ifname(sd_netlink *rtnl, const char *ifname, const char *altifname) {
71 int r;
72
73 assert(rtnl);
74 assert(ifname);
75
76 if (!altifname)
77 return 0;
78
79 if (strlen(altifname) >= ALTIFNAMSIZ)
80 return log_warning_errno(SYNTHETIC_ERRNO(ERANGE),
81 "Alternative interface name '%s' for '%s' is too long, ignoring",
82 altifname, ifname);
83
84 r = rtnl_set_link_alternative_names_by_ifname(&rtnl, ifname, STRV_MAKE(altifname));
85 if (r < 0)
86 return log_warning_errno(r,
87 "Failed to set alternative interface name '%s' to '%s', ignoring: %m",
88 altifname, ifname);
89
90 return 0;
91}
92
f6d6bad1
LP
93static int add_veth(
94 sd_netlink *rtnl,
95 pid_t pid,
96 const char *ifname_host,
6b50cb5c 97 const char *altifname_host,
f6d6bad1
LP
98 const struct ether_addr *mac_host,
99 const char *ifname_container,
100 const struct ether_addr *mac_container) {
9a2a5625 101
4afd3348 102 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
f6d6bad1 103 int r;
9a2a5625 104
f6d6bad1
LP
105 assert(rtnl);
106 assert(ifname_host);
107 assert(mac_host);
108 assert(ifname_container);
109 assert(mac_container);
9a2a5625
LP
110
111 r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
112 if (r < 0)
113 return log_error_errno(r, "Failed to allocate netlink message: %m");
114
f6d6bad1 115 r = sd_netlink_message_append_string(m, IFLA_IFNAME, ifname_host);
9a2a5625
LP
116 if (r < 0)
117 return log_error_errno(r, "Failed to add netlink interface name: %m");
118
f6d6bad1 119 r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, mac_host);
9a2a5625
LP
120 if (r < 0)
121 return log_error_errno(r, "Failed to add netlink MAC address: %m");
122
123 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
124 if (r < 0)
125 return log_error_errno(r, "Failed to open netlink container: %m");
126
127 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "veth");
128 if (r < 0)
129 return log_error_errno(r, "Failed to open netlink container: %m");
130
131 r = sd_netlink_message_open_container(m, VETH_INFO_PEER);
132 if (r < 0)
133 return log_error_errno(r, "Failed to open netlink container: %m");
134
f6d6bad1 135 r = sd_netlink_message_append_string(m, IFLA_IFNAME, ifname_container);
9a2a5625
LP
136 if (r < 0)
137 return log_error_errno(r, "Failed to add netlink interface name: %m");
138
f6d6bad1 139 r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, mac_container);
9a2a5625
LP
140 if (r < 0)
141 return log_error_errno(r, "Failed to add netlink MAC address: %m");
142
143 r = sd_netlink_message_append_u32(m, IFLA_NET_NS_PID, pid);
144 if (r < 0)
145 return log_error_errno(r, "Failed to add netlink namespace field: %m");
146
147 r = sd_netlink_message_close_container(m);
148 if (r < 0)
149 return log_error_errno(r, "Failed to close netlink container: %m");
150
151 r = sd_netlink_message_close_container(m);
152 if (r < 0)
153 return log_error_errno(r, "Failed to close netlink container: %m");
154
155 r = sd_netlink_message_close_container(m);
156 if (r < 0)
157 return log_error_errno(r, "Failed to close netlink container: %m");
158
159 r = sd_netlink_call(rtnl, m, 0, NULL);
160 if (r < 0)
f6d6bad1
LP
161 return log_error_errno(r, "Failed to add new veth interfaces (%s:%s): %m", ifname_host, ifname_container);
162
6b50cb5c
YW
163 (void) set_alternative_ifname(rtnl, ifname_host, altifname_host);
164
f6d6bad1
LP
165 return 0;
166}
167
168int setup_veth(const char *machine_name,
169 pid_t pid,
170 char iface_name[IFNAMSIZ],
813dbff4 171 bool bridge,
5e21da87 172 const struct ether_addr *provided_mac) {
f6d6bad1 173
4afd3348 174 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
f6d6bad1 175 struct ether_addr mac_host, mac_container;
bc5ea049 176 unsigned u;
6b50cb5c 177 char *n, *a = NULL;
bc5ea049 178 int r;
f6d6bad1
LP
179
180 assert(machine_name);
181 assert(pid > 0);
182 assert(iface_name);
183
184 /* Use two different interface name prefixes depending whether
185 * we are in bridge mode or not. */
bc5ea049 186 n = strjoina(bridge ? "vb-" : "ve-", machine_name);
c50e7dca 187 r = net_shorten_ifname(n, /* check_naming_scheme= */ true);
6b50cb5c
YW
188 if (r > 0)
189 a = strjoina(bridge ? "vb-" : "ve-", machine_name);
f6d6bad1 190
813dbff4 191 if (ether_addr_is_null(provided_mac)){
c50e7dca 192 r = net_generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
813dbff4
RC
193 if (r < 0)
194 return log_error_errno(r, "Failed to generate predictable MAC address for container side: %m");
195 } else
196 mac_container = *provided_mac;
f6d6bad1 197
c50e7dca 198 r = net_generate_mac(machine_name, &mac_host, HOST_HASH_KEY, 0);
f6d6bad1
LP
199 if (r < 0)
200 return log_error_errno(r, "Failed to generate predictable MAC address for host side: %m");
201
202 r = sd_netlink_open(&rtnl);
203 if (r < 0)
204 return log_error_errno(r, "Failed to connect to netlink: %m");
205
6b50cb5c 206 r = add_veth(rtnl, pid, n, a, &mac_host, "host0", &mac_container);
f6d6bad1
LP
207 if (r < 0)
208 return r;
9a2a5625 209
f6e49154 210 u = if_nametoindex(n); /* We don't need to use rtnl_resolve_ifname() here because the
d308bb99 211 * name we assigned is always the main name. */
bc5ea049
KK
212 if (u == 0)
213 return log_error_errno(errno, "Failed to resolve interface %s: %m", n);
9a2a5625 214
bc5ea049
KK
215 strcpy(iface_name, n);
216 return (int) u;
9a2a5625
LP
217}
218
f6d6bad1
LP
219int setup_veth_extra(
220 const char *machine_name,
221 pid_t pid,
222 char **pairs) {
223
4afd3348 224 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
f6d6bad1 225 uint64_t idx = 0;
f6d6bad1
LP
226 int r;
227
228 assert(machine_name);
229 assert(pid > 0);
230
231 if (strv_isempty(pairs))
232 return 0;
233
234 r = sd_netlink_open(&rtnl);
235 if (r < 0)
236 return log_error_errno(r, "Failed to connect to netlink: %m");
237
238 STRV_FOREACH_PAIR(a, b, pairs) {
239 struct ether_addr mac_host, mac_container;
240
c50e7dca 241 r = net_generate_mac(machine_name, &mac_container, VETH_EXTRA_CONTAINER_HASH_KEY, idx);
f6d6bad1
LP
242 if (r < 0)
243 return log_error_errno(r, "Failed to generate predictable MAC address for container side of extra veth link: %m");
244
c50e7dca 245 r = net_generate_mac(machine_name, &mac_host, VETH_EXTRA_HOST_HASH_KEY, idx);
f6d6bad1 246 if (r < 0)
bcc0fe63 247 return log_error_errno(r, "Failed to generate predictable MAC address for host side of extra veth link: %m");
f6d6bad1 248
6b50cb5c 249 r = add_veth(rtnl, pid, *a, NULL, &mac_host, *b, &mac_container);
f6d6bad1
LP
250 if (r < 0)
251 return r;
252
313cefa1 253 idx++;
f6d6bad1
LP
254 }
255
256 return 0;
257}
258
22b28dfd 259static int join_bridge(sd_netlink *rtnl, const char *veth_name, const char *bridge_name) {
4afd3348 260 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
9a2a5625
LP
261 int r, bridge_ifi;
262
22b28dfd 263 assert(rtnl);
9a2a5625
LP
264 assert(veth_name);
265 assert(bridge_name);
266
f6e49154 267 bridge_ifi = rtnl_resolve_interface(&rtnl, bridge_name);
597da51b
ZJS
268 if (bridge_ifi < 0)
269 return bridge_ifi;
9a2a5625
LP
270
271 r = sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, 0);
272 if (r < 0)
22b28dfd 273 return r;
9a2a5625
LP
274
275 r = sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP);
276 if (r < 0)
22b28dfd 277 return r;
9a2a5625
LP
278
279 r = sd_netlink_message_append_string(m, IFLA_IFNAME, veth_name);
280 if (r < 0)
22b28dfd 281 return r;
9a2a5625
LP
282
283 r = sd_netlink_message_append_u32(m, IFLA_MASTER, bridge_ifi);
284 if (r < 0)
22b28dfd 285 return r;
9a2a5625
LP
286
287 r = sd_netlink_call(rtnl, m, 0, NULL);
288 if (r < 0)
22b28dfd 289 return r;
9a2a5625
LP
290
291 return bridge_ifi;
292}
293
22b28dfd
LP
294static int create_bridge(sd_netlink *rtnl, const char *bridge_name) {
295 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
296 int r;
297
298 r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
299 if (r < 0)
300 return r;
301
302 r = sd_netlink_message_append_string(m, IFLA_IFNAME, bridge_name);
303 if (r < 0)
304 return r;
305
306 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
307 if (r < 0)
308 return r;
309
310 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "bridge");
311 if (r < 0)
312 return r;
313
314 r = sd_netlink_message_close_container(m);
315 if (r < 0)
316 return r;
317
318 r = sd_netlink_message_close_container(m);
319 if (r < 0)
320 return r;
321
322 r = sd_netlink_call(rtnl, m, 0, NULL);
323 if (r < 0)
324 return r;
325
326 return 0;
327}
328
329int setup_bridge(const char *veth_name, const char *bridge_name, bool create) {
8e766630 330 _cleanup_(release_lock_file) LockFile bridge_lock = LOCK_FILE_INIT;
22b28dfd
LP
331 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
332 int r, bridge_ifi;
333 unsigned n = 0;
334
335 assert(veth_name);
336 assert(bridge_name);
337
338 r = sd_netlink_open(&rtnl);
339 if (r < 0)
340 return log_error_errno(r, "Failed to connect to netlink: %m");
341
342 if (create) {
343 /* We take a system-wide lock here, so that we can safely check whether there's still a member in the
6dd6a9c4 344 * bridge before removing it, without risking interference from other nspawn instances. */
22b28dfd
LP
345
346 r = make_lock_file("/run/systemd/nspawn-network-zone", LOCK_EX, &bridge_lock);
347 if (r < 0)
348 return log_error_errno(r, "Failed to take network zone lock: %m");
349 }
350
351 for (;;) {
352 bridge_ifi = join_bridge(rtnl, veth_name, bridge_name);
353 if (bridge_ifi >= 0)
354 return bridge_ifi;
355 if (bridge_ifi != -ENODEV || !create || n > 10)
356 return log_error_errno(bridge_ifi, "Failed to add interface %s to bridge %s: %m", veth_name, bridge_name);
357
358 /* Count attempts, so that we don't enter an endless loop here. */
359 n++;
360
361 /* The bridge doesn't exist yet. Let's create it */
362 r = create_bridge(rtnl, bridge_name);
363 if (r < 0)
364 return log_error_errno(r, "Failed to create bridge interface %s: %m", bridge_name);
365
366 /* Try again, now that the bridge exists */
367 }
368}
369
370int remove_bridge(const char *bridge_name) {
8e766630 371 _cleanup_(release_lock_file) LockFile bridge_lock = LOCK_FILE_INIT;
22b28dfd
LP
372 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
373 const char *path;
374 int r;
375
376 /* Removes the specified bridge, but only if it is currently empty */
377
378 if (isempty(bridge_name))
379 return 0;
380
381 r = make_lock_file("/run/systemd/nspawn-network-zone", LOCK_EX, &bridge_lock);
382 if (r < 0)
383 return log_error_errno(r, "Failed to take network zone lock: %m");
384
385 path = strjoina("/sys/class/net/", bridge_name, "/brif");
386
db55bbf2 387 r = dir_is_empty(path, /* ignore_hidden_or_backup= */ false);
22b28dfd
LP
388 if (r == -ENOENT) /* Already gone? */
389 return 0;
390 if (r < 0)
391 return log_error_errno(r, "Can't detect if bridge %s is empty: %m", bridge_name);
392 if (r == 0) /* Still populated, leave it around */
393 return 0;
394
395 r = sd_netlink_open(&rtnl);
396 if (r < 0)
397 return log_error_errno(r, "Failed to connect to netlink: %m");
398
399 return remove_one_link(rtnl, bridge_name);
400}
401
2f091b1b 402static int test_network_interface_initialized(const char *name) {
b390f178 403 _cleanup_(sd_device_unrefp) sd_device *d = NULL;
0ac655a6 404 int r;
26208d5b 405
c76b8751 406 if (!udev_available())
b390f178 407 return 0;
26208d5b 408
b390f178 409 /* udev should be around. */
26208d5b 410
0ac655a6 411 r = sd_device_new_from_ifname(&d, name);
b390f178
DDM
412 if (r < 0)
413 return log_error_errno(r, "Failed to get device %s: %m", name);
414
54e61725 415 r = device_is_processed(d);
b390f178
DDM
416 if (r < 0)
417 return log_error_errno(r, "Failed to determine whether interface %s is initialized: %m", name);
418 if (r == 0)
419 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Network interface %s is not initialized yet.", name);
420
421 r = device_is_renaming(d);
422 if (r < 0)
423 return log_error_errno(r, "Failed to determine the interface %s is being renamed: %m", name);
424 if (r > 0)
425 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Interface %s is being renamed.", name);
426
427 return 0;
9a2a5625
LP
428}
429
2f091b1b
TM
430int test_network_interfaces_initialized(char **iface_pairs) {
431 int r;
432 STRV_FOREACH_PAIR(a, b, iface_pairs) {
433 r = test_network_interface_initialized(*a);
434 if (r < 0)
435 return r;
436 }
437 return 0;
438}
439
a342d9e0
YW
440int resolve_network_interface_names(char **iface_pairs) {
441 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
442 int r;
443
444 /* Due to a bug in kernel fixed by 8e15aee621618a3ee3abecaf1fd8c1428098b7ef (v6.6, backported to
445 * 6.1.60 and 6.5.9), an interface with alternative names cannot be resolved by the alternative name
446 * if the interface is moved to another network namespace. Hence, we need to adjust the provided
447 * names before moving interfaces to container namespace. */
448
449 STRV_FOREACH_PAIR(from, to, iface_pairs) {
450 _cleanup_free_ char *name = NULL;
451 _cleanup_strv_free_ char **altnames = NULL;
452
453 r = rtnl_resolve_ifname_full(&rtnl, _RESOLVE_IFNAME_ALL, *from, &name, &altnames);
454 if (r < 0)
455 return r;
456
457 /* Always use the resolved name for 'from'. */
458 free_and_replace(*from, name);
459
460 /* If the name 'to' is assigned as an alternative name, we cannot rename the interface.
461 * Hence, use the assigned interface name (including the alternative names) as is, and
462 * use the resolved name for 'to'. */
463 if (strv_contains(altnames, *to)) {
464 r = free_and_strdup_warn(to, *from);
465 if (r < 0)
466 return r;
467 }
468 }
469 return 0;
470}
471
cdd9988e
YW
472static int netns_child_begin(int netns_fd, int *ret_original_netns_fd) {
473 _cleanup_close_ int original_netns_fd = -EBADF;
474 int r;
475
476 assert(netns_fd >= 0);
477
478 if (ret_original_netns_fd) {
479 r = namespace_open(0,
480 /* ret_pidns_fd = */ NULL,
481 /* ret_mntns_fd = */ NULL,
482 &original_netns_fd,
483 /* ret_userns_fd = */ NULL,
484 /* ret_root_fd = */ NULL);
485 if (r < 0)
486 return log_error_errno(r, "Failed to open original network namespace: %m");
487 }
488
489 r = namespace_enter(/* pidns_fd = */ -EBADF,
490 /* mntns_fd = */ -EBADF,
491 netns_fd,
492 /* userns_fd = */ -EBADF,
493 /* root_fd = */ -EBADF);
494 if (r < 0)
495 return log_error_errno(r, "Failed to enter child network namespace: %m");
496
38475cac
YW
497 r = umount_recursive("/sys/", /* flags = */ 0);
498 if (r < 0)
499 log_debug_errno(r, "Failed to unmount directories below /sys/, ignoring: %m");
500
501 (void) mkdir_p("/sys/", 0755);
502
503 /* Populate new sysfs instance associated with the client netns, to make sd_device usable. */
504 r = mount_nofollow_verbose(LOG_ERR, "sysfs", "/sys/", "sysfs",
505 MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, /* opts = */ NULL);
506 if (r < 0)
507 return log_error_errno(r, "Failed to mount sysfs on /sys/: %m");
508
509 /* udev_avaliable() might be called previously and the result may be cached.
510 * Now, we (re-)mount sysfs. Hence, we need to reset the cache. */
511 reset_cached_udev_availability();
512
cdd9988e
YW
513 if (ret_original_netns_fd)
514 *ret_original_netns_fd = TAKE_FD(original_netns_fd);
515
516 return 0;
517}
518
519static int netns_fork_and_wait(int netns_fd, int *ret_original_netns_fd) {
520 int r;
521
522 assert(netns_fd >= 0);
523
38475cac 524 r = safe_fork("(sd-netns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
cdd9988e
YW
525 if (r < 0)
526 return log_error_errno(r, "Failed to fork process (sd-netns): %m");
527 if (r == 0) {
528 if (netns_child_begin(netns_fd, ret_original_netns_fd) < 0)
529 _exit(EXIT_FAILURE);
530
531 return 0;
532 }
533
534 if (ret_original_netns_fd)
535 *ret_original_netns_fd = -EBADF;
536
537 return 1;
538}
539
1c3e5b42
YW
540static int move_wlan_interface_impl(sd_netlink **genl, int netns_fd, sd_device *dev) {
541 _cleanup_(sd_netlink_unrefp) sd_netlink *our_genl = NULL;
542 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
543 int r;
544
545 assert(netns_fd >= 0);
546 assert(dev);
547
548 if (!genl)
549 genl = &our_genl;
550 if (!*genl) {
551 r = sd_genl_socket_open(genl);
552 if (r < 0)
553 return log_error_errno(r, "Failed to connect to generic netlink: %m");
554 }
555
556 r = sd_genl_message_new(*genl, NL80211_GENL_NAME, NL80211_CMD_SET_WIPHY_NETNS, &m);
557 if (r < 0)
558 return log_device_error_errno(dev, r, "Failed to allocate netlink message: %m");
559
560 uint32_t phy_index;
561 r = device_get_sysattr_u32(dev, "phy80211/index", &phy_index);
562 if (r < 0)
563 return log_device_error_errno(dev, r, "Failed to get phy index: %m");
564
565 r = sd_netlink_message_append_u32(m, NL80211_ATTR_WIPHY, phy_index);
566 if (r < 0)
567 return log_device_error_errno(dev, r, "Failed to append phy index to netlink message: %m");
568
569 r = sd_netlink_message_append_u32(m, NL80211_ATTR_NETNS_FD, netns_fd);
570 if (r < 0)
571 return log_device_error_errno(dev, r, "Failed to append namespace fd to netlink message: %m");
572
573 r = sd_netlink_call(*genl, m, 0, NULL);
574 if (r < 0)
575 return log_device_error_errno(dev, r, "Failed to move interface to namespace: %m");
576
577 return 0;
578}
579
580static int move_wlan_interface_one(
581 sd_netlink **rtnl,
582 sd_netlink **genl,
583 int *temp_netns_fd,
584 int netns_fd,
585 sd_device *dev,
586 const char *name) {
587
588 int r;
589
590 assert(rtnl);
591 assert(genl);
592 assert(temp_netns_fd);
593 assert(netns_fd >= 0);
594 assert(dev);
1c3e5b42 595
a342d9e0 596 if (!name)
1c3e5b42
YW
597 return move_wlan_interface_impl(genl, netns_fd, dev);
598
599 /* The command NL80211_CMD_SET_WIPHY_NETNS takes phy instead of network interface, and does not take
600 * an interface name in the passed network namespace. Hence, we need to move the phy and interface to
601 * a temporary network namespace, rename the interface in it, and move them to the requested netns. */
602
603 if (*temp_netns_fd < 0) {
604 r = netns_acquire();
605 if (r < 0)
606 return log_error_errno(r, "Failed to acquire new network namespace: %m");
607 *temp_netns_fd = r;
608 }
609
610 r = move_wlan_interface_impl(genl, *temp_netns_fd, dev);
611 if (r < 0)
612 return r;
613
614 const char *sysname;
615 r = sd_device_get_sysname(dev, &sysname);
616 if (r < 0)
617 return log_device_error_errno(dev, r, "Failed to get interface name: %m");
618
619 r = netns_fork_and_wait(*temp_netns_fd, NULL);
620 if (r < 0)
621 return log_error_errno(r, "Failed to fork process (nspawn-rename-wlan): %m");
622 if (r == 0) {
623 _cleanup_(sd_device_unrefp) sd_device *temp_dev = NULL;
624
625 r = rtnl_rename_link(NULL, sysname, name);
626 if (r < 0) {
627 log_error_errno(r, "Failed to rename network interface '%s' to '%s': %m", sysname, name);
628 goto finalize;
629 }
630
631 r = sd_device_new_from_ifname(&temp_dev, name);
632 if (r < 0) {
633 log_error_errno(r, "Failed to acquire device '%s': %m", name);
634 goto finalize;
635 }
636
637 r = move_wlan_interface_impl(NULL, netns_fd, temp_dev);
638
639 finalize:
640 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
641 }
642
643 return 0;
644}
645
38475cac
YW
646static int move_network_interface_one(sd_netlink **rtnl, int netns_fd, sd_device *dev, const char *name) {
647 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
9a2a5625
LP
648 int r;
649
38475cac
YW
650 assert(rtnl);
651 assert(netns_fd >= 0);
652 assert(dev);
9a2a5625 653
38475cac
YW
654 if (!*rtnl) {
655 r = sd_netlink_open(rtnl);
656 if (r < 0)
657 return log_error_errno(r, "Failed to connect to rtnetlink: %m");
658 }
659
660 int ifindex;
661 r = sd_device_get_ifindex(dev, &ifindex);
9a2a5625 662 if (r < 0)
38475cac
YW
663 return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
664
665 r = sd_rtnl_message_new_link(*rtnl, &m, RTM_SETLINK, ifindex);
666 if (r < 0)
667 return log_device_error_errno(dev, r, "Failed to allocate netlink message: %m");
9a2a5625 668
38475cac
YW
669 r = sd_netlink_message_append_u32(m, IFLA_NET_NS_FD, netns_fd);
670 if (r < 0)
671 return log_device_error_errno(dev, r, "Failed to append namespace fd to netlink message: %m");
9a2a5625 672
a342d9e0 673 if (name) {
38475cac 674 r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
9a2a5625 675 if (r < 0)
38475cac
YW
676 return log_device_error_errno(dev, r, "Failed to add netlink interface name: %m");
677 }
9a2a5625 678
38475cac
YW
679 r = sd_netlink_call(*rtnl, m, 0, NULL);
680 if (r < 0)
681 return log_device_error_errno(dev, r, "Failed to move interface to namespace: %m");
682
683 return 0;
684}
685
686int move_network_interfaces(int netns_fd, char **iface_pairs) {
1c3e5b42
YW
687 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL, *genl = NULL;
688 _cleanup_close_ int temp_netns_fd = -EBADF;
38475cac
YW
689 int r;
690
691 assert(netns_fd >= 0);
692
693 if (strv_isempty(iface_pairs))
694 return 0;
9a2a5625 695
38475cac
YW
696 STRV_FOREACH_PAIR(from, to, iface_pairs) {
697 _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
a342d9e0
YW
698 const char *name;
699
700 name = streq(*from, *to) ? NULL : *to;
2f091b1b 701
38475cac 702 r = sd_device_new_from_ifname(&dev, *from);
9a2a5625 703 if (r < 0)
38475cac
YW
704 return log_error_errno(r, "Unknown interface name %s: %m", *from);
705
1c3e5b42 706 if (device_is_devtype(dev, "wlan"))
a342d9e0 707 r = move_wlan_interface_one(&rtnl, &genl, &temp_netns_fd, netns_fd, dev, name);
1c3e5b42 708 else
a342d9e0 709 r = move_network_interface_one(&rtnl, netns_fd, dev, name);
38475cac
YW
710 if (r < 0)
711 return r;
9a2a5625
LP
712 }
713
714 return 0;
715}
716
cdd9988e
YW
717int move_back_network_interfaces(int child_netns_fd, char **interface_pairs) {
718 _cleanup_close_ int parent_netns_fd = -EBADF;
719 int r;
720
721 assert(child_netns_fd >= 0);
722
723 if (strv_isempty(interface_pairs))
724 return 0;
725
726 r = netns_fork_and_wait(child_netns_fd, &parent_netns_fd);
727 if (r < 0)
728 return r;
729 if (r == 0) {
730 /* Reverse network interfaces pair list so that interfaces get their initial name back.
731 * This is about ensuring interfaces get their old name back when being moved back. */
732 interface_pairs = strv_reverse(interface_pairs);
733
734 r = move_network_interfaces(parent_netns_fd, interface_pairs);
735 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
736 }
737
738 return 0;
739}
740
2f091b1b 741int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
4afd3348 742 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
9a2a5625 743 unsigned idx = 0;
9a2a5625
LP
744 int r;
745
2f091b1b 746 if (strv_isempty(iface_pairs))
9a2a5625
LP
747 return 0;
748
749 r = sd_netlink_open(&rtnl);
750 if (r < 0)
751 return log_error_errno(r, "Failed to connect to netlink: %m");
752
2f091b1b 753 STRV_FOREACH_PAIR(i, b, iface_pairs) {
4afd3348 754 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
2f091b1b
TM
755 _cleanup_free_ char *n = NULL;
756 int shortened, ifi;
9a2a5625 757 struct ether_addr mac;
9a2a5625 758
f6e49154 759 ifi = rtnl_resolve_interface_or_warn(&rtnl, *i);
9a2a5625
LP
760 if (ifi < 0)
761 return ifi;
762
c50e7dca 763 r = net_generate_mac(machine_name, &mac, MACVLAN_HASH_KEY, idx++);
9a2a5625
LP
764 if (r < 0)
765 return log_error_errno(r, "Failed to create MACVLAN MAC address: %m");
766
767 r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
768 if (r < 0)
769 return log_error_errno(r, "Failed to allocate netlink message: %m");
770
771 r = sd_netlink_message_append_u32(m, IFLA_LINK, ifi);
772 if (r < 0)
773 return log_error_errno(r, "Failed to add netlink interface index: %m");
774
2f091b1b 775 n = strdup(*b);
9a2a5625
LP
776 if (!n)
777 return log_oom();
778
c50e7dca 779 shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
9a2a5625
LP
780
781 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
782 if (r < 0)
783 return log_error_errno(r, "Failed to add netlink interface name: %m");
784
785 r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, &mac);
786 if (r < 0)
787 return log_error_errno(r, "Failed to add netlink MAC address: %m");
788
789 r = sd_netlink_message_append_u32(m, IFLA_NET_NS_PID, pid);
790 if (r < 0)
791 return log_error_errno(r, "Failed to add netlink namespace field: %m");
792
793 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
794 if (r < 0)
795 return log_error_errno(r, "Failed to open netlink container: %m");
796
797 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "macvlan");
798 if (r < 0)
799 return log_error_errno(r, "Failed to open netlink container: %m");
800
801 r = sd_netlink_message_append_u32(m, IFLA_MACVLAN_MODE, MACVLAN_MODE_BRIDGE);
802 if (r < 0)
803 return log_error_errno(r, "Failed to append macvlan mode: %m");
804
805 r = sd_netlink_message_close_container(m);
806 if (r < 0)
807 return log_error_errno(r, "Failed to close netlink container: %m");
808
809 r = sd_netlink_message_close_container(m);
810 if (r < 0)
811 return log_error_errno(r, "Failed to close netlink container: %m");
812
813 r = sd_netlink_call(rtnl, m, 0, NULL);
814 if (r < 0)
815 return log_error_errno(r, "Failed to add new macvlan interfaces: %m");
6b50cb5c 816
2f091b1b
TM
817 if (shortened > 0)
818 (void) set_alternative_ifname(rtnl, n, *b);
9a2a5625
LP
819 }
820
821 return 0;
822}
823
2f091b1b 824int setup_ipvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
4afd3348 825 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
9a2a5625
LP
826 int r;
827
2f091b1b 828 if (strv_isempty(iface_pairs))
9a2a5625
LP
829 return 0;
830
831 r = sd_netlink_open(&rtnl);
832 if (r < 0)
833 return log_error_errno(r, "Failed to connect to netlink: %m");
834
2f091b1b 835 STRV_FOREACH_PAIR(i, b, iface_pairs) {
4afd3348 836 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
2f091b1b
TM
837 _cleanup_free_ char *n = NULL;
838 int shortened, ifi ;
9a2a5625 839
f6e49154 840 ifi = rtnl_resolve_interface_or_warn(&rtnl, *i);
9a2a5625
LP
841 if (ifi < 0)
842 return ifi;
843
844 r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0);
845 if (r < 0)
846 return log_error_errno(r, "Failed to allocate netlink message: %m");
847
848 r = sd_netlink_message_append_u32(m, IFLA_LINK, ifi);
849 if (r < 0)
850 return log_error_errno(r, "Failed to add netlink interface index: %m");
851
2f091b1b 852 n = strdup(*b);
9a2a5625
LP
853 if (!n)
854 return log_oom();
855
c50e7dca 856 shortened = net_shorten_ifname(n, /* check_naming_scheme= */ true);
9a2a5625
LP
857
858 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
859 if (r < 0)
860 return log_error_errno(r, "Failed to add netlink interface name: %m");
861
862 r = sd_netlink_message_append_u32(m, IFLA_NET_NS_PID, pid);
863 if (r < 0)
864 return log_error_errno(r, "Failed to add netlink namespace field: %m");
865
866 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
867 if (r < 0)
868 return log_error_errno(r, "Failed to open netlink container: %m");
869
870 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "ipvlan");
871 if (r < 0)
872 return log_error_errno(r, "Failed to open netlink container: %m");
873
874 r = sd_netlink_message_append_u16(m, IFLA_IPVLAN_MODE, IPVLAN_MODE_L2);
875 if (r < 0)
876 return log_error_errno(r, "Failed to add ipvlan mode: %m");
877
878 r = sd_netlink_message_close_container(m);
879 if (r < 0)
880 return log_error_errno(r, "Failed to close netlink container: %m");
881
882 r = sd_netlink_message_close_container(m);
883 if (r < 0)
884 return log_error_errno(r, "Failed to close netlink container: %m");
885
886 r = sd_netlink_call(rtnl, m, 0, NULL);
887 if (r < 0)
888 return log_error_errno(r, "Failed to add new ipvlan interfaces: %m");
6b50cb5c 889
2f091b1b
TM
890 if (shortened > 0)
891 (void) set_alternative_ifname(rtnl, n, *b);
9a2a5625
LP
892 }
893
894 return 0;
895}
f6d6bad1
LP
896
897int veth_extra_parse(char ***l, const char *p) {
898 _cleanup_free_ char *a = NULL, *b = NULL;
899 int r;
900
901 r = extract_first_word(&p, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
902 if (r < 0)
903 return r;
ef76dff2 904 if (r == 0 || !ifname_valid(a))
f6d6bad1
LP
905 return -EINVAL;
906
907 r = extract_first_word(&p, &b, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
908 if (r < 0)
909 return r;
ef76dff2 910 if (r == 0 || !ifname_valid(b)) {
a73e5eb9
DT
911 r = free_and_strdup(&b, a);
912 if (r < 0)
913 return r;
f6d6bad1
LP
914 }
915
916 if (p)
917 return -EINVAL;
918
919 r = strv_push_pair(l, a, b);
920 if (r < 0)
921 return -ENOMEM;
922
923 a = b = NULL;
924 return 0;
925}
ef3b2aa7 926
ef3b2aa7
LP
927int remove_veth_links(const char *primary, char **pairs) {
928 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
ef3b2aa7
LP
929 int r;
930
931 /* In some cases the kernel might pin the veth links between host and container even after the namespace
932 * died. Hence, let's better remove them explicitly too. */
933
934 if (isempty(primary) && strv_isempty(pairs))
935 return 0;
936
937 r = sd_netlink_open(&rtnl);
938 if (r < 0)
939 return log_error_errno(r, "Failed to connect to netlink: %m");
940
22b28dfd 941 remove_one_link(rtnl, primary);
ef3b2aa7
LP
942
943 STRV_FOREACH_PAIR(a, b, pairs)
22b28dfd 944 remove_one_link(rtnl, *a);
ef3b2aa7
LP
945
946 return 0;
947}
2f091b1b
TM
948
949static int network_iface_pair_parse(const char* iftype, char ***l, const char *p, const char* ifprefix) {
2f091b1b
TM
950 int r;
951
8f4d843a
FS
952 for (;;) {
953 _cleanup_free_ char *word = NULL, *a = NULL, *b = NULL;
954 const char *interface;
2f091b1b 955
8f4d843a
FS
956 r = extract_first_word(&p, &word, NULL, 0);
957 if (r < 0)
958 return log_error_errno(r, "Failed to parse interface name: %m");
959 if (r == 0)
960 break;
2f091b1b 961
8f4d843a
FS
962 interface = word;
963 r = extract_first_word(&interface, &a, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
964 if (r < 0)
965 return log_error_errno(r, "Failed to extract first word in %s parameter: %m", iftype);
966 if (r == 0)
967 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
968 "Short read while reading %s parameter: %m", iftype);
969 if (!ifname_valid(a))
970 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
971 "%s, interface name not valid: %s", iftype, a);
972
927e20fa
YW
973 /* Here, we only check the validity of the specified second name. If it is not specified,
974 * the copied or prefixed name should be already valid, except for its length. If it is too
975 * long, then it will be shortened later. */
976 if (!isempty(interface)) {
977 if (!ifname_valid(interface))
978 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
979 "%s, interface name not valid: %s", iftype, interface);
980
8f4d843a 981 b = strdup(interface);
927e20fa
YW
982 } else if (ifprefix)
983 b = strjoin(ifprefix, a);
984 else
985 b = strdup(a);
8f4d843a
FS
986 if (!b)
987 return log_oom();
988
8f4d843a
FS
989 r = strv_consume_pair(l, TAKE_PTR(a), TAKE_PTR(b));
990 if (r < 0)
991 return log_oom();
992 }
2f091b1b 993
2f091b1b
TM
994 return 0;
995}
996
997int interface_pair_parse(char ***l, const char *p) {
998 return network_iface_pair_parse("Network interface", l, p, NULL);
999}
1000
1001int macvlan_pair_parse(char ***l, const char *p) {
1002 return network_iface_pair_parse("MACVLAN network interface", l, p, "mv-");
1003}
1004
1005int ipvlan_pair_parse(char ***l, const char *p) {
1006 return network_iface_pair_parse("IPVLAN network interface", l, p, "iv-");
1007}