]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/netdev/netdev.c
464f47f2cf78da81d4131ade6057a9c746c6ab3b
[thirdparty/systemd.git] / src / network / netdev / netdev.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <net/if.h>
4 #include <netinet/in.h>
5 #include <linux/if_arp.h>
6 #include <unistd.h>
7
8 #include "alloc-util.h"
9 #include "arphrd-util.h"
10 #include "bareudp.h"
11 #include "batadv.h"
12 #include "bond.h"
13 #include "bridge.h"
14 #include "conf-files.h"
15 #include "conf-parser.h"
16 #include "dummy.h"
17 #include "fd-util.h"
18 #include "fou-tunnel.h"
19 #include "geneve.h"
20 #include "ifb.h"
21 #include "ipoib.h"
22 #include "ipvlan.h"
23 #include "l2tp-tunnel.h"
24 #include "list.h"
25 #include "macsec.h"
26 #include "macvlan.h"
27 #include "netdev.h"
28 #include "netdevsim.h"
29 #include "netif-util.h"
30 #include "netlink-util.h"
31 #include "networkd-manager.h"
32 #include "networkd-queue.h"
33 #include "networkd-setlink.h"
34 #include "networkd-sriov.h"
35 #include "nlmon.h"
36 #include "path-lookup.h"
37 #include "siphash24.h"
38 #include "stat-util.h"
39 #include "string-table.h"
40 #include "string-util.h"
41 #include "strv.h"
42 #include "tunnel.h"
43 #include "tuntap.h"
44 #include "vcan.h"
45 #include "veth.h"
46 #include "vlan.h"
47 #include "vrf.h"
48 #include "vxcan.h"
49 #include "vxlan.h"
50 #include "wireguard.h"
51 #include "wlan.h"
52 #include "xfrm.h"
53
54 const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
55 [NETDEV_KIND_BAREUDP] = &bare_udp_vtable,
56 [NETDEV_KIND_BATADV] = &batadv_vtable,
57 [NETDEV_KIND_BOND] = &bond_vtable,
58 [NETDEV_KIND_BRIDGE] = &bridge_vtable,
59 [NETDEV_KIND_DUMMY] = &dummy_vtable,
60 [NETDEV_KIND_ERSPAN] = &erspan_vtable,
61 [NETDEV_KIND_FOU] = &foutnl_vtable,
62 [NETDEV_KIND_GENEVE] = &geneve_vtable,
63 [NETDEV_KIND_GRE] = &gre_vtable,
64 [NETDEV_KIND_GRETAP] = &gretap_vtable,
65 [NETDEV_KIND_IFB] = &ifb_vtable,
66 [NETDEV_KIND_IP6GRE] = &ip6gre_vtable,
67 [NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable,
68 [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
69 [NETDEV_KIND_IPIP] = &ipip_vtable,
70 [NETDEV_KIND_IPOIB] = &ipoib_vtable,
71 [NETDEV_KIND_IPVLAN] = &ipvlan_vtable,
72 [NETDEV_KIND_IPVTAP] = &ipvtap_vtable,
73 [NETDEV_KIND_L2TP] = &l2tptnl_vtable,
74 [NETDEV_KIND_MACSEC] = &macsec_vtable,
75 [NETDEV_KIND_MACVLAN] = &macvlan_vtable,
76 [NETDEV_KIND_MACVTAP] = &macvtap_vtable,
77 [NETDEV_KIND_NETDEVSIM] = &netdevsim_vtable,
78 [NETDEV_KIND_NLMON] = &nlmon_vtable,
79 [NETDEV_KIND_SIT] = &sit_vtable,
80 [NETDEV_KIND_TAP] = &tap_vtable,
81 [NETDEV_KIND_TUN] = &tun_vtable,
82 [NETDEV_KIND_VCAN] = &vcan_vtable,
83 [NETDEV_KIND_VETH] = &veth_vtable,
84 [NETDEV_KIND_VLAN] = &vlan_vtable,
85 [NETDEV_KIND_VRF] = &vrf_vtable,
86 [NETDEV_KIND_VTI6] = &vti6_vtable,
87 [NETDEV_KIND_VTI] = &vti_vtable,
88 [NETDEV_KIND_VXCAN] = &vxcan_vtable,
89 [NETDEV_KIND_VXLAN] = &vxlan_vtable,
90 [NETDEV_KIND_WIREGUARD] = &wireguard_vtable,
91 [NETDEV_KIND_WLAN] = &wlan_vtable,
92 [NETDEV_KIND_XFRM] = &xfrm_vtable,
93 };
94
95 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
96 [NETDEV_KIND_BAREUDP] = "bareudp",
97 [NETDEV_KIND_BATADV] = "batadv",
98 [NETDEV_KIND_BOND] = "bond",
99 [NETDEV_KIND_BRIDGE] = "bridge",
100 [NETDEV_KIND_DUMMY] = "dummy",
101 [NETDEV_KIND_ERSPAN] = "erspan",
102 [NETDEV_KIND_FOU] = "fou",
103 [NETDEV_KIND_GENEVE] = "geneve",
104 [NETDEV_KIND_GRE] = "gre",
105 [NETDEV_KIND_GRETAP] = "gretap",
106 [NETDEV_KIND_IFB] = "ifb",
107 [NETDEV_KIND_IP6GRE] = "ip6gre",
108 [NETDEV_KIND_IP6GRETAP] = "ip6gretap",
109 [NETDEV_KIND_IP6TNL] = "ip6tnl",
110 [NETDEV_KIND_IPIP] = "ipip",
111 [NETDEV_KIND_IPOIB] = "ipoib",
112 [NETDEV_KIND_IPVLAN] = "ipvlan",
113 [NETDEV_KIND_IPVTAP] = "ipvtap",
114 [NETDEV_KIND_L2TP] = "l2tp",
115 [NETDEV_KIND_MACSEC] = "macsec",
116 [NETDEV_KIND_MACVLAN] = "macvlan",
117 [NETDEV_KIND_MACVTAP] = "macvtap",
118 [NETDEV_KIND_NETDEVSIM] = "netdevsim",
119 [NETDEV_KIND_NLMON] = "nlmon",
120 [NETDEV_KIND_SIT] = "sit",
121 [NETDEV_KIND_TAP] = "tap",
122 [NETDEV_KIND_TUN] = "tun",
123 [NETDEV_KIND_VCAN] = "vcan",
124 [NETDEV_KIND_VETH] = "veth",
125 [NETDEV_KIND_VLAN] = "vlan",
126 [NETDEV_KIND_VRF] = "vrf",
127 [NETDEV_KIND_VTI6] = "vti6",
128 [NETDEV_KIND_VTI] = "vti",
129 [NETDEV_KIND_VXCAN] = "vxcan",
130 [NETDEV_KIND_VXLAN] = "vxlan",
131 [NETDEV_KIND_WIREGUARD] = "wireguard",
132 [NETDEV_KIND_WLAN] = "wlan",
133 [NETDEV_KIND_XFRM] = "xfrm",
134 };
135
136 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
137
138 bool netdev_is_managed(NetDev *netdev) {
139 if (!netdev || !netdev->manager || !netdev->ifname)
140 return false;
141
142 return hashmap_get(netdev->manager->netdevs, netdev->ifname) == netdev;
143 }
144
145 static bool netdev_is_stacked_and_independent(NetDev *netdev) {
146 assert(netdev);
147
148 if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
149 return false;
150
151 switch (netdev->kind) {
152 case NETDEV_KIND_ERSPAN:
153 return ERSPAN(netdev)->independent;
154 case NETDEV_KIND_GRE:
155 return GRE(netdev)->independent;
156 case NETDEV_KIND_GRETAP:
157 return GRETAP(netdev)->independent;
158 case NETDEV_KIND_IP6GRE:
159 return IP6GRE(netdev)->independent;
160 case NETDEV_KIND_IP6GRETAP:
161 return IP6GRETAP(netdev)->independent;
162 case NETDEV_KIND_IP6TNL:
163 return IP6TNL(netdev)->independent;
164 case NETDEV_KIND_IPIP:
165 return IPIP(netdev)->independent;
166 case NETDEV_KIND_SIT:
167 return SIT(netdev)->independent;
168 case NETDEV_KIND_VTI:
169 return VTI(netdev)->independent;
170 case NETDEV_KIND_VTI6:
171 return VTI6(netdev)->independent;
172 case NETDEV_KIND_VXLAN:
173 return VXLAN(netdev)->independent;
174 case NETDEV_KIND_XFRM:
175 return XFRM(netdev)->independent;
176 default:
177 return false;
178 }
179 }
180
181 static bool netdev_is_stacked(NetDev *netdev) {
182 assert(netdev);
183
184 if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
185 return false;
186
187 if (netdev_is_stacked_and_independent(netdev))
188 return false;
189
190 return true;
191 }
192
193 static void netdev_detach_from_manager(NetDev *netdev) {
194 if (netdev->ifname && netdev->manager)
195 hashmap_remove(netdev->manager->netdevs, netdev->ifname);
196 }
197
198 static NetDev *netdev_free(NetDev *netdev) {
199 assert(netdev);
200
201 netdev_detach_from_manager(netdev);
202
203 free(netdev->filename);
204
205 free(netdev->description);
206 free(netdev->ifname);
207 condition_free_list(netdev->conditions);
208
209 /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
210 * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
211 * allocation, with no room for per-kind fields), and once to read the kind's properties (with a full,
212 * comprehensive NetDev structure allocation with enough space for whatever the specific kind needs). Now, in
213 * the first case we shouldn't try to destruct the per-kind NetDev fields on destruction, in the second case we
214 * should. We use the state field to discern the two cases: it's _NETDEV_STATE_INVALID on the first "raw"
215 * call. */
216 if (netdev->state != _NETDEV_STATE_INVALID &&
217 NETDEV_VTABLE(netdev) &&
218 NETDEV_VTABLE(netdev)->done)
219 NETDEV_VTABLE(netdev)->done(netdev);
220
221 return mfree(netdev);
222 }
223
224 DEFINE_TRIVIAL_REF_UNREF_FUNC(NetDev, netdev, netdev_free);
225
226 void netdev_drop(NetDev *netdev) {
227 if (!netdev)
228 return;
229
230 if (netdev_is_stacked(netdev)) {
231 /* The netdev may be removed due to the underlying device removal, and the device may
232 * be re-added later. */
233 netdev->state = NETDEV_STATE_LOADING;
234 netdev->ifindex = 0;
235
236 log_netdev_debug(netdev, "netdev removed");
237 return;
238 }
239
240 netdev->state = NETDEV_STATE_LINGER;
241
242 log_netdev_debug(netdev, "netdev removed");
243
244 netdev_detach_from_manager(netdev);
245 netdev_unref(netdev);
246 return;
247 }
248
249 int netdev_get(Manager *manager, const char *name, NetDev **ret) {
250 NetDev *netdev;
251
252 assert(manager);
253 assert(name);
254 assert(ret);
255
256 netdev = hashmap_get(manager->netdevs, name);
257 if (!netdev)
258 return -ENOENT;
259
260 *ret = netdev;
261
262 return 0;
263 }
264
265 void netdev_enter_failed(NetDev *netdev) {
266 netdev->state = NETDEV_STATE_FAILED;
267 }
268
269 static int netdev_enter_ready(NetDev *netdev) {
270 assert(netdev);
271 assert(netdev->ifname);
272
273 if (netdev->state != NETDEV_STATE_CREATING)
274 return 0;
275
276 netdev->state = NETDEV_STATE_READY;
277
278 log_netdev_info(netdev, "netdev ready");
279
280 if (NETDEV_VTABLE(netdev)->post_create)
281 NETDEV_VTABLE(netdev)->post_create(netdev, NULL);
282
283 return 0;
284 }
285
286 /* callback for netdev's created without a backing Link */
287 static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
288 int r;
289
290 assert(netdev);
291 assert(netdev->state != _NETDEV_STATE_INVALID);
292
293 r = sd_netlink_message_get_errno(m);
294 if (r == -EEXIST)
295 log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
296 else if (r < 0) {
297 log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
298 netdev_enter_failed(netdev);
299
300 return 1;
301 }
302
303 log_netdev_debug(netdev, "Created");
304
305 return 1;
306 }
307
308 int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
309 uint16_t type;
310 const char *kind;
311 const char *received_kind;
312 const char *received_name;
313 int r, ifindex;
314
315 assert(netdev);
316 assert(message);
317
318 r = sd_netlink_message_get_type(message, &type);
319 if (r < 0)
320 return log_netdev_error_errno(netdev, r, "Could not get rtnl message type: %m");
321
322 if (type != RTM_NEWLINK)
323 return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), "Cannot set ifindex from unexpected rtnl message type.");
324
325 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
326 if (r < 0) {
327 log_netdev_error_errno(netdev, r, "Could not get ifindex: %m");
328 netdev_enter_failed(netdev);
329 return r;
330 } else if (ifindex <= 0) {
331 log_netdev_error(netdev, "Got invalid ifindex: %d", ifindex);
332 netdev_enter_failed(netdev);
333 return -EINVAL;
334 }
335
336 if (netdev->ifindex > 0) {
337 if (netdev->ifindex != ifindex) {
338 log_netdev_error(netdev, "Could not set ifindex to %d, already set to %d",
339 ifindex, netdev->ifindex);
340 netdev_enter_failed(netdev);
341 return -EEXIST;
342 } else
343 /* ifindex already set to the same for this netdev */
344 return 0;
345 }
346
347 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &received_name);
348 if (r < 0)
349 return log_netdev_error_errno(netdev, r, "Could not get IFNAME: %m");
350
351 if (!streq(netdev->ifname, received_name)) {
352 log_netdev_error(netdev, "Received newlink with wrong IFNAME %s", received_name);
353 netdev_enter_failed(netdev);
354 return -EINVAL;
355 }
356
357 if (!NETDEV_VTABLE(netdev)->skip_netdev_kind_check) {
358
359 r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
360 if (r < 0)
361 return log_netdev_error_errno(netdev, r, "Could not get LINKINFO: %m");
362
363 r = sd_netlink_message_read_string(message, IFLA_INFO_KIND, &received_kind);
364 if (r < 0)
365 return log_netdev_error_errno(netdev, r, "Could not get KIND: %m");
366
367 r = sd_netlink_message_exit_container(message);
368 if (r < 0)
369 return log_netdev_error_errno(netdev, r, "Could not exit container: %m");
370
371 if (netdev->kind == NETDEV_KIND_TAP)
372 /* the kernel does not distinguish between tun and tap */
373 kind = "tun";
374 else {
375 kind = netdev_kind_to_string(netdev->kind);
376 if (!kind) {
377 log_netdev_error(netdev, "Could not get kind");
378 netdev_enter_failed(netdev);
379 return -EINVAL;
380 }
381 }
382
383 if (!streq(kind, received_kind)) {
384 log_netdev_error(netdev, "Received newlink with wrong KIND %s, expected %s",
385 received_kind, kind);
386 netdev_enter_failed(netdev);
387 return -EINVAL;
388 }
389 }
390
391 netdev->ifindex = ifindex;
392
393 log_netdev_debug(netdev, "netdev has index %d", netdev->ifindex);
394
395 netdev_enter_ready(netdev);
396
397 return 0;
398 }
399
400 #define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
401
402 int netdev_generate_hw_addr(
403 NetDev *netdev,
404 Link *parent,
405 const char *name,
406 const struct hw_addr_data *hw_addr,
407 struct hw_addr_data *ret) {
408
409 struct hw_addr_data a = HW_ADDR_NULL;
410 bool is_static = false;
411 int r;
412
413 assert(netdev);
414 assert(name);
415 assert(hw_addr);
416 assert(ret);
417
418 if (hw_addr_equal(hw_addr, &HW_ADDR_NONE)) {
419 *ret = HW_ADDR_NULL;
420 return 0;
421 }
422
423 if (hw_addr->length == 0) {
424 uint64_t result;
425
426 /* HardwareAddress= is not specified. */
427
428 if (!NETDEV_VTABLE(netdev)->generate_mac)
429 goto finalize;
430
431 if (!IN_SET(NETDEV_VTABLE(netdev)->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
432 goto finalize;
433
434 r = net_get_unique_predictable_data_from_name(name, &HASH_KEY, &result);
435 if (r < 0) {
436 log_netdev_warning_errno(netdev, r,
437 "Failed to generate persistent MAC address, ignoring: %m");
438 goto finalize;
439 }
440
441 a.length = arphrd_to_hw_addr_len(NETDEV_VTABLE(netdev)->iftype);
442
443 switch (NETDEV_VTABLE(netdev)->iftype) {
444 case ARPHRD_ETHER:
445 assert(a.length <= sizeof(result));
446 memcpy(a.bytes, &result, a.length);
447
448 if (ether_addr_is_null(&a.ether) || ether_addr_is_broadcast(&a.ether)) {
449 log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
450 "Failed to generate persistent MAC address, ignoring: %m");
451 a = HW_ADDR_NULL;
452 goto finalize;
453 }
454
455 break;
456 case ARPHRD_INFINIBAND:
457 if (result == 0) {
458 log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
459 "Failed to generate persistent MAC address: %m");
460 goto finalize;
461 }
462
463 assert(a.length >= sizeof(result));
464 memzero(a.bytes, a.length - sizeof(result));
465 memcpy(a.bytes + a.length - sizeof(result), &result, sizeof(result));
466 break;
467 default:
468 assert_not_reached();
469 }
470
471 } else {
472 a = *hw_addr;
473 is_static = true;
474 }
475
476 r = net_verify_hardware_address(name, is_static, NETDEV_VTABLE(netdev)->iftype,
477 parent ? &parent->hw_addr : NULL, &a);
478 if (r < 0)
479 return r;
480
481 finalize:
482 *ret = a;
483 return 0;
484 }
485
486 static int netdev_create_message(NetDev *netdev, Link *link, sd_netlink_message *m) {
487 int r;
488
489 r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
490 if (r < 0)
491 return r;
492
493 struct hw_addr_data hw_addr;
494 r = netdev_generate_hw_addr(netdev, link, netdev->ifname, &netdev->hw_addr, &hw_addr);
495 if (r < 0)
496 return r;
497
498 if (hw_addr.length > 0) {
499 log_netdev_debug(netdev, "Using MAC address: %s", HW_ADDR_TO_STR(&hw_addr));
500 r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &hw_addr);
501 if (r < 0)
502 return r;
503 }
504
505 if (netdev->mtu != 0) {
506 r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu);
507 if (r < 0)
508 return r;
509 }
510
511 if (link) {
512 r = sd_netlink_message_append_u32(m, IFLA_LINK, link->ifindex);
513 if (r < 0)
514 return r;
515 }
516
517 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
518 if (r < 0)
519 return r;
520
521 if (NETDEV_VTABLE(netdev)->fill_message_create) {
522 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
523 if (r < 0)
524 return r;
525
526 r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
527 if (r < 0)
528 return r;
529
530 r = sd_netlink_message_close_container(m);
531 if (r < 0)
532 return r;
533 } else {
534 r = sd_netlink_message_append_string(m, IFLA_INFO_KIND, netdev_kind_to_string(netdev->kind));
535 if (r < 0)
536 return r;
537 }
538
539 r = sd_netlink_message_close_container(m);
540 if (r < 0)
541 return r;
542
543 return 0;
544 }
545
546 static int independent_netdev_create(NetDev *netdev) {
547 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
548 int r;
549
550 assert(netdev);
551
552 /* create netdev */
553 if (NETDEV_VTABLE(netdev)->create) {
554 r = NETDEV_VTABLE(netdev)->create(netdev);
555 if (r < 0)
556 return r;
557
558 log_netdev_debug(netdev, "Created");
559 return 0;
560 }
561
562 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
563 if (r < 0)
564 return r;
565
566 r = netdev_create_message(netdev, NULL, m);
567 if (r < 0)
568 return r;
569
570 r = netlink_call_async(netdev->manager->rtnl, NULL, m, netdev_create_handler,
571 netdev_destroy_callback, netdev);
572 if (r < 0)
573 return r;
574
575 netdev_ref(netdev);
576
577 netdev->state = NETDEV_STATE_CREATING;
578 log_netdev_debug(netdev, "Creating");
579 return 0;
580 }
581
582 static int stacked_netdev_create(NetDev *netdev, Link *link, Request *req) {
583 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
584 int r;
585
586 assert(netdev);
587 assert(netdev->manager);
588 assert(link);
589 assert(req);
590
591 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
592 if (r < 0)
593 return r;
594
595 r = netdev_create_message(netdev, link, m);
596 if (r < 0)
597 return r;
598
599 r = request_call_netlink_async(netdev->manager->rtnl, m, req);
600 if (r < 0)
601 return r;
602
603 netdev->state = NETDEV_STATE_CREATING;
604 log_netdev_debug(netdev, "Creating");
605 return 0;
606 }
607
608 static bool link_is_ready_to_create_stacked_netdev_one(Link *link, bool allow_unmanaged) {
609 assert(link);
610
611 if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED, LINK_STATE_UNMANAGED))
612 return false;
613
614 if (!link->network)
615 return allow_unmanaged;
616
617 if (link->set_link_messages > 0)
618 return false;
619
620 /* If stacked netdevs are created before the underlying interface being activated, then
621 * the activation policy for the netdevs are ignored. See issue #22593. */
622 if (!link->activated)
623 return false;
624
625 return true;
626 }
627
628 static bool link_is_ready_to_create_stacked_netdev(Link *link) {
629 return check_ready_for_all_sr_iov_ports(link, /* allow_unmanaged = */ false,
630 link_is_ready_to_create_stacked_netdev_one);
631 }
632
633 static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
634 assert(netdev);
635
636 if (netdev->state != NETDEV_STATE_LOADING)
637 return false;
638
639 if (link && !link_is_ready_to_create_stacked_netdev(link))
640 return false;
641
642 if (NETDEV_VTABLE(netdev)->is_ready_to_create)
643 return NETDEV_VTABLE(netdev)->is_ready_to_create(netdev, link);
644
645 return true;
646 }
647
648 static int stacked_netdev_process_request(Request *req, Link *link, void *userdata) {
649 NetDev *netdev = ASSERT_PTR(userdata);
650 int r;
651
652 assert(req);
653 assert(link);
654
655 r = netdev_is_ready_to_create(netdev, link);
656 if (r <= 0)
657 return r;
658
659 r = stacked_netdev_create(netdev, link, req);
660 if (r < 0)
661 return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
662
663 return 1;
664 }
665
666 static int create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
667 int r;
668
669 assert(m);
670 assert(link);
671
672 r = sd_netlink_message_get_errno(m);
673 if (r < 0 && r != -EEXIST) {
674 log_link_message_warning_errno(link, m, r, "Could not create stacked netdev");
675 link_enter_failed(link);
676 return 0;
677 }
678
679 if (link->create_stacked_netdev_messages == 0) {
680 link->stacked_netdevs_created = true;
681 log_link_debug(link, "Stacked netdevs created.");
682 link_check_ready(link);
683 }
684
685 return 0;
686 }
687
688 int link_request_stacked_netdev(Link *link, NetDev *netdev) {
689 int r;
690
691 assert(link);
692 assert(netdev);
693
694 if (!netdev_is_stacked(netdev))
695 return -EINVAL;
696
697 if (!IN_SET(netdev->state, NETDEV_STATE_LOADING, NETDEV_STATE_FAILED) || netdev->ifindex > 0)
698 return 0; /* Already created. */
699
700 link->stacked_netdevs_created = false;
701 r = link_queue_request_full(link, REQUEST_TYPE_NETDEV_STACKED,
702 netdev_ref(netdev), (mfree_func_t) netdev_unref,
703 trivial_hash_func, trivial_compare_func,
704 stacked_netdev_process_request,
705 &link->create_stacked_netdev_messages,
706 create_stacked_netdev_handler, NULL);
707 if (r < 0)
708 return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m",
709 netdev->ifname);
710
711 log_link_debug(link, "Requested stacked netdev '%s'", netdev->ifname);
712 return 0;
713 }
714
715 static int independent_netdev_process_request(Request *req, Link *link, void *userdata) {
716 NetDev *netdev = ASSERT_PTR(userdata);
717 int r;
718
719 assert(!link);
720
721 r = netdev_is_ready_to_create(netdev, NULL);
722 if (r <= 0)
723 return r;
724
725 r = independent_netdev_create(netdev);
726 if (r < 0)
727 return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
728
729 return 1;
730 }
731
732 static int netdev_request_to_create(NetDev *netdev) {
733 int r;
734
735 assert(netdev);
736
737 if (netdev_is_stacked(netdev))
738 return 0;
739
740 r = netdev_is_ready_to_create(netdev, NULL);
741 if (r < 0)
742 return r;
743 if (r > 0) {
744 /* If the netdev has no dependency, then create it now. */
745 r = independent_netdev_create(netdev);
746 if (r < 0)
747 return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
748
749 } else {
750 /* Otherwise, wait for the dependencies being resolved. */
751 r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
752 if (r < 0)
753 return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
754 }
755
756 return 0;
757 }
758
759 int netdev_load_one(Manager *manager, const char *filename) {
760 _cleanup_(netdev_unrefp) NetDev *netdev_raw = NULL, *netdev = NULL;
761 const char *dropin_dirname;
762 int r;
763
764 assert(manager);
765 assert(filename);
766
767 r = null_or_empty_path(filename);
768 if (r < 0)
769 return log_warning_errno(r, "Failed to check if \"%s\" is empty: %m", filename);
770 if (r > 0) {
771 log_debug("Skipping empty file: %s", filename);
772 return 0;
773 }
774
775 netdev_raw = new(NetDev, 1);
776 if (!netdev_raw)
777 return log_oom();
778
779 *netdev_raw = (NetDev) {
780 .n_ref = 1,
781 .kind = _NETDEV_KIND_INVALID,
782 .state = _NETDEV_STATE_INVALID, /* an invalid state means done() of the implementation won't be called on destruction */
783 };
784
785 dropin_dirname = strjoina(basename(filename), ".d");
786 r = config_parse_many(
787 STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname,
788 NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
789 config_item_perf_lookup, network_netdev_gperf_lookup,
790 CONFIG_PARSE_WARN,
791 netdev_raw,
792 NULL,
793 NULL);
794 if (r < 0)
795 return r; /* config_parse_many() logs internally. */
796
797 /* skip out early if configuration does not match the environment */
798 if (!condition_test_list(netdev_raw->conditions, environ, NULL, NULL, NULL)) {
799 log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename);
800 return 0;
801 }
802
803 if (netdev_raw->kind == _NETDEV_KIND_INVALID)
804 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "NetDev has no Kind= configured in \"%s\", ignoring.", filename);
805
806 if (!netdev_raw->ifname)
807 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "NetDev without Name= configured in \"%s\", ignoring.", filename);
808
809 netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
810 if (!netdev)
811 return log_oom();
812
813 netdev->n_ref = 1;
814 netdev->manager = manager;
815 netdev->kind = netdev_raw->kind;
816 netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time,
817 so that done() will be called on destruction */
818
819 if (NETDEV_VTABLE(netdev)->init)
820 NETDEV_VTABLE(netdev)->init(netdev);
821
822 r = config_parse_many(
823 STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname,
824 NETDEV_VTABLE(netdev)->sections,
825 config_item_perf_lookup, network_netdev_gperf_lookup,
826 CONFIG_PARSE_WARN,
827 netdev, NULL, NULL);
828 if (r < 0)
829 return r; /* config_parse_many() logs internally. */
830
831 /* verify configuration */
832 if (NETDEV_VTABLE(netdev)->config_verify) {
833 r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
834 if (r < 0)
835 return r; /* config_verify() logs internally. */
836 }
837
838 netdev->filename = strdup(filename);
839 if (!netdev->filename)
840 return log_oom();
841
842 r = hashmap_ensure_put(&netdev->manager->netdevs, &string_hash_ops, netdev->ifname, netdev);
843 if (r == -ENOMEM)
844 return log_oom();
845 if (r == -EEXIST) {
846 NetDev *n = hashmap_get(netdev->manager->netdevs, netdev->ifname);
847
848 assert(n);
849 if (!streq(netdev->filename, n->filename))
850 log_netdev_warning_errno(netdev, r,
851 "Device was already configured by \"%s\", ignoring %s.",
852 n->filename, netdev->filename);
853
854 /* Clear ifname before netdev_free() is called. Otherwise, the NetDev object 'n' is
855 * removed from the hashmap 'manager->netdevs'. */
856 netdev->ifname = mfree(netdev->ifname);
857 return -EEXIST;
858 }
859 assert(r > 0);
860
861 log_netdev_debug(netdev, "loaded \"%s\"", netdev_kind_to_string(netdev->kind));
862
863 r = netdev_request_to_create(netdev);
864 if (r < 0)
865 return r; /* netdev_request_to_create() logs internally. */
866
867 TAKE_PTR(netdev);
868 return 0;
869 }
870
871 int netdev_load(Manager *manager, bool reload) {
872 _cleanup_strv_free_ char **files = NULL;
873 int r;
874
875 assert(manager);
876
877 if (!reload)
878 hashmap_clear_with_destructor(manager->netdevs, netdev_unref);
879
880 r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
881 if (r < 0)
882 return log_error_errno(r, "Failed to enumerate netdev files: %m");
883
884 STRV_FOREACH(f, files)
885 (void) netdev_load_one(manager, *f);
886
887 return 0;
888 }
889
890 int config_parse_netdev_kind(
891 const char *unit,
892 const char *filename,
893 unsigned line,
894 const char *section,
895 unsigned section_line,
896 const char *lvalue,
897 int ltype,
898 const char *rvalue,
899 void *data,
900 void *userdata) {
901
902 NetDevKind k, *kind = data;
903
904 assert(filename);
905 assert(rvalue);
906 assert(data);
907
908 k = netdev_kind_from_string(rvalue);
909 if (k < 0) {
910 log_syntax(unit, LOG_WARNING, filename, line, k, "Failed to parse netdev kind, ignoring assignment: %s", rvalue);
911 return 0;
912 }
913
914 if (*kind != _NETDEV_KIND_INVALID && *kind != k) {
915 log_syntax(unit, LOG_WARNING, filename, line, 0,
916 "Specified netdev kind is different from the previous value '%s', ignoring assignment: %s",
917 netdev_kind_to_string(*kind), rvalue);
918 return 0;
919 }
920
921 *kind = k;
922
923 return 0;
924 }
925
926 int config_parse_netdev_hw_addr(
927 const char *unit,
928 const char *filename,
929 unsigned line,
930 const char *section,
931 unsigned section_line,
932 const char *lvalue,
933 int ltype,
934 const char *rvalue,
935 void *data,
936 void *userdata) {
937
938 struct hw_addr_data *hw_addr = data;
939
940 assert(rvalue);
941 assert(data);
942
943 if (streq(rvalue, "none")) {
944 *hw_addr = HW_ADDR_NONE;
945 return 0;
946 }
947
948 return config_parse_hw_addr(unit, filename, line, section, section_line, lvalue, ltype, rvalue, data, userdata);
949 }