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