1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/if_arp.h>
6 #include "sd-netlink.h"
8 #include "alloc-util.h"
9 #include "arphrd-util.h"
14 #include "condition.h"
15 #include "conf-files.h"
16 #include "conf-parser.h"
18 #include "fou-tunnel.h"
25 #include "l2tp-tunnel.h"
29 #include "netif-util.h"
30 #include "netlink-util.h"
31 #include "network-util.h"
32 #include "networkd-manager.h"
33 #include "networkd-queue.h"
34 #include "networkd-sriov.h"
35 #include "networkd-state-file.h"
37 #include "path-util.h"
38 #include "stat-util.h"
39 #include "string-table.h"
40 #include "string-util.h"
50 #include "wireguard.h"
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_HSR
] = &hsr_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_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
,
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_HSR
] = "hsr",
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_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",
136 DEFINE_STRING_TABLE_LOOKUP(netdev_kind
, NetDevKind
);
138 bool netdev_is_managed(NetDev
*netdev
) {
139 if (!netdev
|| !netdev
->manager
|| !netdev
->ifname
)
142 return hashmap_get(netdev
->manager
->netdevs
, netdev
->ifname
) == netdev
;
145 static bool netdev_is_stacked_and_independent(NetDev
*netdev
) {
148 if (netdev_get_create_type(netdev
) != NETDEV_CREATE_STACKED
)
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
;
181 static bool netdev_is_stacked(NetDev
*netdev
) {
184 if (netdev_get_create_type(netdev
) != NETDEV_CREATE_STACKED
)
187 if (netdev_is_stacked_and_independent(netdev
))
193 NetDev
* netdev_detach_name(NetDev
*netdev
, const char *name
) {
196 if (!netdev
->manager
|| !name
)
197 return NULL
; /* Already detached or not attached yet. */
199 return hashmap_remove_value(netdev
->manager
->netdevs
, name
, netdev
);
202 static NetDev
* netdev_detach_impl(NetDev
*netdev
) {
205 if (netdev
->state
!= _NETDEV_STATE_INVALID
&&
206 NETDEV_VTABLE(netdev
) &&
207 NETDEV_VTABLE(netdev
)->detach
)
208 NETDEV_VTABLE(netdev
)->detach(netdev
);
210 NetDev
*n
= netdev_detach_name(netdev
, netdev
->ifname
);
212 netdev
->manager
= NULL
;
213 return n
; /* Return NULL when it is not attached yet, or already detached. */
216 void netdev_detach(NetDev
*netdev
) {
219 netdev_unref(netdev_detach_impl(netdev
));
222 static NetDev
* netdev_free(NetDev
*netdev
) {
225 netdev_detach_impl(netdev
);
227 /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
228 * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
229 * allocation, with no room for per-kind fields), and once to read the kind's properties (with a full,
230 * comprehensive NetDev structure allocation with enough space for whatever the specific kind needs). Now, in
231 * the first case we shouldn't try to destruct the per-kind NetDev fields on destruction, in the second case we
232 * should. We use the state field to discern the two cases: it's _NETDEV_STATE_INVALID on the first "raw"
234 if (netdev
->state
!= _NETDEV_STATE_INVALID
&&
235 NETDEV_VTABLE(netdev
) &&
236 NETDEV_VTABLE(netdev
)->done
)
237 NETDEV_VTABLE(netdev
)->done(netdev
);
239 condition_free_list(netdev
->conditions
);
240 free(netdev
->filename
);
241 strv_free(netdev
->dropins
);
242 hashmap_free(netdev
->stats_by_path
);
243 free(netdev
->description
);
244 free(netdev
->ifname
);
246 return mfree(netdev
);
249 DEFINE_TRIVIAL_REF_UNREF_FUNC(NetDev
, netdev
, netdev_free
);
251 void netdev_drop(NetDev
*netdev
) {
255 if (netdev_is_stacked(netdev
)) {
256 /* The netdev may be removed due to the underlying device removal, and the device may
257 * be re-added later. */
258 netdev
->state
= NETDEV_STATE_LOADING
;
261 log_netdev_debug(netdev
, "netdev removed");
265 if (NETDEV_VTABLE(netdev
) && NETDEV_VTABLE(netdev
)->drop
)
266 NETDEV_VTABLE(netdev
)->drop(netdev
);
268 netdev
->state
= NETDEV_STATE_LINGER
;
270 log_netdev_debug(netdev
, "netdev removed");
272 netdev_detach(netdev
);
275 static int netdev_attach_name_full(NetDev
*netdev
, const char *name
, Hashmap
**netdevs
) {
281 r
= hashmap_ensure_put(netdevs
, &string_hash_ops
, name
, netdev
);
285 NetDev
*n
= hashmap_get(*netdevs
, name
);
288 if (!streq(netdev
->filename
, n
->filename
))
289 log_netdev_warning_errno(netdev
, r
,
290 "Device \"%s\" was already configured by \"%s\", ignoring %s.",
291 name
, n
->filename
, netdev
->filename
);
300 int netdev_attach_name(NetDev
*netdev
, const char *name
) {
302 assert(netdev
->manager
);
304 return netdev_attach_name_full(netdev
, name
, &netdev
->manager
->netdevs
);
307 static int netdev_attach(NetDev
*netdev
) {
311 assert(netdev
->ifname
);
313 r
= netdev_attach_name(netdev
, netdev
->ifname
);
317 if (NETDEV_VTABLE(netdev
)->attach
) {
318 r
= NETDEV_VTABLE(netdev
)->attach(netdev
);
326 int netdev_get(Manager
*manager
, const char *name
, NetDev
**ret
) {
333 netdev
= hashmap_get(manager
->netdevs
, name
);
342 void link_assign_netdev(Link
*link
) {
343 _unused_
_cleanup_(netdev_unrefp
) NetDev
*old
= NULL
;
347 assert(link
->manager
);
348 assert(link
->ifname
);
350 old
= TAKE_PTR(link
->netdev
);
352 if (netdev_get(link
->manager
, link
->ifname
, &netdev
) < 0)
355 int ifindex
= NETDEV_VTABLE(netdev
)->get_ifindex
?
356 NETDEV_VTABLE(netdev
)->get_ifindex(netdev
, link
->ifname
) :
358 if (ifindex
!= link
->ifindex
)
361 if (NETDEV_VTABLE(netdev
)->iftype
!= link
->iftype
)
364 if (!NETDEV_VTABLE(netdev
)->skip_netdev_kind_check
) {
367 if (netdev
->kind
== NETDEV_KIND_TAP
)
368 kind
= "tun"; /* the kernel does not distinguish between tun and tap */
370 kind
= netdev_kind_to_string(netdev
->kind
);
372 if (!streq_ptr(kind
, link
->kind
))
376 link
->netdev
= netdev_ref(netdev
);
379 return; /* The same NetDev found. */
381 log_link_debug(link
, "Found matching .netdev file: %s", netdev
->filename
);
388 /* Previously assigned NetDev is detached from Manager? Update the state file. */
392 void netdev_enter_failed(NetDev
*netdev
) {
393 netdev
->state
= NETDEV_STATE_FAILED
;
396 int netdev_enter_ready(NetDev
*netdev
) {
398 assert(netdev
->ifname
);
400 if (!IN_SET(netdev
->state
, NETDEV_STATE_LOADING
, NETDEV_STATE_CREATING
))
403 netdev
->state
= NETDEV_STATE_READY
;
405 log_netdev_info(netdev
, "netdev ready");
407 if (NETDEV_VTABLE(netdev
)->post_create
)
408 NETDEV_VTABLE(netdev
)->post_create(netdev
, NULL
);
413 bool netdev_needs_reconfigure(NetDev
*netdev
, NetDevLocalAddressType type
) {
415 assert(type
< _NETDEV_LOCAL_ADDRESS_TYPE_MAX
);
420 return NETDEV_VTABLE(netdev
)->needs_reconfigure
&&
421 NETDEV_VTABLE(netdev
)->needs_reconfigure(netdev
, type
);
424 /* callback for netdev's created without a backing Link */
425 static int netdev_create_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, NetDev
*netdev
) {
429 assert(netdev
->state
!= _NETDEV_STATE_INVALID
);
431 r
= sd_netlink_message_get_errno(m
);
433 log_netdev_debug(netdev
, "Created.");
434 else if (r
== -EEXIST
&& netdev
->ifindex
> 0)
435 log_netdev_debug(netdev
, "Already exists.");
437 log_netdev_warning_errno(netdev
, r
, "Failed to create netdev: %m");
438 netdev_enter_failed(netdev
);
442 return netdev_enter_ready(netdev
);
445 int netdev_set_ifindex_internal(NetDev
*netdev
, int ifindex
) {
449 if (netdev
->ifindex
== ifindex
)
450 return 0; /* Already set. */
452 if (netdev
->ifindex
> 0 && netdev
->ifindex
!= ifindex
)
453 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EEXIST
),
454 "Could not set ifindex to %i, already set to %i.",
455 ifindex
, netdev
->ifindex
);
457 netdev
->ifindex
= ifindex
;
458 log_netdev_debug(netdev
, "Gained index %i.", ifindex
);
459 return 1; /* set new ifindex. */
462 static int netdev_set_ifindex_impl(NetDev
*netdev
, const char *name
, int ifindex
) {
467 if (NETDEV_VTABLE(netdev
)->set_ifindex
)
468 return NETDEV_VTABLE(netdev
)->set_ifindex(netdev
, name
, ifindex
);
470 if (!streq(netdev
->ifname
, name
))
471 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
472 "Received netlink message with unexpected interface name %s (ifindex=%i).",
475 return netdev_set_ifindex_internal(netdev
, ifindex
);
478 int netdev_set_ifindex(NetDev
*netdev
, sd_netlink_message
*message
) {
481 const char *received_kind
;
482 const char *received_name
;
483 int r
, ifindex
, family
;
488 r
= sd_netlink_message_get_type(message
, &type
);
490 return log_netdev_warning_errno(netdev
, r
, "Could not get rtnl message type: %m");
492 if (type
!= RTM_NEWLINK
)
493 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
), "Cannot set ifindex from unexpected rtnl message type.");
495 r
= sd_rtnl_message_get_family(message
, &family
);
497 return log_netdev_warning_errno(netdev
, r
, "Failed to get family from received rtnl message: %m");
499 if (family
!= AF_UNSPEC
)
500 return 0; /* IFLA_LINKINFO is only contained in the message with AF_UNSPEC. */
502 r
= sd_rtnl_message_link_get_ifindex(message
, &ifindex
);
504 return log_netdev_warning_errno(netdev
, r
, "Could not get ifindex: %m");
506 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
), "Got invalid ifindex: %d", ifindex
);
508 r
= sd_netlink_message_read_string(message
, IFLA_IFNAME
, &received_name
);
510 return log_netdev_warning_errno(netdev
, r
, "Could not get IFNAME: %m");
512 if (!NETDEV_VTABLE(netdev
)->skip_netdev_kind_check
) {
514 r
= sd_netlink_message_enter_container(message
, IFLA_LINKINFO
);
516 return log_netdev_warning_errno(netdev
, r
, "Could not get LINKINFO: %m");
518 r
= sd_netlink_message_read_string(message
, IFLA_INFO_KIND
, &received_kind
);
520 return log_netdev_warning_errno(netdev
, r
, "Could not get KIND: %m");
522 r
= sd_netlink_message_exit_container(message
);
524 return log_netdev_warning_errno(netdev
, r
, "Could not exit container: %m");
526 if (netdev
->kind
== NETDEV_KIND_TAP
)
527 /* the kernel does not distinguish between tun and tap */
530 kind
= netdev_kind_to_string(netdev
->kind
);
532 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
), "Could not get netdev kind.");
534 if (!streq(kind
, received_kind
))
535 return log_netdev_warning_errno(netdev
, SYNTHETIC_ERRNO(EINVAL
),
536 "Received newlink with wrong KIND %s, expected %s",
537 received_kind
, kind
);
540 return netdev_set_ifindex_impl(netdev
, received_name
, ifindex
);
543 #define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
545 int netdev_generate_hw_addr(
549 const struct hw_addr_data
*hw_addr
,
550 struct hw_addr_data
*ret
) {
552 struct hw_addr_data a
= HW_ADDR_NULL
;
553 bool is_static
= false;
561 if (hw_addr_equal(hw_addr
, &HW_ADDR_NONE
)) {
566 if (hw_addr
->length
== 0) {
569 /* HardwareAddress= is not specified. */
571 if (!NETDEV_VTABLE(netdev
)->generate_mac
)
574 if (!IN_SET(NETDEV_VTABLE(netdev
)->iftype
, ARPHRD_ETHER
, ARPHRD_INFINIBAND
))
577 r
= net_get_unique_predictable_data_from_name(name
, &HASH_KEY
, &result
);
579 log_netdev_warning_errno(netdev
, r
,
580 "Failed to generate persistent MAC address, ignoring: %m");
584 a
.length
= arphrd_to_hw_addr_len(NETDEV_VTABLE(netdev
)->iftype
);
586 switch (NETDEV_VTABLE(netdev
)->iftype
) {
588 assert(a
.length
<= sizeof(result
));
589 memcpy(a
.bytes
, &result
, a
.length
);
591 if (ether_addr_is_null(&a
.ether
) || ether_addr_is_broadcast(&a
.ether
)) {
592 log_netdev_warning(netdev
, "Failed to generate persistent MAC address, ignoring.");
598 case ARPHRD_INFINIBAND
:
600 log_netdev_warning(netdev
, "Failed to generate persistent MAC address.");
604 assert(a
.length
>= sizeof(result
));
605 memzero(a
.bytes
, a
.length
- sizeof(result
));
606 memcpy(a
.bytes
+ a
.length
- sizeof(result
), &result
, sizeof(result
));
609 assert_not_reached();
617 r
= net_verify_hardware_address(name
, is_static
, NETDEV_VTABLE(netdev
)->iftype
,
618 parent
? &parent
->hw_addr
: NULL
, &a
);
627 static bool netdev_can_set_mac(NetDev
*netdev
, const struct hw_addr_data
*hw_addr
) {
629 assert(netdev
->manager
);
632 if (hw_addr
->length
<= 0)
636 if (link_get_by_index(netdev
->manager
, netdev
->ifindex
, &link
) < 0)
637 return true; /* The netdev does not exist yet. We can set MAC address. */
639 if (hw_addr_equal(&link
->hw_addr
, hw_addr
))
640 return false; /* Unchanged, not necessary to set. */
642 /* Some netdevs refuse to update MAC address even if the interface is not running, e.g. ipvlan.
643 * Some other netdevs have the IFF_LIVE_ADDR_CHANGE flag and can update update MAC address even if
644 * the interface is running, e.g. dummy. For those cases, use custom checkers. */
645 if (NETDEV_VTABLE(netdev
)->can_set_mac
)
646 return NETDEV_VTABLE(netdev
)->can_set_mac(netdev
, hw_addr
);
648 /* Before ad72c4a06acc6762e84994ac2f722da7a07df34e and 0ec92a8f56ff07237dbe8af7c7a72aba7f957baf
649 * (both in v6.5), the kernel refuse to set MAC address for existing netdevs even if it is unchanged.
650 * So, by default, do not update MAC address if the it is running. See eth_prepare_mac_addr_change(),
651 * which is called by eth_mac_addr(). Note, the result of netif_running() is mapped to operstate
652 * and flags. See rtnl_fill_ifinfo() and dev_get_flags(). */
653 return link
->kernel_operstate
== IF_OPER_DOWN
&&
654 (link
->flags
& (IFF_RUNNING
| IFF_LOWER_UP
| IFF_DORMANT
)) == 0;
657 static bool netdev_can_set_mtu(NetDev
*netdev
, uint32_t mtu
) {
664 if (link_get_by_index(netdev
->manager
, netdev
->ifindex
, &link
) < 0)
665 return true; /* The netdev does not exist yet. We can set MTU. */
667 if (mtu
< link
->min_mtu
|| link
->max_mtu
< mtu
)
668 return false; /* The MTU is out of range. */
670 if (link
->mtu
== mtu
)
671 return false; /* Unchanged, not necessary to set. */
673 /* Some netdevs cannot change MTU, e.g. vxlan. Let's use the custom checkers in such cases. */
674 if (NETDEV_VTABLE(netdev
)->can_set_mtu
)
675 return NETDEV_VTABLE(netdev
)->can_set_mtu(netdev
, mtu
);
677 /* By default, allow to update the MTU. */
681 static int netdev_create_message(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
684 if (netdev
->ifindex
<= 0) {
685 /* Set interface name when it is newly created. Otherwise, the kernel older than
686 * bd039b5ea2a91ea707ee8539df26456bd5be80af (v6.2) will refuse the netlink message even if
687 * the name is unchanged. */
688 r
= sd_netlink_message_append_string(m
, IFLA_IFNAME
, netdev
->ifname
);
693 struct hw_addr_data hw_addr
;
694 r
= netdev_generate_hw_addr(netdev
, link
, netdev
->ifname
, &netdev
->hw_addr
, &hw_addr
);
698 if (netdev_can_set_mac(netdev
, &hw_addr
)) {
699 log_netdev_debug(netdev
, "Using MAC address: %s", HW_ADDR_TO_STR(&hw_addr
));
700 r
= netlink_message_append_hw_addr(m
, IFLA_ADDRESS
, &hw_addr
);
705 if (netdev_can_set_mtu(netdev
, netdev
->mtu
)) {
706 r
= sd_netlink_message_append_u32(m
, IFLA_MTU
, netdev
->mtu
);
712 r
= sd_netlink_message_append_u32(m
, IFLA_LINK
, link
->ifindex
);
717 r
= sd_netlink_message_open_container(m
, IFLA_LINKINFO
);
721 if (NETDEV_VTABLE(netdev
)->fill_message_create
) {
722 r
= sd_netlink_message_open_container_union(m
, IFLA_INFO_DATA
, netdev_kind_to_string(netdev
->kind
));
726 r
= NETDEV_VTABLE(netdev
)->fill_message_create(netdev
, link
, m
);
730 r
= sd_netlink_message_close_container(m
);
734 r
= sd_netlink_message_append_string(m
, IFLA_INFO_KIND
, netdev_kind_to_string(netdev
->kind
));
739 r
= sd_netlink_message_close_container(m
);
746 static int independent_netdev_create(NetDev
*netdev
) {
747 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
751 assert(netdev
->manager
);
754 if (NETDEV_VTABLE(netdev
)->create
) {
755 r
= NETDEV_VTABLE(netdev
)->create(netdev
);
759 log_netdev_debug(netdev
, "Created");
763 r
= sd_rtnl_message_new_link(netdev
->manager
->rtnl
, &m
, RTM_NEWLINK
, netdev
->ifindex
);
767 r
= netdev_create_message(netdev
, NULL
, m
);
771 r
= netlink_call_async(netdev
->manager
->rtnl
, NULL
, m
, netdev_create_handler
,
772 netdev_destroy_callback
, netdev
);
778 netdev
->state
= NETDEV_STATE_CREATING
;
779 log_netdev_debug(netdev
, "Creating");
783 static int stacked_netdev_create(NetDev
*netdev
, Link
*link
, Request
*req
) {
784 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
788 assert(netdev
->manager
);
792 r
= sd_rtnl_message_new_link(netdev
->manager
->rtnl
, &m
, RTM_NEWLINK
, netdev
->ifindex
);
796 r
= netdev_create_message(netdev
, link
, m
);
800 r
= request_call_netlink_async(netdev
->manager
->rtnl
, m
, req
);
804 netdev
->state
= NETDEV_STATE_CREATING
;
805 log_netdev_debug(netdev
, "Creating");
809 static bool link_is_ready_to_create_stacked_netdev_one(Link
*link
, bool allow_unmanaged
) {
812 if (!IN_SET(link
->state
, LINK_STATE_CONFIGURING
, LINK_STATE_CONFIGURED
, LINK_STATE_UNMANAGED
))
816 return allow_unmanaged
;
818 if (link
->set_link_messages
> 0)
821 /* If stacked netdevs are created before the underlying interface being activated, then
822 * the activation policy for the netdevs are ignored. See issue #22593. */
823 if (!link
->activated
)
829 static bool link_is_ready_to_create_stacked_netdev(Link
*link
) {
830 return check_ready_for_all_sr_iov_ports(link
, /* allow_unmanaged = */ false,
831 link_is_ready_to_create_stacked_netdev_one
);
834 static int netdev_is_ready_to_create(NetDev
*netdev
, Link
*link
) {
837 if (link
&& !link_is_ready_to_create_stacked_netdev(link
))
840 if (NETDEV_VTABLE(netdev
)->is_ready_to_create
)
841 return NETDEV_VTABLE(netdev
)->is_ready_to_create(netdev
, link
);
846 static int stacked_netdev_process_request(Request
*req
, Link
*link
, void *userdata
) {
847 NetDev
*netdev
= ASSERT_PTR(userdata
);
853 if (!netdev_is_managed(netdev
))
854 goto cancelled
; /* Already detached, due to e.g. reloading .netdev files, cancelling the request. */
856 if (NETDEV_VTABLE(netdev
)->keep_existing
&& netdev
->ifindex
> 0) {
857 /* Already exists, and the netdev does not support updating, entering the ready state. */
858 r
= netdev_enter_ready(netdev
);
865 r
= netdev_is_ready_to_create(netdev
, link
);
869 r
= stacked_netdev_create(netdev
, link
, req
);
871 return log_netdev_warning_errno(netdev
, r
, "Failed to create netdev: %m");
876 assert_se(TAKE_PTR(req
->counter
) == &link
->create_stacked_netdev_messages
);
877 link
->create_stacked_netdev_messages
--;
879 if (link
->create_stacked_netdev_messages
== 0) {
880 link
->stacked_netdevs_created
= true;
881 log_link_debug(link
, "Stacked netdevs created.");
882 link_check_ready(link
);
888 static int create_stacked_netdev_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Request
*req
, Link
*link
, void *userdata
) {
889 NetDev
*netdev
= ASSERT_PTR(userdata
);
895 r
= sd_netlink_message_get_errno(m
);
897 log_netdev_debug(netdev
, "Created.");
898 else if (r
== -EEXIST
&& netdev
->ifindex
> 0)
899 log_netdev_debug(netdev
, "Already exists.");
901 log_netdev_warning_errno(netdev
, r
, "Failed to create netdev: %m");
902 netdev_enter_failed(netdev
);
903 link_enter_failed(link
);
907 (void) netdev_enter_ready(netdev
);
909 if (link
->create_stacked_netdev_messages
== 0) {
910 link
->stacked_netdevs_created
= true;
911 log_link_debug(link
, "Stacked netdevs created.");
912 link_check_ready(link
);
918 int link_request_stacked_netdev(Link
*link
, NetDev
*netdev
) {
924 if (!netdev_is_stacked(netdev
))
927 if (!netdev_is_managed(netdev
))
928 return 0; /* Already detached, due to e.g. reloading .netdev files. */
930 link
->stacked_netdevs_created
= false;
931 r
= link_queue_request_full(link
, REQUEST_TYPE_NETDEV_STACKED
,
932 netdev
, (mfree_func_t
) netdev_unref
,
933 trivial_hash_func
, trivial_compare_func
,
934 stacked_netdev_process_request
,
935 &link
->create_stacked_netdev_messages
,
936 create_stacked_netdev_handler
, NULL
);
938 return log_link_error_errno(link
, r
, "Failed to request stacked netdev '%s': %m",
944 log_link_debug(link
, "Requested stacked netdev '%s'", netdev
->ifname
);
948 static int independent_netdev_process_request(Request
*req
, Link
*link
, void *userdata
) {
949 NetDev
*netdev
= ASSERT_PTR(userdata
);
954 if (!netdev_is_managed(netdev
))
955 return 1; /* Already detached, due to e.g. reloading .netdev files, cancelling the request. */
957 if (NETDEV_VTABLE(netdev
)->keep_existing
&& netdev
->ifindex
> 0) {
958 /* Already exists, and the netdev does not support updating, entering the ready state. */
959 r
= netdev_enter_ready(netdev
);
963 return 1; /* Skip this request. */
966 r
= netdev_is_ready_to_create(netdev
, NULL
);
970 r
= independent_netdev_create(netdev
);
972 return log_netdev_warning_errno(netdev
, r
, "Failed to create netdev: %m");
977 static int netdev_request_to_create(NetDev
*netdev
) {
981 assert(netdev
->manager
);
983 if (netdev
->manager
->test_mode
)
986 if (netdev_is_stacked(netdev
))
989 if (!netdev_is_managed(netdev
))
990 return 0; /* Already detached, due to e.g. reloading .netdev files. */
992 if (netdev
->state
!= NETDEV_STATE_LOADING
)
993 return 0; /* Already configured (at least tried previously). Not necessary to reconfigure. */
995 r
= netdev_queue_request(netdev
, independent_netdev_process_request
, NULL
);
997 return log_netdev_warning_errno(netdev
, r
, "Failed to request to create netdev: %m");
1002 int netdev_load_one(Manager
*manager
, const char *filename
, NetDev
**ret
) {
1003 _cleanup_(netdev_unrefp
) NetDev
*netdev_raw
= NULL
, *netdev
= NULL
;
1004 _cleanup_free_
char *file_basename
= NULL
;
1005 const char *dropin_dirname
;
1012 r
= null_or_empty_path(filename
);
1014 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
1016 return log_debug_errno(SYNTHETIC_ERRNO(ENOENT
), "Skipping empty file: %s", filename
);
1018 netdev_raw
= new(NetDev
, 1);
1022 *netdev_raw
= (NetDev
) {
1024 .kind
= _NETDEV_KIND_INVALID
,
1025 .state
= _NETDEV_STATE_INVALID
, /* an invalid state means done() of the implementation won't be called on destruction */
1028 r
= path_extract_filename(filename
, &file_basename
);
1030 return log_warning_errno(r
, "Failed to extract file name of '%s': %m", filename
);
1032 dropin_dirname
= strjoina(file_basename
, ".d");
1033 r
= config_parse_many(
1034 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
1035 NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS
,
1036 config_item_perf_lookup
, network_netdev_gperf_lookup
,
1042 return r
; /* config_parse_many() logs internally. */
1044 /* skip out early if configuration does not match the environment */
1045 if (!condition_test_list(netdev_raw
->conditions
, environ
, NULL
, NULL
, NULL
))
1046 return log_debug_errno(SYNTHETIC_ERRNO(ESTALE
), "%s: Conditions in the file do not match the system environment, skipping.", filename
);
1048 if (netdev_raw
->kind
== _NETDEV_KIND_INVALID
)
1049 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "NetDev has no Kind= configured in \"%s\", ignoring.", filename
);
1051 if (!netdev_raw
->ifname
)
1052 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "NetDev without Name= configured in \"%s\", ignoring.", filename
);
1054 netdev
= malloc0(NETDEV_VTABLE(netdev_raw
)->object_size
);
1059 netdev
->manager
= manager
;
1060 netdev
->kind
= netdev_raw
->kind
;
1061 netdev
->state
= NETDEV_STATE_LOADING
; /* we initialize the state here for the first time,
1062 so that done() will be called on destruction */
1064 if (NETDEV_VTABLE(netdev
)->init
)
1065 NETDEV_VTABLE(netdev
)->init(netdev
);
1067 r
= config_parse_many(
1068 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
1069 NETDEV_VTABLE(netdev
)->sections
,
1070 config_item_perf_lookup
, network_netdev_gperf_lookup
,
1073 &netdev
->stats_by_path
,
1076 return r
; /* config_parse_many() logs internally. */
1078 /* verify configuration */
1079 if (NETDEV_VTABLE(netdev
)->config_verify
) {
1080 r
= NETDEV_VTABLE(netdev
)->config_verify(netdev
, filename
);
1082 return r
; /* config_verify() logs internally. */
1085 netdev
->filename
= strdup(filename
);
1086 if (!netdev
->filename
)
1089 log_syntax(/* unit = */ NULL
, LOG_DEBUG
, filename
, /* config_line = */ 0, /* error = */ 0, "Successfully loaded.");
1091 *ret
= TAKE_PTR(netdev
);
1095 int netdev_load(Manager
*manager
) {
1096 _cleanup_strv_free_
char **files
= NULL
;
1101 r
= conf_files_list_strv(&files
, ".netdev", NULL
, 0, NETWORK_DIRS
);
1103 return log_error_errno(r
, "Failed to enumerate netdev files: %m");
1105 STRV_FOREACH(f
, files
) {
1106 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
1108 if (netdev_load_one(manager
, *f
, &netdev
) < 0)
1111 if (netdev_attach(netdev
) < 0)
1114 if (netdev_request_to_create(netdev
) < 0)
1123 int netdev_reload(Manager
*manager
) {
1124 _cleanup_hashmap_free_ Hashmap
*new_netdevs
= NULL
;
1125 _cleanup_strv_free_
char **files
= NULL
;
1130 r
= conf_files_list_strv(&files
, ".netdev", NULL
, 0, NETWORK_DIRS
);
1132 return log_error_errno(r
, "Failed to enumerate netdev files: %m");
1134 STRV_FOREACH(f
, files
) {
1135 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
1138 if (netdev_load_one(manager
, *f
, &netdev
) < 0)
1141 if (netdev_get(manager
, netdev
->ifname
, &old
) < 0) {
1142 log_netdev_debug(netdev
, "Found new .netdev file: %s", netdev
->filename
);
1144 if (netdev_attach_name_full(netdev
, netdev
->ifname
, &new_netdevs
) >= 0)
1150 if (!stats_by_path_equal(netdev
->stats_by_path
, old
->stats_by_path
)) {
1151 log_netdev_debug(netdev
, "Found updated .netdev file: %s", netdev
->filename
);
1154 netdev
->ifindex
= old
->ifindex
;
1156 if (netdev_attach_name_full(netdev
, netdev
->ifname
, &new_netdevs
) >= 0)
1162 /* Keep the original object, and drop the new one. */
1163 if (netdev_attach_name_full(old
, old
->ifname
, &new_netdevs
) >= 0)
1167 /* Detach old NetDev objects from Manager.
1168 * The same object may be registered with multiple names, and netdev_detach() may drop multiple entries. */
1169 for (NetDev
*n
; (n
= hashmap_first(manager
->netdevs
)); )
1172 /* Attach new NetDev objects to Manager. */
1174 _cleanup_(netdev_unrefp
) NetDev
*netdev
= hashmap_steal_first(new_netdevs
);
1178 netdev
->manager
= manager
;
1179 if (netdev_attach(netdev
) < 0)
1182 /* Create a new netdev or update existing netdev, */
1183 if (netdev_request_to_create(netdev
) < 0)
1189 /* Reassign NetDev objects to Link object. */
1191 HASHMAP_FOREACH(link
, manager
->links_by_index
)
1192 link_assign_netdev(link
);
1197 int config_parse_netdev_kind(
1199 const char *filename
,
1201 const char *section
,
1202 unsigned section_line
,
1209 NetDevKind k
, *kind
= ASSERT_PTR(data
);
1214 k
= netdev_kind_from_string(rvalue
);
1216 log_syntax(unit
, LOG_WARNING
, filename
, line
, k
, "Failed to parse netdev kind, ignoring assignment: %s", rvalue
);
1220 if (*kind
!= _NETDEV_KIND_INVALID
&& *kind
!= k
) {
1221 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1222 "Specified netdev kind is different from the previous value '%s', ignoring assignment: %s",
1223 netdev_kind_to_string(*kind
), rvalue
);
1232 int config_parse_netdev_hw_addr(
1234 const char *filename
,
1236 const char *section
,
1237 unsigned section_line
,
1244 struct hw_addr_data
*hw_addr
= ASSERT_PTR(data
);
1248 if (streq(rvalue
, "none")) {
1249 *hw_addr
= HW_ADDR_NONE
;
1253 return config_parse_hw_addr(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, data
, userdata
);