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