Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <netinet/in.h>
4 : : #include <linux/if.h>
5 : : #include <linux/if_arp.h>
6 : : #include <unistd.h>
7 : :
8 : : #include "alloc-util.h"
9 : : #include "bus-util.h"
10 : : #include "dhcp-identifier.h"
11 : : #include "dhcp-lease-internal.h"
12 : : #include "env-file.h"
13 : : #include "fd-util.h"
14 : : #include "fileio.h"
15 : : #include "missing_network.h"
16 : : #include "netdev/bond.h"
17 : : #include "netdev/bridge.h"
18 : : #include "netdev/ipvlan.h"
19 : : #include "netdev/vrf.h"
20 : : #include "netlink-util.h"
21 : : #include "network-internal.h"
22 : : #include "networkd-can.h"
23 : : #include "networkd-dhcp-server.h"
24 : : #include "networkd-dhcp4.h"
25 : : #include "networkd-dhcp6.h"
26 : : #include "networkd-ipv4ll.h"
27 : : #include "networkd-ipv6-proxy-ndp.h"
28 : : #include "networkd-link-bus.h"
29 : : #include "networkd-link.h"
30 : : #include "networkd-lldp-tx.h"
31 : : #include "networkd-manager.h"
32 : : #include "networkd-ndisc.h"
33 : : #include "networkd-neighbor.h"
34 : : #include "networkd-radv.h"
35 : : #include "networkd-routing-policy-rule.h"
36 : : #include "set.h"
37 : : #include "socket-util.h"
38 : : #include "stdio-util.h"
39 : : #include "string-table.h"
40 : : #include "strv.h"
41 : : #include "sysctl-util.h"
42 : : #include "tmpfile-util.h"
43 : : #include "udev-util.h"
44 : : #include "util.h"
45 : : #include "virt.h"
46 : :
47 : 0 : uint32_t link_get_vrf_table(Link *link) {
48 [ # # ]: 0 : return link->network->vrf ? VRF(link->network->vrf)->table : RT_TABLE_MAIN;
49 : : }
50 : :
51 : 0 : uint32_t link_get_dhcp_route_table(Link *link) {
52 : : /* When the interface is part of an VRF use the VRFs routing table, unless
53 : : * another table is explicitly specified. */
54 [ # # ]: 0 : if (link->network->dhcp_route_table_set)
55 : 0 : return link->network->dhcp_route_table;
56 : 0 : return link_get_vrf_table(link);
57 : : }
58 : :
59 : 0 : uint32_t link_get_ipv6_accept_ra_route_table(Link *link) {
60 [ # # ]: 0 : if (link->network->ipv6_accept_ra_route_table_set)
61 : 0 : return link->network->ipv6_accept_ra_route_table;
62 : 0 : return link_get_vrf_table(link);
63 : : }
64 : :
65 : 0 : DUID* link_get_duid(Link *link) {
66 [ # # ]: 0 : if (link->network->duid.type != _DUID_TYPE_INVALID)
67 : 0 : return &link->network->duid;
68 : : else
69 : 0 : return &link->manager->duid;
70 : : }
71 : :
72 : 0 : int link_sysctl_ipv6_enabled(Link *link) {
73 : 0 : _cleanup_free_ char *value = NULL;
74 : : int r;
75 : :
76 [ # # ]: 0 : assert(link);
77 [ # # ]: 0 : assert(link->ifname);
78 : :
79 [ # # ]: 0 : if (link->sysctl_ipv6_enabled >= 0)
80 : 0 : return link->sysctl_ipv6_enabled;
81 : :
82 : 0 : const char *ifname = link->ifname; /* work around bogus gcc warning */
83 : 0 : r = sysctl_read_ip_property(AF_INET6, ifname, "disable_ipv6", &value);
84 [ # # ]: 0 : if (r < 0)
85 [ # # # # ]: 0 : return log_link_warning_errno(link, r,
86 : : "Failed to read net.ipv6.conf.%s.disable_ipv6 sysctl property: %m",
87 : : ifname);
88 : :
89 : 0 : link->sysctl_ipv6_enabled = value[0] == '0';
90 : 0 : return link->sysctl_ipv6_enabled;
91 : : }
92 : :
93 : 0 : static bool link_dhcp6_enabled(Link *link) {
94 [ # # ]: 0 : assert(link);
95 : :
96 [ # # ]: 0 : if (!socket_ipv6_is_supported())
97 : 0 : return false;
98 : :
99 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
100 : 0 : return false;
101 : :
102 [ # # ]: 0 : if (!link->network)
103 : 0 : return false;
104 : :
105 [ # # ]: 0 : if (link->network->bond)
106 : 0 : return false;
107 : :
108 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
109 : 0 : return false;
110 : :
111 [ # # ]: 0 : if (link_sysctl_ipv6_enabled(link) == 0)
112 : 0 : return false;
113 : :
114 : 0 : return link->network->dhcp & ADDRESS_FAMILY_IPV6;
115 : : }
116 : :
117 : 0 : static bool link_dhcp4_enabled(Link *link) {
118 [ # # ]: 0 : assert(link);
119 : :
120 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
121 : 0 : return false;
122 : :
123 [ # # ]: 0 : if (!link->network)
124 : 0 : return false;
125 : :
126 [ # # ]: 0 : if (link->network->bond)
127 : 0 : return false;
128 : :
129 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
130 : 0 : return false;
131 : :
132 : 0 : return link->network->dhcp & ADDRESS_FAMILY_IPV4;
133 : : }
134 : :
135 : 0 : static bool link_dhcp4_server_enabled(Link *link) {
136 [ # # ]: 0 : assert(link);
137 : :
138 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
139 : 0 : return false;
140 : :
141 [ # # ]: 0 : if (!link->network)
142 : 0 : return false;
143 : :
144 [ # # ]: 0 : if (link->network->bond)
145 : 0 : return false;
146 : :
147 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
148 : 0 : return false;
149 : :
150 : 0 : return link->network->dhcp_server;
151 : : }
152 : :
153 : 0 : bool link_ipv4ll_enabled(Link *link, AddressFamily mask) {
154 [ # # ]: 0 : assert(link);
155 [ # # ]: 0 : assert((mask & ~(ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) == 0);
156 : :
157 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
158 : 0 : return false;
159 : :
160 [ # # ]: 0 : if (!link->network)
161 : 0 : return false;
162 : :
163 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
164 : 0 : return false;
165 : :
166 [ # # # # : 0 : if (STRPTR_IN_SET(link->kind,
# # ]
167 : : "vrf", "wireguard", "ipip", "gre", "ip6gre","ip6tnl", "sit", "vti",
168 : : "vti6", "nlmon", "xfrm"))
169 : 0 : return false;
170 : :
171 : : /* L3 or L3S mode do not support ARP. */
172 [ # # # # ]: 0 : if (IN_SET(link_get_ipvlan_mode(link), NETDEV_IPVLAN_MODE_L3, NETDEV_IPVLAN_MODE_L3S))
173 : 0 : return false;
174 : :
175 [ # # ]: 0 : if (link->network->bond)
176 : 0 : return false;
177 : :
178 : 0 : return link->network->link_local & mask;
179 : : }
180 : :
181 : 0 : static bool link_ipv6ll_enabled(Link *link) {
182 [ # # ]: 0 : assert(link);
183 : :
184 [ # # ]: 0 : if (!socket_ipv6_is_supported())
185 : 0 : return false;
186 : :
187 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
188 : 0 : return false;
189 : :
190 [ # # ]: 0 : if (!link->network)
191 : 0 : return false;
192 : :
193 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
194 : 0 : return false;
195 : :
196 [ # # # # : 0 : if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "nlmon"))
# # ]
197 : 0 : return false;
198 : :
199 [ # # ]: 0 : if (link->network->bond)
200 : 0 : return false;
201 : :
202 [ # # ]: 0 : if (link_sysctl_ipv6_enabled(link) == 0)
203 : 0 : return false;
204 : :
205 : 0 : return link->network->link_local & ADDRESS_FAMILY_IPV6;
206 : : }
207 : :
208 : 0 : static bool link_ipv6_enabled(Link *link) {
209 [ # # ]: 0 : assert(link);
210 : :
211 [ # # ]: 0 : if (!socket_ipv6_is_supported())
212 : 0 : return false;
213 : :
214 [ # # ]: 0 : if (link->network->bond)
215 : 0 : return false;
216 : :
217 [ # # ]: 0 : if (link_sysctl_ipv6_enabled(link) == 0)
218 : 0 : return false;
219 : :
220 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
221 : 0 : return false;
222 : :
223 : : /* DHCPv6 client will not be started if no IPv6 link-local address is configured. */
224 [ # # # # ]: 0 : return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
225 : : }
226 : :
227 : 0 : static bool link_radv_enabled(Link *link) {
228 [ # # ]: 0 : assert(link);
229 : :
230 [ # # ]: 0 : if (!link_ipv6ll_enabled(link))
231 : 0 : return false;
232 : :
233 : 0 : return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE;
234 : : }
235 : :
236 : 0 : static bool link_ipv4_forward_enabled(Link *link) {
237 [ # # ]: 0 : assert(link);
238 : :
239 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
240 : 0 : return false;
241 : :
242 [ # # ]: 0 : if (!link->network)
243 : 0 : return false;
244 : :
245 [ # # ]: 0 : if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
246 : 0 : return false;
247 : :
248 : 0 : return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
249 : : }
250 : :
251 : 0 : static bool link_ipv6_forward_enabled(Link *link) {
252 [ # # ]: 0 : assert(link);
253 : :
254 [ # # ]: 0 : if (!socket_ipv6_is_supported())
255 : 0 : return false;
256 : :
257 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
258 : 0 : return false;
259 : :
260 [ # # ]: 0 : if (!link->network)
261 : 0 : return false;
262 : :
263 [ # # ]: 0 : if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
264 : 0 : return false;
265 : :
266 [ # # ]: 0 : if (link_sysctl_ipv6_enabled(link) == 0)
267 : 0 : return false;
268 : :
269 : 0 : return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
270 : : }
271 : :
272 : 0 : static bool link_proxy_arp_enabled(Link *link) {
273 [ # # ]: 0 : assert(link);
274 : :
275 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
276 : 0 : return false;
277 : :
278 [ # # ]: 0 : if (!link->network)
279 : 0 : return false;
280 : :
281 [ # # ]: 0 : if (link->network->proxy_arp < 0)
282 : 0 : return false;
283 : :
284 : 0 : return true;
285 : : }
286 : :
287 : 0 : static bool link_ipv6_accept_ra_enabled(Link *link) {
288 [ # # ]: 0 : assert(link);
289 : :
290 [ # # ]: 0 : if (!socket_ipv6_is_supported())
291 : 0 : return false;
292 : :
293 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
294 : 0 : return false;
295 : :
296 [ # # ]: 0 : if (!link->network)
297 : 0 : return false;
298 : :
299 [ # # ]: 0 : if (!link_ipv6ll_enabled(link))
300 : 0 : return false;
301 : :
302 : : /* If unset use system default (enabled if local forwarding is disabled.
303 : : * disabled if local forwarding is enabled).
304 : : * If set, ignore or enforce RA independent of local forwarding state.
305 : : */
306 [ # # ]: 0 : if (link->network->ipv6_accept_ra < 0)
307 : : /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
308 : 0 : return !link_ipv6_forward_enabled(link);
309 [ # # ]: 0 : else if (link->network->ipv6_accept_ra > 0)
310 : : /* accept RA even if ip_forward is enabled */
311 : 0 : return true;
312 : : else
313 : : /* ignore RA */
314 : 0 : return false;
315 : : }
316 : :
317 : 0 : static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
318 [ # # ]: 0 : assert(link);
319 : :
320 [ # # ]: 0 : if (!socket_ipv6_is_supported())
321 : 0 : return _IPV6_PRIVACY_EXTENSIONS_INVALID;
322 : :
323 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
324 : 0 : return _IPV6_PRIVACY_EXTENSIONS_INVALID;
325 : :
326 [ # # ]: 0 : if (!link->network)
327 : 0 : return _IPV6_PRIVACY_EXTENSIONS_INVALID;
328 : :
329 : 0 : return link->network->ipv6_privacy_extensions;
330 : : }
331 : :
332 : 0 : static int link_enable_ipv6(Link *link) {
333 : : bool disabled;
334 : : int r;
335 : :
336 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
337 : 0 : return 0;
338 : :
339 : 0 : disabled = !link_ipv6_enabled(link);
340 : :
341 : 0 : r = sysctl_write_ip_property_boolean(AF_INET6, link->ifname, "disable_ipv6", disabled);
342 [ # # ]: 0 : if (r < 0)
343 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot %s IPv6: %m", enable_disable(!disabled));
344 : : else
345 [ # # # # ]: 0 : log_link_info(link, "IPv6 successfully %sd", enable_disable(!disabled));
346 : :
347 : 0 : return 0;
348 : : }
349 : :
350 : 16 : static bool link_is_enslaved(Link *link) {
351 [ - + ]: 16 : if (link->flags & IFF_SLAVE)
352 : : /* Even if the link is not managed by networkd, honor IFF_SLAVE flag. */
353 : 0 : return true;
354 : :
355 [ + - ]: 16 : if (!link->network)
356 : 16 : return false;
357 : :
358 [ # # # # ]: 0 : if (link->master_ifindex > 0 && link->network->bridge)
359 : 0 : return true;
360 : :
361 : : /* TODO: add conditions for other netdevs. */
362 : :
363 : 0 : return false;
364 : : }
365 : :
366 : 0 : static void link_update_master_operstate(Link *link, NetDev *netdev) {
367 : : Link *master;
368 : :
369 [ # # ]: 0 : if (!netdev)
370 : 0 : return;
371 : :
372 [ # # ]: 0 : if (link_get(link->manager, netdev->ifindex, &master) < 0)
373 : 0 : return;
374 : :
375 : 0 : link_update_operstate(master, true);
376 : : }
377 : :
378 : 28 : void link_update_operstate(Link *link, bool also_update_master) {
379 : : LinkOperationalState operstate;
380 : : LinkCarrierState carrier_state;
381 : : LinkAddressState address_state;
382 : 28 : _cleanup_strv_free_ char **p = NULL;
383 : 28 : uint8_t scope = RT_SCOPE_NOWHERE;
384 : 28 : bool changed = false;
385 : : Address *address;
386 : : Iterator i;
387 : :
388 [ - + ]: 28 : assert(link);
389 : :
390 [ - + ]: 28 : if (link->kernel_operstate == IF_OPER_DORMANT)
391 : 0 : carrier_state = LINK_CARRIER_STATE_DORMANT;
392 [ + + ]: 28 : else if (link_has_carrier(link)) {
393 [ - + ]: 16 : if (link_is_enslaved(link))
394 : 0 : carrier_state = LINK_CARRIER_STATE_ENSLAVED;
395 : : else
396 : 16 : carrier_state = LINK_CARRIER_STATE_CARRIER;
397 [ + + ]: 12 : } else if (link->flags & IFF_UP)
398 : 8 : carrier_state = LINK_CARRIER_STATE_NO_CARRIER;
399 : : else
400 : 4 : carrier_state = LINK_CARRIER_STATE_OFF;
401 : :
402 [ + + ]: 28 : if (carrier_state >= LINK_CARRIER_STATE_CARRIER) {
403 : : Link *slave;
404 : :
405 [ - + ]: 16 : SET_FOREACH(slave, link->slaves, i) {
406 : 0 : link_update_operstate(slave, false);
407 : :
408 [ # # ]: 0 : if (slave->carrier_state < LINK_CARRIER_STATE_CARRIER)
409 : 0 : carrier_state = LINK_CARRIER_STATE_DEGRADED_CARRIER;
410 : : }
411 : : }
412 : :
413 [ - + ]: 28 : SET_FOREACH(address, link->addresses, i) {
414 [ # # ]: 0 : if (!address_is_ready(address))
415 : 0 : continue;
416 : :
417 [ # # ]: 0 : if (address->scope < scope)
418 : 0 : scope = address->scope;
419 : : }
420 : :
421 : : /* for operstate we also take foreign addresses into account */
422 [ - + ]: 28 : SET_FOREACH(address, link->addresses_foreign, i) {
423 [ # # ]: 0 : if (!address_is_ready(address))
424 : 0 : continue;
425 : :
426 [ # # ]: 0 : if (address->scope < scope)
427 : 0 : scope = address->scope;
428 : : }
429 : :
430 [ - + ]: 28 : if (scope < RT_SCOPE_SITE)
431 : : /* universally accessible addresses found */
432 : 0 : address_state = LINK_ADDRESS_STATE_ROUTABLE;
433 [ - + ]: 28 : else if (scope < RT_SCOPE_HOST)
434 : : /* only link or site local addresses found */
435 : 0 : address_state = LINK_ADDRESS_STATE_DEGRADED;
436 : : else
437 : : /* no useful addresses found */
438 : 28 : address_state = LINK_ADDRESS_STATE_OFF;
439 : :
440 : : /* Mapping of address and carrier state vs operational state
441 : : * carrier state
442 : : * | off | no-carrier | dormant | degraded-carrier | carrier | enslaved
443 : : * ------------------------------------------------------------------------------
444 : : * off | off | no-carrier | dormant | degraded-carrier | carrier | enslaved
445 : : * address_state degraded | off | no-carrier | dormant | degraded-carrier | degraded | enslaved
446 : : * routable | off | no-carrier | dormant | degraded-carrier | routable | routable
447 : : */
448 : :
449 [ + + + - ]: 28 : if (carrier_state < LINK_CARRIER_STATE_CARRIER || address_state == LINK_ADDRESS_STATE_OFF)
450 : 28 : operstate = (LinkOperationalState) carrier_state;
451 [ # # ]: 0 : else if (address_state == LINK_ADDRESS_STATE_ROUTABLE)
452 : 0 : operstate = LINK_OPERSTATE_ROUTABLE;
453 [ # # ]: 0 : else if (carrier_state == LINK_CARRIER_STATE_CARRIER)
454 : 0 : operstate = LINK_OPERSTATE_DEGRADED;
455 : : else
456 : 0 : operstate = LINK_OPERSTATE_ENSLAVED;
457 : :
458 [ + + ]: 28 : if (link->carrier_state != carrier_state) {
459 : 24 : link->carrier_state = carrier_state;
460 : 24 : changed = true;
461 [ - + ]: 24 : if (strv_extend(&p, "CarrierState") < 0)
462 : 0 : log_oom();
463 : : }
464 : :
465 [ - + ]: 28 : if (link->address_state != address_state) {
466 : 0 : link->address_state = address_state;
467 : 0 : changed = true;
468 [ # # ]: 0 : if (strv_extend(&p, "AddressState") < 0)
469 : 0 : log_oom();
470 : : }
471 : :
472 [ + + ]: 28 : if (link->operstate != operstate) {
473 : 24 : link->operstate = operstate;
474 : 24 : changed = true;
475 [ - + ]: 24 : if (strv_extend(&p, "OperationalState") < 0)
476 : 0 : log_oom();
477 : : }
478 : :
479 [ + + ]: 28 : if (p)
480 : 24 : link_send_changed_strv(link, p);
481 [ + + ]: 28 : if (changed)
482 : 24 : link_dirty(link);
483 : :
484 [ + - - + ]: 28 : if (also_update_master && link->network) {
485 : 0 : link_update_master_operstate(link, link->network->bond);
486 : 0 : link_update_master_operstate(link, link->network->bridge);
487 : : }
488 : 28 : }
489 : :
490 : : #define FLAG_STRING(string, flag, old, new) \
491 : : (((old ^ new) & flag) \
492 : : ? ((old & flag) ? (" -" string) : (" +" string)) \
493 : : : "")
494 : :
495 : 56 : static int link_update_flags(Link *link, sd_netlink_message *m, bool force_update_operstate) {
496 : : unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
497 : : uint8_t operstate;
498 : : int r;
499 : :
500 [ - + ]: 56 : assert(link);
501 : :
502 : 56 : r = sd_rtnl_message_link_get_flags(m, &flags);
503 [ - + ]: 56 : if (r < 0)
504 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not get link flags: %m");
505 : :
506 : 56 : r = sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &operstate);
507 [ - + ]: 56 : if (r < 0)
508 : : /* if we got a message without operstate, take it to mean
509 : : the state was unchanged */
510 : 0 : operstate = link->kernel_operstate;
511 : :
512 [ + - + + : 56 : if (!force_update_operstate && (link->flags == flags) && (link->kernel_operstate == operstate))
+ - ]
513 : 28 : return 0;
514 : :
515 [ + - ]: 28 : if (link->flags != flags) {
516 [ + - + - : 28 : log_link_debug(link, "Flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
- + # # -
+ # # - +
# # + + -
+ - + # #
- + # # -
+ # # - +
# # - + #
# + + - +
+ + - + +
+ - + + +
- + + + -
+ - + # #
+ + - + -
+ # # - +
# # + + -
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
517 : : FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
518 : : FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
519 : : FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
520 : : FLAG_STRING("UP", IFF_UP, link->flags, flags),
521 : : FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
522 : : FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
523 : : FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
524 : : FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
525 : : FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
526 : : FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
527 : : FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
528 : : FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
529 : : FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
530 : : FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
531 : : FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
532 : : FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
533 : : FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
534 : : FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
535 : : FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
536 : :
537 : 28 : unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
538 : : IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
539 : : IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
540 : : IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
541 : : IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
542 : : IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
543 : 28 : unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
544 : 28 : unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
545 : :
546 : : /* link flags are currently at most 18 bits, let's align to
547 : : * printing 20 */
548 [ - + ]: 28 : if (unknown_flags_added)
549 [ # # # # ]: 0 : log_link_debug(link,
550 : : "Unknown link flags gained: %#.5x (ignoring)",
551 : : unknown_flags_added);
552 : :
553 [ - + ]: 28 : if (unknown_flags_removed)
554 [ # # # # ]: 0 : log_link_debug(link,
555 : : "Unknown link flags lost: %#.5x (ignoring)",
556 : : unknown_flags_removed);
557 : : }
558 : :
559 : 28 : link->flags = flags;
560 : 28 : link->kernel_operstate = operstate;
561 : :
562 : 28 : link_update_operstate(link, true);
563 : :
564 : 28 : return 0;
565 : : }
566 : :
567 : 28 : static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
568 : 28 : _cleanup_(link_unrefp) Link *link = NULL;
569 : : uint16_t type;
570 : 28 : const char *ifname, *kind = NULL;
571 : : int r, ifindex;
572 : : unsigned short iftype;
573 : :
574 [ - + ]: 28 : assert(manager);
575 [ - + ]: 28 : assert(message);
576 [ - + ]: 28 : assert(ret);
577 : :
578 : : /* check for link kind */
579 : 28 : r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
580 [ + + ]: 28 : if (r == 0) {
581 : 16 : (void) sd_netlink_message_read_string(message, IFLA_INFO_KIND, &kind);
582 : 16 : r = sd_netlink_message_exit_container(message);
583 [ - + ]: 16 : if (r < 0)
584 : 0 : return r;
585 : : }
586 : :
587 : 28 : r = sd_netlink_message_get_type(message, &type);
588 [ - + ]: 28 : if (r < 0)
589 : 0 : return r;
590 [ - + ]: 28 : else if (type != RTM_NEWLINK)
591 : 0 : return -EINVAL;
592 : :
593 : 28 : r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
594 [ - + ]: 28 : if (r < 0)
595 : 0 : return r;
596 [ - + ]: 28 : else if (ifindex <= 0)
597 : 0 : return -EINVAL;
598 : :
599 : 28 : r = sd_rtnl_message_link_get_type(message, &iftype);
600 [ - + ]: 28 : if (r < 0)
601 : 0 : return r;
602 : :
603 : 28 : r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
604 [ - + ]: 28 : if (r < 0)
605 : 0 : return r;
606 : :
607 : 28 : link = new(Link, 1);
608 [ - + ]: 28 : if (!link)
609 : 0 : return -ENOMEM;
610 : :
611 : 28 : *link = (Link) {
612 : : .n_ref = 1,
613 : : .manager = manager,
614 : : .state = LINK_STATE_PENDING,
615 : : .ifindex = ifindex,
616 : : .iftype = iftype,
617 : : .sysctl_ipv6_enabled = -1,
618 : :
619 : : .n_dns = (unsigned) -1,
620 : : .dns_default_route = -1,
621 : : .llmnr = _RESOLVE_SUPPORT_INVALID,
622 : : .mdns = _RESOLVE_SUPPORT_INVALID,
623 : : .dnssec_mode = _DNSSEC_MODE_INVALID,
624 : : .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
625 : : };
626 : :
627 : 28 : link->ifname = strdup(ifname);
628 [ - + ]: 28 : if (!link->ifname)
629 : 0 : return -ENOMEM;
630 : :
631 [ + + ]: 28 : if (kind) {
632 : 16 : link->kind = strdup(kind);
633 [ - + ]: 16 : if (!link->kind)
634 : 0 : return -ENOMEM;
635 : : }
636 : :
637 : 28 : r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t *)&link->master_ifindex);
638 [ + + ]: 28 : if (r < 0)
639 [ + - + - ]: 24 : log_link_debug_errno(link, r, "New device has no master, continuing without");
640 : :
641 : 28 : r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
642 [ + + ]: 28 : if (r < 0)
643 [ + - + - ]: 8 : log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
644 : :
645 [ - + ]: 28 : if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
646 : 0 : return -ENOMEM;
647 : :
648 [ - + ]: 28 : if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
649 : 0 : return -ENOMEM;
650 : :
651 [ - + ]: 28 : if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
652 : 0 : return -ENOMEM;
653 : :
654 : 28 : r = hashmap_ensure_allocated(&manager->links, NULL);
655 [ - + ]: 28 : if (r < 0)
656 : 0 : return r;
657 : :
658 : 28 : r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
659 [ - + ]: 28 : if (r < 0)
660 : 0 : return r;
661 : :
662 : 28 : r = link_update_flags(link, message, false);
663 [ - + ]: 28 : if (r < 0)
664 : 0 : return r;
665 : :
666 : 28 : *ret = TAKE_PTR(link);
667 : :
668 : 28 : return 0;
669 : : }
670 : :
671 : 28 : void link_ntp_settings_clear(Link *link) {
672 : 28 : link->ntp = strv_free(link->ntp);
673 : 28 : }
674 : :
675 : 28 : void link_dns_settings_clear(Link *link) {
676 : 28 : link->dns = mfree(link->dns);
677 : 28 : link->n_dns = (unsigned) -1;
678 : :
679 : 28 : link->search_domains = ordered_set_free_free(link->search_domains);
680 : 28 : link->route_domains = ordered_set_free_free(link->route_domains);
681 : :
682 : 28 : link->dns_default_route = -1;
683 : 28 : link->llmnr = _RESOLVE_SUPPORT_INVALID;
684 : 28 : link->mdns = _RESOLVE_SUPPORT_INVALID;
685 : 28 : link->dnssec_mode = _DNSSEC_MODE_INVALID;
686 : 28 : link->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID;
687 : :
688 : 28 : link->dnssec_negative_trust_anchors = set_free_free(link->dnssec_negative_trust_anchors);
689 : 28 : }
690 : :
691 : 28 : static Link *link_free(Link *link) {
692 : : Address *address;
693 : :
694 [ - + ]: 28 : assert(link);
695 : :
696 : 28 : link_ntp_settings_clear(link);
697 : 28 : link_dns_settings_clear(link);
698 : :
699 [ - + ]: 28 : link->routes = set_free_with_destructor(link->routes, route_free);
700 [ - + ]: 28 : link->routes_foreign = set_free_with_destructor(link->routes_foreign, route_free);
701 : :
702 [ - + ]: 28 : link->neighbors = set_free_with_destructor(link->neighbors, neighbor_free);
703 [ - + ]: 28 : link->neighbors_foreign = set_free_with_destructor(link->neighbors_foreign, neighbor_free);
704 : :
705 [ - + ]: 28 : link->addresses = set_free_with_destructor(link->addresses, address_free);
706 [ - + ]: 28 : link->addresses_foreign = set_free_with_destructor(link->addresses_foreign, address_free);
707 : :
708 [ - + ]: 28 : while ((address = link->pool_addresses)) {
709 [ # # # # : 0 : LIST_REMOVE(addresses, link->pool_addresses, address);
# # # # ]
710 : 0 : address_free(address);
711 : : }
712 : :
713 : 28 : sd_dhcp_server_unref(link->dhcp_server);
714 : 28 : sd_dhcp_client_unref(link->dhcp_client);
715 : 28 : sd_dhcp_lease_unref(link->dhcp_lease);
716 : 28 : set_free(link->dhcp_routes);
717 : :
718 : 28 : link_lldp_emit_stop(link);
719 : :
720 : 28 : free(link->lease_file);
721 : :
722 : 28 : sd_lldp_unref(link->lldp);
723 : 28 : free(link->lldp_file);
724 : :
725 : 28 : ndisc_flush(link);
726 : :
727 : 28 : sd_ipv4ll_unref(link->ipv4ll);
728 : 28 : sd_dhcp6_client_unref(link->dhcp6_client);
729 : 28 : sd_ndisc_unref(link->ndisc);
730 : 28 : sd_radv_unref(link->radv);
731 : :
732 : 28 : free(link->ifname);
733 : 28 : free(link->kind);
734 : :
735 : 28 : (void) unlink(link->state_file);
736 : 28 : free(link->state_file);
737 : :
738 : 28 : sd_device_unref(link->sd_device);
739 : :
740 : 28 : hashmap_free(link->bound_to_links);
741 : 28 : hashmap_free(link->bound_by_links);
742 : :
743 [ - + ]: 28 : set_free_with_destructor(link->slaves, link_unref);
744 : :
745 : 28 : network_unref(link->network);
746 : :
747 : 28 : return mfree(link);
748 : : }
749 : :
750 [ - + - + : 132 : DEFINE_TRIVIAL_REF_UNREF_FUNC(Link, link, link_free);
+ + ]
751 : :
752 : 28 : int link_get(Manager *m, int ifindex, Link **ret) {
753 : : Link *link;
754 : :
755 [ - + ]: 28 : assert(m);
756 [ - + ]: 28 : assert(ifindex);
757 [ - + ]: 28 : assert(ret);
758 : :
759 : 28 : link = hashmap_get(m->links, INT_TO_PTR(ifindex));
760 [ + - ]: 28 : if (!link)
761 : 28 : return -ENODEV;
762 : :
763 : 0 : *ret = link;
764 : :
765 : 0 : return 0;
766 : : }
767 : :
768 : 28 : void link_set_state(Link *link, LinkState state) {
769 [ - + ]: 28 : assert(link);
770 : :
771 [ - + ]: 28 : if (link->state == state)
772 : 0 : return;
773 : :
774 [ + - + - ]: 28 : log_link_debug(link, "State changed: %s -> %s",
775 : : link_state_to_string(link->state),
776 : : link_state_to_string(state));
777 : :
778 : 28 : link->state = state;
779 : :
780 : 28 : link_send_changed(link, "AdministrativeState", NULL);
781 : : }
782 : :
783 : 0 : static void link_enter_unmanaged(Link *link) {
784 [ # # ]: 0 : assert(link);
785 : :
786 : 0 : link_set_state(link, LINK_STATE_UNMANAGED);
787 : :
788 : 0 : link_dirty(link);
789 : 0 : }
790 : :
791 : 28 : int link_stop_clients(Link *link, bool may_keep_dhcp) {
792 : 28 : int r = 0, k;
793 : :
794 [ - + ]: 28 : assert(link);
795 [ - + ]: 28 : assert(link->manager);
796 [ - + ]: 28 : assert(link->manager->event);
797 : :
798 : 28 : dhcp4_release_old_lease(link);
799 : :
800 [ - + # # : 28 : if (link->dhcp_client && (!may_keep_dhcp || !link->network ||
# # ]
801 [ # # ]: 0 : !FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP))) {
802 : 0 : k = sd_dhcp_client_stop(link->dhcp_client);
803 [ # # ]: 0 : if (k < 0)
804 [ # # # # ]: 0 : r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
805 : : }
806 : :
807 [ - + ]: 28 : if (link->ipv4ll) {
808 : 0 : k = sd_ipv4ll_stop(link->ipv4ll);
809 [ # # ]: 0 : if (k < 0)
810 [ # # # # ]: 0 : r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
811 : : }
812 : :
813 [ - + ]: 28 : if (link->dhcp6_client) {
814 : 0 : k = sd_dhcp6_client_stop(link->dhcp6_client);
815 [ # # ]: 0 : if (k < 0)
816 [ # # # # ]: 0 : r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
817 : : }
818 : :
819 [ - + ]: 28 : if (link->ndisc) {
820 : 0 : k = sd_ndisc_stop(link->ndisc);
821 [ # # ]: 0 : if (k < 0)
822 [ # # # # ]: 0 : r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
823 : : }
824 : :
825 [ - + ]: 28 : if (link->radv) {
826 : 0 : k = sd_radv_stop(link->radv);
827 [ # # ]: 0 : if (k < 0)
828 [ # # # # ]: 0 : r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
829 : : }
830 : :
831 : 28 : link_lldp_emit_stop(link);
832 : 28 : return r;
833 : : }
834 : :
835 : 0 : void link_enter_failed(Link *link) {
836 [ # # ]: 0 : assert(link);
837 : :
838 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
839 : 0 : return;
840 : :
841 [ # # # # ]: 0 : log_link_warning(link, "Failed");
842 : :
843 : 0 : link_set_state(link, LINK_STATE_FAILED);
844 : :
845 : 0 : link_stop_clients(link, false);
846 : :
847 : 0 : link_dirty(link);
848 : : }
849 : :
850 : 0 : static int link_join_netdevs_after_configured(Link *link) {
851 : : NetDev *netdev;
852 : : Iterator i;
853 : : int r;
854 : :
855 [ # # ]: 0 : HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
856 [ # # ]: 0 : if (netdev->ifindex > 0)
857 : : /* Assume already enslaved. */
858 : 0 : continue;
859 : :
860 [ # # ]: 0 : if (netdev_get_create_type(netdev) != NETDEV_CREATE_AFTER_CONFIGURED)
861 : 0 : continue;
862 : :
863 : 0 : log_struct(LOG_DEBUG,
864 : : LOG_LINK_INTERFACE(link),
865 : : LOG_NETDEV_INTERFACE(netdev),
866 : : LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
867 : :
868 : 0 : r = netdev_join(netdev, link, NULL);
869 [ # # ]: 0 : if (r < 0)
870 : 0 : return log_struct_errno(LOG_WARNING, r,
871 : : LOG_LINK_INTERFACE(link),
872 : : LOG_NETDEV_INTERFACE(netdev),
873 : : LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
874 : : }
875 : :
876 : 0 : return 0;
877 : : }
878 : :
879 : 0 : static void link_enter_configured(Link *link) {
880 [ # # ]: 0 : assert(link);
881 [ # # ]: 0 : assert(link->network);
882 : :
883 [ # # ]: 0 : if (link->state != LINK_STATE_CONFIGURING)
884 : 0 : return;
885 : :
886 [ # # # # ]: 0 : log_link_info(link, "Configured");
887 : :
888 : 0 : link_set_state(link, LINK_STATE_CONFIGURED);
889 : :
890 : 0 : (void) link_join_netdevs_after_configured(link);
891 : :
892 : 0 : link_dirty(link);
893 : : }
894 : :
895 : 0 : static int link_request_set_routing_policy_rule(Link *link) {
896 : 0 : RoutingPolicyRule *rule, *rrule = NULL;
897 : : int r;
898 : :
899 [ # # ]: 0 : assert(link);
900 [ # # ]: 0 : assert(link->network);
901 : :
902 : 0 : link->routing_policy_rules_configured = false;
903 : :
904 [ # # ]: 0 : LIST_FOREACH(rules, rule, link->network->rules) {
905 : 0 : r = routing_policy_rule_get(link->manager, rule, &rrule);
906 [ # # ]: 0 : if (r >= 0) {
907 [ # # ]: 0 : if (r == 0)
908 : 0 : (void) routing_policy_rule_make_local(link->manager, rrule);
909 : 0 : continue;
910 : : }
911 : :
912 : 0 : r = routing_policy_rule_configure(rule, link, NULL);
913 [ # # ]: 0 : if (r < 0)
914 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set routing policy rules: %m");
915 [ # # ]: 0 : if (r > 0)
916 : 0 : link->routing_policy_rule_messages++;
917 : : }
918 : :
919 : 0 : routing_policy_rule_purge(link->manager, link);
920 [ # # ]: 0 : if (link->routing_policy_rule_messages == 0) {
921 : 0 : link->routing_policy_rules_configured = true;
922 : 0 : link_check_ready(link);
923 : : } else {
924 [ # # # # ]: 0 : log_link_debug(link, "Setting routing policy rules");
925 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
926 : : }
927 : :
928 : 0 : return 0;
929 : : }
930 : :
931 : 0 : static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
932 : : int r;
933 : :
934 [ # # ]: 0 : assert(link);
935 [ # # ]: 0 : assert(link->route_messages > 0);
936 [ # # # # ]: 0 : assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
937 : : LINK_STATE_FAILED, LINK_STATE_LINGER));
938 : :
939 : 0 : link->route_messages--;
940 : :
941 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
942 : 0 : return 1;
943 : :
944 : 0 : r = sd_netlink_message_get_errno(m);
945 [ # # # # ]: 0 : if (r < 0 && r != -EEXIST) {
946 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not set route: %m");
947 : 0 : link_enter_failed(link);
948 : 0 : return 1;
949 : : }
950 : :
951 [ # # ]: 0 : if (link->route_messages == 0) {
952 [ # # # # ]: 0 : log_link_debug(link, "Routes set");
953 : 0 : link->static_routes_configured = true;
954 : 0 : link_check_ready(link);
955 : : }
956 : :
957 : 0 : return 1;
958 : : }
959 : :
960 : 0 : int link_request_set_routes(Link *link) {
961 : : enum {
962 : : PHASE_NON_GATEWAY, /* First phase: Routes without a gateway */
963 : : PHASE_GATEWAY, /* Second phase: Routes with a gateway */
964 : : _PHASE_MAX
965 : : } phase;
966 : : Route *rt;
967 : : int r;
968 : :
969 [ # # ]: 0 : assert(link);
970 [ # # ]: 0 : assert(link->network);
971 [ # # ]: 0 : assert(link->addresses_configured);
972 [ # # ]: 0 : assert(link->address_messages == 0);
973 [ # # ]: 0 : assert(link->state != _LINK_STATE_INVALID);
974 : :
975 : 0 : link->static_routes_configured = false;
976 : :
977 [ # # # # ]: 0 : if (!link_has_carrier(link) && !link->network->configure_without_carrier)
978 : : /* During configuring addresses, the link lost its carrier. As networkd is dropping
979 : : * the addresses now, let's not configure the routes either. */
980 : 0 : return 0;
981 : :
982 : 0 : r = link_request_set_routing_policy_rule(link);
983 [ # # ]: 0 : if (r < 0)
984 : 0 : return r;
985 : :
986 : : /* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
987 [ # # ]: 0 : for (phase = 0; phase < _PHASE_MAX; phase++)
988 [ # # ]: 0 : LIST_FOREACH(routes, rt, link->network->static_routes) {
989 : :
990 [ # # ]: 0 : if (in_addr_is_null(rt->family, &rt->gw) != (phase == PHASE_NON_GATEWAY))
991 : 0 : continue;
992 : :
993 : 0 : r = route_configure(rt, link, route_handler);
994 [ # # ]: 0 : if (r < 0)
995 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set routes: %m");
996 [ # # ]: 0 : if (r > 0)
997 : 0 : link->route_messages++;
998 : : }
999 : :
1000 [ # # ]: 0 : if (link->route_messages == 0) {
1001 : 0 : link->static_routes_configured = true;
1002 : 0 : link_check_ready(link);
1003 : : } else {
1004 [ # # # # ]: 0 : log_link_debug(link, "Setting routes");
1005 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
1006 : : }
1007 : :
1008 : 0 : return 0;
1009 : : }
1010 : :
1011 : 0 : void link_check_ready(Link *link) {
1012 : : Address *a;
1013 : : Iterator i;
1014 : : int r;
1015 : :
1016 [ # # ]: 0 : assert(link);
1017 : :
1018 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1019 : 0 : return;
1020 : :
1021 [ # # ]: 0 : if (!link->network)
1022 : 0 : return;
1023 : :
1024 [ # # ]: 0 : if (!link->addresses_configured)
1025 : 0 : return;
1026 : :
1027 [ # # ]: 0 : if (!link->neighbors_configured)
1028 : 0 : return;
1029 : :
1030 [ # # ]: 0 : SET_FOREACH(a, link->addresses, i)
1031 [ # # ]: 0 : if (!address_is_ready(a))
1032 : 0 : return;
1033 : :
1034 [ # # ]: 0 : if (!link->addresses_ready) {
1035 : 0 : link->addresses_ready = true;
1036 : 0 : r = link_request_set_routes(link);
1037 [ # # ]: 0 : if (r < 0)
1038 : 0 : link_enter_failed(link);
1039 : 0 : return;
1040 : : }
1041 : :
1042 [ # # ]: 0 : if (!link->static_routes_configured)
1043 : 0 : return;
1044 : :
1045 [ # # ]: 0 : if (!link->routing_policy_rules_configured)
1046 : 0 : return;
1047 : :
1048 [ # # # # ]: 0 : if (link_has_carrier(link) || !link->network->configure_without_carrier) {
1049 : :
1050 [ # # # # : 0 : if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !(link->ipv4ll_address && link->ipv4ll_route))
# # ]
1051 : 0 : return;
1052 : :
1053 [ # # # # ]: 0 : if (link_ipv6ll_enabled(link) &&
1054 : 0 : in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address))
1055 : 0 : return;
1056 : :
1057 [ # # # # ]: 0 : if ((link_dhcp4_enabled(link) || link_dhcp6_enabled(link)) &&
1058 [ # # ]: 0 : !link->dhcp4_configured &&
1059 [ # # ]: 0 : !link->dhcp6_configured &&
1060 [ # # # # : 0 : !(link_ipv4ll_enabled(link, ADDRESS_FAMILY_FALLBACK_IPV4) && link->ipv4ll_address && link->ipv4ll_route))
# # ]
1061 : : /* When DHCP is enabled, at least one protocol must provide an address, or
1062 : : * an IPv4ll fallback address must be configured. */
1063 : 0 : return;
1064 : :
1065 [ # # # # ]: 0 : if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
1066 : 0 : return;
1067 : : }
1068 : :
1069 [ # # ]: 0 : if (link->state != LINK_STATE_CONFIGURED)
1070 : 0 : link_enter_configured(link);
1071 : :
1072 : 0 : return;
1073 : : }
1074 : :
1075 : 0 : static int link_request_set_neighbors(Link *link) {
1076 : : Neighbor *neighbor;
1077 : : int r;
1078 : :
1079 [ # # ]: 0 : assert(link);
1080 [ # # ]: 0 : assert(link->network);
1081 [ # # ]: 0 : assert(link->state != _LINK_STATE_INVALID);
1082 : :
1083 : 0 : link->neighbors_configured = false;
1084 : :
1085 [ # # ]: 0 : LIST_FOREACH(neighbors, neighbor, link->network->neighbors) {
1086 : 0 : r = neighbor_configure(neighbor, link, NULL);
1087 [ # # ]: 0 : if (r < 0)
1088 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set neighbor: %m");
1089 : : }
1090 : :
1091 [ # # ]: 0 : if (link->neighbor_messages == 0) {
1092 : 0 : link->neighbors_configured = true;
1093 : 0 : link_check_ready(link);
1094 : : } else {
1095 [ # # # # ]: 0 : log_link_debug(link, "Setting neighbors");
1096 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
1097 : : }
1098 : :
1099 : 0 : return 0;
1100 : : }
1101 : :
1102 : 0 : static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1103 : : int r;
1104 : :
1105 [ # # ]: 0 : assert(rtnl);
1106 [ # # ]: 0 : assert(m);
1107 [ # # ]: 0 : assert(link);
1108 [ # # ]: 0 : assert(link->ifname);
1109 [ # # ]: 0 : assert(link->address_messages > 0);
1110 [ # # # # ]: 0 : assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
1111 : : LINK_STATE_FAILED, LINK_STATE_LINGER));
1112 : :
1113 : 0 : link->address_messages--;
1114 : :
1115 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1116 : 0 : return 1;
1117 : :
1118 : 0 : r = sd_netlink_message_get_errno(m);
1119 [ # # # # ]: 0 : if (r < 0 && r != -EEXIST) {
1120 [ # # # # ]: 0 : log_link_warning_errno(link, r, "could not set address: %m");
1121 : 0 : link_enter_failed(link);
1122 : 0 : return 1;
1123 [ # # ]: 0 : } else if (r >= 0)
1124 : 0 : (void) manager_rtnl_process_address(rtnl, m, link->manager);
1125 : :
1126 [ # # ]: 0 : if (link->address_messages == 0) {
1127 [ # # # # ]: 0 : log_link_debug(link, "Addresses set");
1128 : 0 : link->addresses_configured = true;
1129 : 0 : link_check_ready(link);
1130 : : }
1131 : :
1132 : 0 : return 1;
1133 : : }
1134 : :
1135 : 0 : static int link_set_bridge_fdb(Link *link) {
1136 : : FdbEntry *fdb_entry;
1137 : : int r;
1138 : :
1139 [ # # ]: 0 : LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
1140 : 0 : r = fdb_entry_configure(link, fdb_entry);
1141 [ # # ]: 0 : if (r < 0)
1142 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
1143 : : }
1144 : :
1145 : 0 : return 0;
1146 : : }
1147 : :
1148 : 0 : static int link_request_set_addresses(Link *link) {
1149 : : AddressLabel *label;
1150 : : Address *ad;
1151 : : int r;
1152 : :
1153 [ # # ]: 0 : assert(link);
1154 [ # # ]: 0 : assert(link->network);
1155 [ # # ]: 0 : assert(link->state != _LINK_STATE_INVALID);
1156 : :
1157 : : /* Reset all *_configured flags we are configuring. */
1158 : 0 : link->addresses_configured = false;
1159 : 0 : link->addresses_ready = false;
1160 : 0 : link->neighbors_configured = false;
1161 : 0 : link->static_routes_configured = false;
1162 : 0 : link->routing_policy_rules_configured = false;
1163 : :
1164 : 0 : r = link_set_bridge_fdb(link);
1165 [ # # ]: 0 : if (r < 0)
1166 : 0 : return r;
1167 : :
1168 : 0 : r = link_request_set_neighbors(link);
1169 [ # # ]: 0 : if (r < 0)
1170 : 0 : return r;
1171 : :
1172 [ # # ]: 0 : LIST_FOREACH(addresses, ad, link->network->static_addresses) {
1173 : : bool update;
1174 : :
1175 : 0 : update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
1176 : :
1177 : 0 : r = address_configure(ad, link, address_handler, update);
1178 [ # # ]: 0 : if (r < 0)
1179 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set addresses: %m");
1180 [ # # ]: 0 : if (r > 0)
1181 : 0 : link->address_messages++;
1182 : : }
1183 : :
1184 [ # # ]: 0 : LIST_FOREACH(labels, label, link->network->address_labels) {
1185 : 0 : r = address_label_configure(label, link, NULL, false);
1186 [ # # ]: 0 : if (r < 0)
1187 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set address label: %m");
1188 : :
1189 : 0 : link->address_label_messages++;
1190 : : }
1191 : :
1192 : : /* now that we can figure out a default address for the dhcp server,
1193 : : start it */
1194 [ # # # # ]: 0 : if (link_dhcp4_server_enabled(link) && (link->flags & IFF_UP)) {
1195 : 0 : r = dhcp4_server_configure(link);
1196 [ # # ]: 0 : if (r < 0)
1197 : 0 : return r;
1198 [ # # # # ]: 0 : log_link_debug(link, "Offering DHCPv4 leases");
1199 : : }
1200 : :
1201 [ # # ]: 0 : if (link->address_messages == 0) {
1202 : 0 : link->addresses_configured = true;
1203 : 0 : link_check_ready(link);
1204 : : } else {
1205 [ # # # # ]: 0 : log_link_debug(link, "Setting addresses");
1206 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
1207 : : }
1208 : :
1209 : 0 : return 0;
1210 : : }
1211 : :
1212 : 0 : static int link_set_bridge_vlan(Link *link) {
1213 : : int r;
1214 : :
1215 : 0 : r = br_vlan_configure(link, link->network->pvid, link->network->br_vid_bitmap, link->network->br_untagged_bitmap);
1216 [ # # ]: 0 : if (r < 0)
1217 [ # # # # ]: 0 : log_link_error_errno(link, r, "Failed to assign VLANs to bridge port: %m");
1218 : :
1219 : 0 : return r;
1220 : : }
1221 : :
1222 : 0 : static int link_set_proxy_arp(Link *link) {
1223 : : int r;
1224 : :
1225 [ # # ]: 0 : if (!link_proxy_arp_enabled(link))
1226 : 0 : return 0;
1227 : :
1228 : 0 : r = sysctl_write_ip_property_boolean(AF_INET, link->ifname, "proxy_arp", link->network->proxy_arp > 0);
1229 [ # # ]: 0 : if (r < 0)
1230 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
1231 : :
1232 : 0 : return 0;
1233 : : }
1234 : :
1235 : : static int link_configure_after_setting_mtu(Link *link);
1236 : :
1237 : 0 : static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1238 : : int r;
1239 : :
1240 [ # # ]: 0 : assert(m);
1241 [ # # ]: 0 : assert(link);
1242 [ # # ]: 0 : assert(link->ifname);
1243 : :
1244 : 0 : link->setting_mtu = false;
1245 : :
1246 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1247 : 0 : return 1;
1248 : :
1249 : 0 : r = sd_netlink_message_get_errno(m);
1250 [ # # ]: 0 : if (r < 0)
1251 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not set MTU, ignoring: %m");
1252 : : else
1253 [ # # # # ]: 0 : log_link_debug(link, "Setting MTU done.");
1254 : :
1255 [ # # ]: 0 : if (link->state == LINK_STATE_INITIALIZED) {
1256 : 0 : r = link_configure_after_setting_mtu(link);
1257 [ # # ]: 0 : if (r < 0)
1258 : 0 : link_enter_failed(link);
1259 : : }
1260 : :
1261 : 0 : return 1;
1262 : : }
1263 : :
1264 : 0 : int link_set_mtu(Link *link, uint32_t mtu) {
1265 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1266 : : int r;
1267 : :
1268 [ # # ]: 0 : assert(link);
1269 [ # # ]: 0 : assert(link->manager);
1270 [ # # ]: 0 : assert(link->manager->rtnl);
1271 : :
1272 [ # # # # ]: 0 : if (mtu == 0 || link->setting_mtu)
1273 : 0 : return 0;
1274 : :
1275 [ # # ]: 0 : if (link->mtu == mtu)
1276 : 0 : return 0;
1277 : :
1278 [ # # # # ]: 0 : log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
1279 : :
1280 : 0 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1281 [ # # ]: 0 : if (r < 0)
1282 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1283 : :
1284 : : /* If IPv6 not configured (no static IPv6 address and IPv6LL autoconfiguration is disabled)
1285 : : * for this interface, then disable IPv6 else enable it. */
1286 : 0 : (void) link_enable_ipv6(link);
1287 : :
1288 : : /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
1289 : : * on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
1290 [ # # # # ]: 0 : if (link_ipv6_enabled(link) && mtu < IPV6_MIN_MTU) {
1291 : :
1292 [ # # # # ]: 0 : log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as "
1293 : : "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m");
1294 : :
1295 : 0 : mtu = IPV6_MIN_MTU;
1296 : : }
1297 : :
1298 : 0 : r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
1299 [ # # ]: 0 : if (r < 0)
1300 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not append MTU: %m");
1301 : :
1302 : 0 : r = netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
1303 : : link_netlink_destroy_callback, link);
1304 [ # # ]: 0 : if (r < 0)
1305 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1306 : :
1307 : 0 : link_ref(link);
1308 : 0 : link->setting_mtu = true;
1309 : :
1310 : 0 : return 0;
1311 : : }
1312 : :
1313 : 0 : static bool link_reduces_vlan_mtu(Link *link) {
1314 : : /* See netif_reduces_vlan_mtu() in kernel. */
1315 : 0 : return streq_ptr(link->kind, "macsec");
1316 : : }
1317 : :
1318 : 0 : static uint32_t link_get_requested_mtu_by_stacked_netdevs(Link *link) {
1319 : 0 : uint32_t mtu = 0;
1320 : : NetDev *dev;
1321 : : Iterator i;
1322 : :
1323 [ # # ]: 0 : HASHMAP_FOREACH(dev, link->network->stacked_netdevs, i)
1324 [ # # # # ]: 0 : if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0)
1325 : : /* See vlan_dev_change_mtu() in kernel. */
1326 [ # # ]: 0 : mtu = MAX(mtu, link_reduces_vlan_mtu(link) ? dev->mtu + 4 : dev->mtu);
1327 : :
1328 [ # # # # ]: 0 : else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu)
1329 : : /* See macvlan_change_mtu() in kernel. */
1330 : 0 : mtu = dev->mtu;
1331 : :
1332 : 0 : return mtu;
1333 : : }
1334 : :
1335 : 0 : static int link_configure_mtu(Link *link) {
1336 : : uint32_t mtu;
1337 : :
1338 [ # # ]: 0 : assert(link);
1339 [ # # ]: 0 : assert(link->network);
1340 : :
1341 [ # # ]: 0 : if (link->network->mtu > 0)
1342 : 0 : return link_set_mtu(link, link->network->mtu);
1343 : :
1344 : 0 : mtu = link_get_requested_mtu_by_stacked_netdevs(link);
1345 [ # # ]: 0 : if (link->mtu >= mtu)
1346 : 0 : return 0;
1347 : :
1348 [ # # # # ]: 0 : log_link_notice(link, "Bumping MTU bytes from %"PRIu32" to %"PRIu32" because of stacked device. "
1349 : : "If it is not desired, then please explicitly specify MTUBytes= setting.",
1350 : : link->mtu, mtu);
1351 : :
1352 : 0 : return link_set_mtu(link, mtu);
1353 : : }
1354 : :
1355 : 0 : static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1356 : : int r;
1357 : :
1358 [ # # ]: 0 : assert(m);
1359 [ # # ]: 0 : assert(link);
1360 [ # # ]: 0 : assert(link->ifname);
1361 : :
1362 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1363 : 0 : return 1;
1364 : :
1365 : 0 : r = sd_netlink_message_get_errno(m);
1366 [ # # ]: 0 : if (r < 0)
1367 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not set link flags, ignoring: %m");
1368 : :
1369 : 0 : return 1;
1370 : : }
1371 : :
1372 : 0 : static int link_set_flags(Link *link) {
1373 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1374 : 0 : unsigned ifi_change = 0;
1375 : 0 : unsigned ifi_flags = 0;
1376 : : int r;
1377 : :
1378 [ # # ]: 0 : assert(link);
1379 [ # # ]: 0 : assert(link->manager);
1380 [ # # ]: 0 : assert(link->manager->rtnl);
1381 : :
1382 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
1383 : 0 : return 0;
1384 : :
1385 [ # # ]: 0 : if (!link->network)
1386 : 0 : return 0;
1387 : :
1388 [ # # # # : 0 : if (link->network->arp < 0 && link->network->multicast < 0 && link->network->allmulticast < 0)
# # ]
1389 : 0 : return 0;
1390 : :
1391 : 0 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1392 [ # # ]: 0 : if (r < 0)
1393 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1394 : :
1395 [ # # ]: 0 : if (link->network->arp >= 0) {
1396 : 0 : ifi_change |= IFF_NOARP;
1397 [ # # ]: 0 : SET_FLAG(ifi_flags, IFF_NOARP, link->network->arp == 0);
1398 : : }
1399 : :
1400 [ # # ]: 0 : if (link->network->multicast >= 0) {
1401 : 0 : ifi_change |= IFF_MULTICAST;
1402 [ # # ]: 0 : SET_FLAG(ifi_flags, IFF_MULTICAST, link->network->multicast);
1403 : : }
1404 : :
1405 [ # # ]: 0 : if (link->network->allmulticast >= 0) {
1406 : 0 : ifi_change |= IFF_ALLMULTI;
1407 [ # # ]: 0 : SET_FLAG(ifi_flags, IFF_ALLMULTI, link->network->allmulticast);
1408 : : }
1409 : :
1410 : 0 : r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change);
1411 [ # # ]: 0 : if (r < 0)
1412 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not set link flags: %m");
1413 : :
1414 : 0 : r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
1415 : : link_netlink_destroy_callback, link);
1416 [ # # ]: 0 : if (r < 0)
1417 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1418 : :
1419 : 0 : link_ref(link);
1420 : :
1421 : 0 : return 0;
1422 : : }
1423 : :
1424 : 0 : static int link_acquire_ipv6_conf(Link *link) {
1425 : : int r;
1426 : :
1427 [ # # ]: 0 : assert(link);
1428 : :
1429 [ # # ]: 0 : if (link_ipv6_accept_ra_enabled(link)) {
1430 [ # # ]: 0 : assert(link->ndisc);
1431 : :
1432 [ # # # # ]: 0 : log_link_debug(link, "Discovering IPv6 routers");
1433 : :
1434 : 0 : r = sd_ndisc_start(link->ndisc);
1435 [ # # # # ]: 0 : if (r < 0 && r != -EBUSY)
1436 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
1437 : : }
1438 : :
1439 [ # # ]: 0 : if (link_radv_enabled(link)) {
1440 [ # # ]: 0 : assert(link->radv);
1441 [ # # ]: 0 : assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
1442 : :
1443 [ # # # # ]: 0 : log_link_debug(link, "Starting IPv6 Router Advertisements");
1444 : :
1445 : 0 : r = sd_radv_start(link->radv);
1446 [ # # # # ]: 0 : if (r < 0 && r != -EBUSY)
1447 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
1448 : : }
1449 : :
1450 : 0 : (void) dhcp6_request_prefix_delegation(link);
1451 : :
1452 : 0 : return 0;
1453 : : }
1454 : :
1455 : 0 : static int link_acquire_ipv4_conf(Link *link) {
1456 : : int r;
1457 : :
1458 [ # # ]: 0 : assert(link);
1459 [ # # ]: 0 : assert(link->manager);
1460 [ # # ]: 0 : assert(link->manager->event);
1461 : :
1462 [ # # ]: 0 : if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4)) {
1463 [ # # ]: 0 : assert(link->ipv4ll);
1464 : :
1465 [ # # # # ]: 0 : log_link_debug(link, "Acquiring IPv4 link-local address");
1466 : :
1467 : 0 : r = sd_ipv4ll_start(link->ipv4ll);
1468 [ # # ]: 0 : if (r < 0)
1469 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1470 : : }
1471 : :
1472 [ # # ]: 0 : if (link_dhcp4_enabled(link)) {
1473 [ # # ]: 0 : assert(link->dhcp_client);
1474 : :
1475 [ # # # # ]: 0 : log_link_debug(link, "Acquiring DHCPv4 lease");
1476 : :
1477 : 0 : r = sd_dhcp_client_start(link->dhcp_client);
1478 [ # # ]: 0 : if (r < 0)
1479 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
1480 : : }
1481 : :
1482 : 0 : return 0;
1483 : : }
1484 : :
1485 : 0 : static int link_acquire_conf(Link *link) {
1486 : : int r;
1487 : :
1488 [ # # ]: 0 : assert(link);
1489 : :
1490 : 0 : r = link_acquire_ipv4_conf(link);
1491 [ # # ]: 0 : if (r < 0)
1492 : 0 : return r;
1493 : :
1494 [ # # ]: 0 : if (!in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) {
1495 : 0 : r = link_acquire_ipv6_conf(link);
1496 [ # # ]: 0 : if (r < 0)
1497 : 0 : return r;
1498 : : }
1499 : :
1500 [ # # ]: 0 : if (link_lldp_emit_enabled(link)) {
1501 : 0 : r = link_lldp_emit_start(link);
1502 [ # # ]: 0 : if (r < 0)
1503 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Failed to start LLDP transmission: %m");
1504 : : }
1505 : :
1506 : 0 : return 0;
1507 : : }
1508 : :
1509 : 84 : bool link_has_carrier(Link *link) {
1510 : : /* see Documentation/networking/operstates.txt in the kernel sources */
1511 : :
1512 [ + + ]: 84 : if (link->kernel_operstate == IF_OPER_UP)
1513 : 12 : return true;
1514 : :
1515 [ + + ]: 72 : if (link->kernel_operstate == IF_OPER_UNKNOWN)
1516 : : /* operstate may not be implemented, so fall back to flags */
1517 [ + - ]: 36 : if (FLAGS_SET(link->flags, IFF_LOWER_UP | IFF_RUNNING) &&
1518 [ + - ]: 36 : !FLAGS_SET(link->flags, IFF_DORMANT))
1519 : 36 : return true;
1520 : :
1521 : 36 : return false;
1522 : : }
1523 : :
1524 : 0 : static int link_address_genmode_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1525 : : int r;
1526 : :
1527 [ # # ]: 0 : assert(link);
1528 : :
1529 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1530 : 0 : return 1;
1531 : :
1532 : 0 : r = sd_netlink_message_get_errno(m);
1533 [ # # ]: 0 : if (r < 0)
1534 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not set address genmode for interface, ignoring: %m");
1535 : :
1536 : 0 : return 1;
1537 : : }
1538 : :
1539 : 0 : static int link_configure_addrgen_mode(Link *link) {
1540 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1541 : : uint8_t ipv6ll_mode;
1542 : : int r;
1543 : :
1544 [ # # ]: 0 : assert(link);
1545 [ # # ]: 0 : assert(link->network);
1546 [ # # ]: 0 : assert(link->manager);
1547 [ # # ]: 0 : assert(link->manager->rtnl);
1548 : :
1549 [ # # ]: 0 : if (!socket_ipv6_is_supported())
1550 : 0 : return 0;
1551 : :
1552 [ # # # # ]: 0 : log_link_debug(link, "Setting address genmode for link");
1553 : :
1554 : 0 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1555 [ # # ]: 0 : if (r < 0)
1556 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1557 : :
1558 : 0 : r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
1559 [ # # ]: 0 : if (r < 0)
1560 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
1561 : :
1562 : 0 : r = sd_netlink_message_open_container(req, AF_INET6);
1563 [ # # ]: 0 : if (r < 0)
1564 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
1565 : :
1566 [ # # ]: 0 : if (!link_ipv6ll_enabled(link))
1567 : 0 : ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
1568 [ # # ]: 0 : else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
1569 : : /* The file may not exist. And event if it exists, when stable_secret is unset,
1570 : : * reading the file fails with EIO. */
1571 : 0 : ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
1572 : : else
1573 : 0 : ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
1574 : :
1575 : 0 : r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
1576 [ # # ]: 0 : if (r < 0)
1577 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
1578 : :
1579 : 0 : r = sd_netlink_message_close_container(req);
1580 [ # # ]: 0 : if (r < 0)
1581 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
1582 : :
1583 : 0 : r = sd_netlink_message_close_container(req);
1584 [ # # ]: 0 : if (r < 0)
1585 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
1586 : :
1587 : 0 : r = netlink_call_async(link->manager->rtnl, NULL, req, link_address_genmode_handler,
1588 : : link_netlink_destroy_callback, link);
1589 [ # # ]: 0 : if (r < 0)
1590 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1591 : :
1592 : 0 : link_ref(link);
1593 : :
1594 : 0 : return 0;
1595 : : }
1596 : :
1597 : 0 : static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1598 : : int r;
1599 : :
1600 [ # # ]: 0 : assert(link);
1601 : :
1602 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1603 : 0 : return 1;
1604 : :
1605 : 0 : r = sd_netlink_message_get_errno(m);
1606 [ # # ]: 0 : if (r < 0)
1607 : : /* we warn but don't fail the link, as it may be brought up later */
1608 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not bring up interface: %m");
1609 : :
1610 : 0 : return 1;
1611 : : }
1612 : :
1613 : 0 : static int link_up(Link *link) {
1614 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1615 : : int r;
1616 : :
1617 [ # # ]: 0 : assert(link);
1618 [ # # ]: 0 : assert(link->network);
1619 [ # # ]: 0 : assert(link->manager);
1620 [ # # ]: 0 : assert(link->manager->rtnl);
1621 : :
1622 [ # # # # ]: 0 : log_link_debug(link, "Bringing link up");
1623 : :
1624 : 0 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1625 [ # # ]: 0 : if (r < 0)
1626 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1627 : :
1628 : : /* set it free if not enslaved with networkd */
1629 [ # # # # : 0 : if (!link->network->bridge && !link->network->bond && !link->network->vrf) {
# # ]
1630 : 0 : r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
1631 [ # # ]: 0 : if (r < 0)
1632 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
1633 : : }
1634 : :
1635 : 0 : r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1636 [ # # ]: 0 : if (r < 0)
1637 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not set link flags: %m");
1638 : :
1639 [ # # ]: 0 : if (link->network->mac) {
1640 : 0 : r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1641 [ # # ]: 0 : if (r < 0)
1642 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not set MAC address: %m");
1643 : : }
1644 : :
1645 : 0 : r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
1646 : : link_netlink_destroy_callback, link);
1647 [ # # ]: 0 : if (r < 0)
1648 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1649 : :
1650 : 0 : link_ref(link);
1651 : :
1652 : 0 : return 0;
1653 : : }
1654 : :
1655 : 0 : static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
1656 : : int r;
1657 : :
1658 [ # # ]: 0 : assert(link);
1659 : :
1660 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1661 : 0 : return 1;
1662 : :
1663 : 0 : r = sd_netlink_message_get_errno(m);
1664 [ # # ]: 0 : if (r < 0)
1665 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not bring down interface: %m");
1666 : :
1667 : 0 : return 1;
1668 : : }
1669 : :
1670 : 0 : int link_down(Link *link, link_netlink_message_handler_t callback) {
1671 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1672 : : int r;
1673 : :
1674 [ # # ]: 0 : assert(link);
1675 [ # # ]: 0 : assert(link->manager);
1676 [ # # ]: 0 : assert(link->manager->rtnl);
1677 : :
1678 [ # # # # ]: 0 : log_link_debug(link, "Bringing link down");
1679 : :
1680 : 0 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1681 : : RTM_SETLINK, link->ifindex);
1682 [ # # ]: 0 : if (r < 0)
1683 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1684 : :
1685 : 0 : r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
1686 [ # # ]: 0 : if (r < 0)
1687 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not set link flags: %m");
1688 : :
1689 [ # # ]: 0 : r = netlink_call_async(link->manager->rtnl, NULL, req,
1690 : : callback ?: link_down_handler,
1691 : : link_netlink_destroy_callback, link);
1692 [ # # ]: 0 : if (r < 0)
1693 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1694 : :
1695 : 0 : link_ref(link);
1696 : :
1697 : 0 : return 0;
1698 : : }
1699 : :
1700 : 0 : static int link_handle_bound_to_list(Link *link) {
1701 : : Link *l;
1702 : : Iterator i;
1703 : : int r;
1704 : 0 : bool required_up = false;
1705 : 0 : bool link_is_up = false;
1706 : :
1707 [ # # ]: 0 : assert(link);
1708 : :
1709 [ # # ]: 0 : if (hashmap_isempty(link->bound_to_links))
1710 : 0 : return 0;
1711 : :
1712 [ # # ]: 0 : if (link->flags & IFF_UP)
1713 : 0 : link_is_up = true;
1714 : :
1715 [ # # ]: 0 : HASHMAP_FOREACH (l, link->bound_to_links, i)
1716 [ # # ]: 0 : if (link_has_carrier(l)) {
1717 : 0 : required_up = true;
1718 : 0 : break;
1719 : : }
1720 : :
1721 [ # # # # ]: 0 : if (!required_up && link_is_up) {
1722 : 0 : r = link_down(link, NULL);
1723 [ # # ]: 0 : if (r < 0)
1724 : 0 : return r;
1725 [ # # # # ]: 0 : } else if (required_up && !link_is_up) {
1726 : 0 : r = link_up(link);
1727 [ # # ]: 0 : if (r < 0)
1728 : 0 : return r;
1729 : : }
1730 : :
1731 : 0 : return 0;
1732 : : }
1733 : :
1734 : 0 : static int link_handle_bound_by_list(Link *link) {
1735 : : Iterator i;
1736 : : Link *l;
1737 : : int r;
1738 : :
1739 [ # # ]: 0 : assert(link);
1740 : :
1741 [ # # ]: 0 : if (hashmap_isempty(link->bound_by_links))
1742 : 0 : return 0;
1743 : :
1744 [ # # ]: 0 : HASHMAP_FOREACH (l, link->bound_by_links, i) {
1745 : 0 : r = link_handle_bound_to_list(l);
1746 [ # # ]: 0 : if (r < 0)
1747 : 0 : return r;
1748 : : }
1749 : :
1750 : 0 : return 0;
1751 : : }
1752 : :
1753 : 0 : static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1754 : : int r;
1755 : :
1756 [ # # ]: 0 : assert(link);
1757 [ # # ]: 0 : assert(carrier);
1758 : :
1759 [ # # ]: 0 : if (link == carrier)
1760 : 0 : return 0;
1761 : :
1762 [ # # ]: 0 : if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1763 : 0 : return 0;
1764 : :
1765 : 0 : r = hashmap_ensure_allocated(h, NULL);
1766 [ # # ]: 0 : if (r < 0)
1767 : 0 : return r;
1768 : :
1769 : 0 : r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1770 [ # # ]: 0 : if (r < 0)
1771 : 0 : return r;
1772 : :
1773 : 0 : return 0;
1774 : : }
1775 : :
1776 : 0 : static int link_new_bound_by_list(Link *link) {
1777 : : Manager *m;
1778 : : Link *carrier;
1779 : : Iterator i;
1780 : : int r;
1781 : 0 : bool list_updated = false;
1782 : :
1783 [ # # ]: 0 : assert(link);
1784 [ # # ]: 0 : assert(link->manager);
1785 : :
1786 : 0 : m = link->manager;
1787 : :
1788 [ # # ]: 0 : HASHMAP_FOREACH(carrier, m->links, i) {
1789 [ # # ]: 0 : if (!carrier->network)
1790 : 0 : continue;
1791 : :
1792 [ # # ]: 0 : if (strv_isempty(carrier->network->bind_carrier))
1793 : 0 : continue;
1794 : :
1795 [ # # ]: 0 : if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1796 : 0 : r = link_put_carrier(link, carrier, &link->bound_by_links);
1797 [ # # ]: 0 : if (r < 0)
1798 : 0 : return r;
1799 : :
1800 : 0 : list_updated = true;
1801 : : }
1802 : : }
1803 : :
1804 [ # # ]: 0 : if (list_updated)
1805 : 0 : link_dirty(link);
1806 : :
1807 [ # # ]: 0 : HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
1808 : 0 : r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1809 [ # # ]: 0 : if (r < 0)
1810 : 0 : return r;
1811 : :
1812 : 0 : link_dirty(carrier);
1813 : : }
1814 : :
1815 : 0 : return 0;
1816 : : }
1817 : :
1818 : 0 : static int link_new_bound_to_list(Link *link) {
1819 : : Manager *m;
1820 : : Link *carrier;
1821 : : Iterator i;
1822 : : int r;
1823 : 0 : bool list_updated = false;
1824 : :
1825 [ # # ]: 0 : assert(link);
1826 [ # # ]: 0 : assert(link->manager);
1827 : :
1828 [ # # ]: 0 : if (!link->network)
1829 : 0 : return 0;
1830 : :
1831 [ # # ]: 0 : if (strv_isempty(link->network->bind_carrier))
1832 : 0 : return 0;
1833 : :
1834 : 0 : m = link->manager;
1835 : :
1836 [ # # ]: 0 : HASHMAP_FOREACH (carrier, m->links, i) {
1837 [ # # ]: 0 : if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1838 : 0 : r = link_put_carrier(link, carrier, &link->bound_to_links);
1839 [ # # ]: 0 : if (r < 0)
1840 : 0 : return r;
1841 : :
1842 : 0 : list_updated = true;
1843 : : }
1844 : : }
1845 : :
1846 [ # # ]: 0 : if (list_updated)
1847 : 0 : link_dirty(link);
1848 : :
1849 [ # # ]: 0 : HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1850 : 0 : r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1851 [ # # ]: 0 : if (r < 0)
1852 : 0 : return r;
1853 : :
1854 : 0 : link_dirty(carrier);
1855 : : }
1856 : :
1857 : 0 : return 0;
1858 : : }
1859 : :
1860 : 0 : static int link_new_carrier_maps(Link *link) {
1861 : : int r;
1862 : :
1863 : 0 : r = link_new_bound_by_list(link);
1864 [ # # ]: 0 : if (r < 0)
1865 : 0 : return r;
1866 : :
1867 : 0 : r = link_handle_bound_by_list(link);
1868 [ # # ]: 0 : if (r < 0)
1869 : 0 : return r;
1870 : :
1871 : 0 : r = link_new_bound_to_list(link);
1872 [ # # ]: 0 : if (r < 0)
1873 : 0 : return r;
1874 : :
1875 : 0 : r = link_handle_bound_to_list(link);
1876 [ # # ]: 0 : if (r < 0)
1877 : 0 : return r;
1878 : :
1879 : 0 : return 0;
1880 : : }
1881 : :
1882 : 0 : static void link_free_bound_to_list(Link *link) {
1883 : : Link *bound_to;
1884 : : Iterator i;
1885 : :
1886 [ # # ]: 0 : HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1887 : 0 : hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1888 : :
1889 [ # # ]: 0 : if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
1890 : 0 : link_dirty(bound_to);
1891 : : }
1892 : :
1893 : 0 : return;
1894 : : }
1895 : :
1896 : 0 : static void link_free_bound_by_list(Link *link) {
1897 : : Link *bound_by;
1898 : : Iterator i;
1899 : :
1900 [ # # ]: 0 : HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1901 : 0 : hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1902 : :
1903 [ # # ]: 0 : if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
1904 : 0 : link_dirty(bound_by);
1905 : 0 : link_handle_bound_to_list(bound_by);
1906 : : }
1907 : : }
1908 : :
1909 : 0 : return;
1910 : : }
1911 : :
1912 : 0 : static void link_free_carrier_maps(Link *link) {
1913 : 0 : bool list_updated = false;
1914 : :
1915 [ # # ]: 0 : assert(link);
1916 : :
1917 [ # # ]: 0 : if (!hashmap_isempty(link->bound_to_links)) {
1918 : 0 : link_free_bound_to_list(link);
1919 : 0 : list_updated = true;
1920 : : }
1921 : :
1922 [ # # ]: 0 : if (!hashmap_isempty(link->bound_by_links)) {
1923 : 0 : link_free_bound_by_list(link);
1924 : 0 : list_updated = true;
1925 : : }
1926 : :
1927 [ # # ]: 0 : if (list_updated)
1928 : 0 : link_dirty(link);
1929 : :
1930 : 0 : return;
1931 : : }
1932 : :
1933 : 0 : static int link_append_to_master(Link *link, NetDev *netdev) {
1934 : : Link *master;
1935 : : int r;
1936 : :
1937 [ # # ]: 0 : assert(link);
1938 [ # # ]: 0 : assert(netdev);
1939 : :
1940 : 0 : r = link_get(link->manager, netdev->ifindex, &master);
1941 [ # # ]: 0 : if (r < 0)
1942 : 0 : return r;
1943 : :
1944 : 0 : r = set_ensure_allocated(&master->slaves, NULL);
1945 [ # # ]: 0 : if (r < 0)
1946 : 0 : return r;
1947 : :
1948 : 0 : r = set_put(master->slaves, link);
1949 [ # # ]: 0 : if (r < 0)
1950 : 0 : return r;
1951 [ # # ]: 0 : if (r == 0)
1952 : 0 : return 0;
1953 : :
1954 : 0 : link_ref(link);
1955 : 0 : return 0;
1956 : : }
1957 : :
1958 : 0 : static void link_drop_from_master(Link *link, NetDev *netdev) {
1959 : : Link *master;
1960 : :
1961 [ # # ]: 0 : assert(link);
1962 : :
1963 [ # # # # ]: 0 : if (!link->manager || !netdev)
1964 : 0 : return;
1965 : :
1966 [ # # ]: 0 : if (link_get(link->manager, netdev->ifindex, &master) < 0)
1967 : 0 : return;
1968 : :
1969 : 0 : link_unref(set_remove(master->slaves, link));
1970 : : }
1971 : :
1972 : 0 : static void link_detach_from_manager(Link *link) {
1973 [ # # # # ]: 0 : if (!link || !link->manager)
1974 : 0 : return;
1975 : :
1976 : 0 : link_unref(set_remove(link->manager->links_requesting_uuid, link));
1977 : 0 : link_clean(link);
1978 : :
1979 : : /* The following must be called at last. */
1980 [ # # ]: 0 : assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
1981 : 0 : link_unref(link);
1982 : : }
1983 : :
1984 : 0 : void link_drop(Link *link) {
1985 [ # # # # ]: 0 : if (!link || link->state == LINK_STATE_LINGER)
1986 : 0 : return;
1987 : :
1988 : 0 : link_set_state(link, LINK_STATE_LINGER);
1989 : :
1990 : 0 : link_free_carrier_maps(link);
1991 : :
1992 [ # # ]: 0 : if (link->network) {
1993 : 0 : link_drop_from_master(link, link->network->bridge);
1994 : 0 : link_drop_from_master(link, link->network->bond);
1995 : : }
1996 : :
1997 [ # # # # ]: 0 : log_link_debug(link, "Link removed");
1998 : :
1999 : 0 : (void) unlink(link->state_file);
2000 : 0 : link_detach_from_manager(link);
2001 : : }
2002 : :
2003 : 0 : static int link_joined(Link *link) {
2004 : : int r;
2005 : :
2006 [ # # ]: 0 : assert(link);
2007 [ # # ]: 0 : assert(link->network);
2008 : :
2009 [ # # ]: 0 : if (!hashmap_isempty(link->bound_to_links)) {
2010 : 0 : r = link_handle_bound_to_list(link);
2011 [ # # ]: 0 : if (r < 0)
2012 : 0 : return r;
2013 [ # # ]: 0 : } else if (!(link->flags & IFF_UP)) {
2014 : 0 : r = link_up(link);
2015 [ # # ]: 0 : if (r < 0) {
2016 : 0 : link_enter_failed(link);
2017 : 0 : return r;
2018 : : }
2019 : : }
2020 : :
2021 [ # # ]: 0 : if (link->network->bridge) {
2022 : 0 : r = link_set_bridge(link);
2023 [ # # ]: 0 : if (r < 0)
2024 [ # # # # ]: 0 : log_link_error_errno(link, r, "Could not set bridge message: %m");
2025 : :
2026 : 0 : r = link_append_to_master(link, link->network->bridge);
2027 [ # # ]: 0 : if (r < 0)
2028 [ # # # # ]: 0 : log_link_error_errno(link, r, "Failed to add to bridge master's slave list: %m");
2029 : : }
2030 : :
2031 [ # # ]: 0 : if (link->network->bond) {
2032 : 0 : r = link_set_bond(link);
2033 [ # # ]: 0 : if (r < 0)
2034 [ # # # # ]: 0 : log_link_error_errno(link, r, "Could not set bond message: %m");
2035 : :
2036 : 0 : r = link_append_to_master(link, link->network->bond);
2037 [ # # ]: 0 : if (r < 0)
2038 [ # # # # ]: 0 : log_link_error_errno(link, r, "Failed to add to bond master's slave list: %m");
2039 : : }
2040 : :
2041 [ # # ]: 0 : if (link->network->use_br_vlan &&
2042 [ # # # # ]: 0 : (link->network->bridge || streq_ptr("bridge", link->kind))) {
2043 : 0 : r = link_set_bridge_vlan(link);
2044 [ # # ]: 0 : if (r < 0)
2045 [ # # # # ]: 0 : log_link_error_errno(link, r, "Could not set bridge vlan: %m");
2046 : : }
2047 : :
2048 : : /* Skip setting up addresses until it gets carrier,
2049 : : or it would try to set addresses twice,
2050 : : which is bad for non-idempotent steps. */
2051 [ # # # # ]: 0 : if (!link_has_carrier(link) && !link->network->configure_without_carrier)
2052 : 0 : return 0;
2053 : :
2054 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
2055 : 0 : return link_request_set_addresses(link);
2056 : : }
2057 : :
2058 : 0 : static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
2059 : : int r;
2060 : :
2061 [ # # ]: 0 : assert(link);
2062 [ # # ]: 0 : assert(link->network);
2063 [ # # ]: 0 : assert(link->enslaving > 0);
2064 : :
2065 : 0 : link->enslaving--;
2066 : :
2067 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2068 : 0 : return 1;
2069 : :
2070 : 0 : r = sd_netlink_message_get_errno(m);
2071 [ # # # # ]: 0 : if (r < 0 && r != -EEXIST) {
2072 [ # # # # ]: 0 : log_link_error_errno(link, r, "Could not join netdev: %m");
2073 : 0 : link_enter_failed(link);
2074 : 0 : return 1;
2075 : : }
2076 : :
2077 [ # # # # ]: 0 : log_link_debug(link, "Joined netdev");
2078 : :
2079 [ # # ]: 0 : if (link->enslaving == 0) {
2080 : 0 : r = link_joined(link);
2081 [ # # ]: 0 : if (r < 0)
2082 : 0 : link_enter_failed(link);
2083 : : }
2084 : :
2085 : 0 : return 1;
2086 : : }
2087 : :
2088 : 0 : static int link_enter_join_netdev(Link *link) {
2089 : : NetDev *netdev;
2090 : : Iterator i;
2091 : : int r;
2092 : :
2093 [ # # ]: 0 : assert(link);
2094 [ # # ]: 0 : assert(link->network);
2095 [ # # ]: 0 : assert(link->state == LINK_STATE_INITIALIZED);
2096 : :
2097 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
2098 : :
2099 : 0 : link_dirty(link);
2100 : 0 : link->enslaving = 0;
2101 : :
2102 [ # # ]: 0 : if (link->network->bond) {
2103 [ # # ]: 0 : if (link->network->bond->state == NETDEV_STATE_READY &&
2104 [ # # ]: 0 : link->network->bond->ifindex == link->master_ifindex)
2105 : 0 : return link_joined(link);
2106 : :
2107 : 0 : log_struct(LOG_DEBUG,
2108 : : LOG_LINK_INTERFACE(link),
2109 : : LOG_NETDEV_INTERFACE(link->network->bond),
2110 : : LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname));
2111 : :
2112 : 0 : link->enslaving++;
2113 : :
2114 : 0 : r = netdev_join(link->network->bond, link, netdev_join_handler);
2115 [ # # ]: 0 : if (r < 0) {
2116 : 0 : log_struct_errno(LOG_WARNING, r,
2117 : : LOG_LINK_INTERFACE(link),
2118 : : LOG_NETDEV_INTERFACE(link->network->bond),
2119 : : LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname));
2120 : 0 : link_enter_failed(link);
2121 : 0 : return r;
2122 : : }
2123 : : }
2124 : :
2125 [ # # ]: 0 : if (link->network->bridge) {
2126 : 0 : log_struct(LOG_DEBUG,
2127 : : LOG_LINK_INTERFACE(link),
2128 : : LOG_NETDEV_INTERFACE(link->network->bridge),
2129 : : LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname));
2130 : :
2131 : 0 : link->enslaving++;
2132 : :
2133 : 0 : r = netdev_join(link->network->bridge, link, netdev_join_handler);
2134 [ # # ]: 0 : if (r < 0) {
2135 : 0 : log_struct_errno(LOG_WARNING, r,
2136 : : LOG_LINK_INTERFACE(link),
2137 : : LOG_NETDEV_INTERFACE(link->network->bridge),
2138 : : LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname));
2139 : 0 : link_enter_failed(link);
2140 : 0 : return r;
2141 : : }
2142 : : }
2143 : :
2144 [ # # ]: 0 : if (link->network->vrf) {
2145 : 0 : log_struct(LOG_DEBUG,
2146 : : LOG_LINK_INTERFACE(link),
2147 : : LOG_NETDEV_INTERFACE(link->network->vrf),
2148 : : LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname));
2149 : :
2150 : 0 : link->enslaving++;
2151 : :
2152 : 0 : r = netdev_join(link->network->vrf, link, netdev_join_handler);
2153 [ # # ]: 0 : if (r < 0) {
2154 : 0 : log_struct_errno(LOG_WARNING, r,
2155 : : LOG_LINK_INTERFACE(link),
2156 : : LOG_NETDEV_INTERFACE(link->network->vrf),
2157 : : LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname));
2158 : 0 : link_enter_failed(link);
2159 : 0 : return r;
2160 : : }
2161 : : }
2162 : :
2163 [ # # ]: 0 : HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
2164 : :
2165 [ # # ]: 0 : if (netdev->ifindex > 0)
2166 : : /* Assume already enslaved. */
2167 : 0 : continue;
2168 : :
2169 [ # # ]: 0 : if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
2170 : 0 : continue;
2171 : :
2172 : 0 : log_struct(LOG_DEBUG,
2173 : : LOG_LINK_INTERFACE(link),
2174 : : LOG_NETDEV_INTERFACE(netdev),
2175 : : LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
2176 : :
2177 : 0 : link->enslaving++;
2178 : :
2179 : 0 : r = netdev_join(netdev, link, netdev_join_handler);
2180 [ # # ]: 0 : if (r < 0) {
2181 : 0 : log_struct_errno(LOG_WARNING, r,
2182 : : LOG_LINK_INTERFACE(link),
2183 : : LOG_NETDEV_INTERFACE(netdev),
2184 : : LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
2185 : 0 : link_enter_failed(link);
2186 : 0 : return r;
2187 : : }
2188 : : }
2189 : :
2190 [ # # ]: 0 : if (link->enslaving == 0)
2191 : 0 : return link_joined(link);
2192 : :
2193 : 0 : return 0;
2194 : : }
2195 : :
2196 : 0 : static int link_set_ipv4_forward(Link *link) {
2197 : : int r;
2198 : :
2199 [ # # ]: 0 : if (!link_ipv4_forward_enabled(link))
2200 : 0 : return 0;
2201 : :
2202 : : /* We propagate the forwarding flag from one interface to the
2203 : : * global setting one way. This means: as long as at least one
2204 : : * interface was configured at any time that had IP forwarding
2205 : : * enabled the setting will stay on for good. We do this
2206 : : * primarily to keep IPv4 and IPv6 packet forwarding behaviour
2207 : : * somewhat in sync (see below). */
2208 : :
2209 : 0 : r = sysctl_write_ip_property(AF_INET, NULL, "ip_forward", "1");
2210 [ # # ]: 0 : if (r < 0)
2211 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
2212 : :
2213 : 0 : return 0;
2214 : : }
2215 : :
2216 : 0 : static int link_set_ipv6_forward(Link *link) {
2217 : : int r;
2218 : :
2219 [ # # ]: 0 : if (!link_ipv6_forward_enabled(link))
2220 : 0 : return 0;
2221 : :
2222 : : /* On Linux, the IPv6 stack does not know a per-interface
2223 : : * packet forwarding setting: either packet forwarding is on
2224 : : * for all, or off for all. We hence don't bother with a
2225 : : * per-interface setting, but simply propagate the interface
2226 : : * flag, if it is set, to the global flag, one-way. Note that
2227 : : * while IPv4 would allow a per-interface flag, we expose the
2228 : : * same behaviour there and also propagate the setting from
2229 : : * one to all, to keep things simple (see above). */
2230 : :
2231 : 0 : r = sysctl_write_ip_property(AF_INET6, "all", "forwarding", "1");
2232 [ # # ]: 0 : if (r < 0)
2233 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
2234 : :
2235 : 0 : return 0;
2236 : : }
2237 : :
2238 : 0 : static int link_set_ipv6_privacy_extensions(Link *link) {
2239 : : IPv6PrivacyExtensions s;
2240 : : int r;
2241 : :
2242 : 0 : s = link_ipv6_privacy_extensions(link);
2243 [ # # ]: 0 : if (s < 0)
2244 : 0 : return 0;
2245 : :
2246 : 0 : r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "use_tempaddr", (int) link->network->ipv6_privacy_extensions);
2247 [ # # ]: 0 : if (r < 0)
2248 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
2249 : :
2250 : 0 : return 0;
2251 : : }
2252 : :
2253 : 0 : static int link_set_ipv6_accept_ra(Link *link) {
2254 : : int r;
2255 : :
2256 : : /* Make this a NOP if IPv6 is not available */
2257 [ # # ]: 0 : if (!socket_ipv6_is_supported())
2258 : 0 : return 0;
2259 : :
2260 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
2261 : 0 : return 0;
2262 : :
2263 [ # # ]: 0 : if (!link->network)
2264 : 0 : return 0;
2265 : :
2266 : 0 : r = sysctl_write_ip_property(AF_INET6, link->ifname, "accept_ra", "0");
2267 [ # # ]: 0 : if (r < 0)
2268 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
2269 : :
2270 : 0 : return 0;
2271 : : }
2272 : :
2273 : 0 : static int link_set_ipv6_dad_transmits(Link *link) {
2274 : : int r;
2275 : :
2276 : : /* Make this a NOP if IPv6 is not available */
2277 [ # # ]: 0 : if (!socket_ipv6_is_supported())
2278 : 0 : return 0;
2279 : :
2280 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
2281 : 0 : return 0;
2282 : :
2283 [ # # ]: 0 : if (!link->network)
2284 : 0 : return 0;
2285 : :
2286 [ # # ]: 0 : if (link->network->ipv6_dad_transmits < 0)
2287 : 0 : return 0;
2288 : :
2289 : 0 : r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "dad_transmits", link->network->ipv6_dad_transmits);
2290 [ # # ]: 0 : if (r < 0)
2291 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
2292 : :
2293 : 0 : return 0;
2294 : : }
2295 : :
2296 : 0 : static int link_set_ipv6_hop_limit(Link *link) {
2297 : : int r;
2298 : :
2299 : : /* Make this a NOP if IPv6 is not available */
2300 [ # # ]: 0 : if (!socket_ipv6_is_supported())
2301 : 0 : return 0;
2302 : :
2303 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
2304 : 0 : return 0;
2305 : :
2306 [ # # ]: 0 : if (!link->network)
2307 : 0 : return 0;
2308 : :
2309 [ # # ]: 0 : if (link->network->ipv6_hop_limit < 0)
2310 : 0 : return 0;
2311 : :
2312 : 0 : r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "hop_limit", link->network->ipv6_hop_limit);
2313 [ # # ]: 0 : if (r < 0)
2314 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
2315 : :
2316 : 0 : return 0;
2317 : : }
2318 : :
2319 : 0 : static int link_set_ipv6_mtu(Link *link) {
2320 : : int r;
2321 : :
2322 : : /* Make this a NOP if IPv6 is not available */
2323 [ # # ]: 0 : if (!socket_ipv6_is_supported())
2324 : 0 : return 0;
2325 : :
2326 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK)
2327 : 0 : return 0;
2328 : :
2329 [ # # ]: 0 : if (link->network->ipv6_mtu == 0)
2330 : 0 : return 0;
2331 : :
2332 : 0 : r = sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", link->network->ipv6_mtu);
2333 [ # # ]: 0 : if (r < 0)
2334 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface: %m");
2335 : :
2336 : 0 : return 0;
2337 : : }
2338 : :
2339 : 0 : static bool link_is_static_address_configured(Link *link, Address *address) {
2340 : : Address *net_address;
2341 : :
2342 [ # # ]: 0 : assert(link);
2343 [ # # ]: 0 : assert(address);
2344 : :
2345 [ # # ]: 0 : if (!link->network)
2346 : 0 : return false;
2347 : :
2348 [ # # ]: 0 : LIST_FOREACH(addresses, net_address, link->network->static_addresses)
2349 [ # # ]: 0 : if (address_equal(net_address, address))
2350 : 0 : return true;
2351 : :
2352 : 0 : return false;
2353 : : }
2354 : :
2355 : 0 : static bool link_is_neighbor_configured(Link *link, Neighbor *neighbor) {
2356 : : Neighbor *net_neighbor;
2357 : :
2358 [ # # ]: 0 : assert(link);
2359 [ # # ]: 0 : assert(neighbor);
2360 : :
2361 [ # # ]: 0 : if (!link->network)
2362 : 0 : return false;
2363 : :
2364 [ # # ]: 0 : LIST_FOREACH(neighbors, net_neighbor, link->network->neighbors)
2365 [ # # ]: 0 : if (neighbor_equal(net_neighbor, neighbor))
2366 : 0 : return true;
2367 : :
2368 : 0 : return false;
2369 : : }
2370 : :
2371 : 0 : static bool link_is_static_route_configured(Link *link, Route *route) {
2372 : : Route *net_route;
2373 : :
2374 [ # # ]: 0 : assert(link);
2375 [ # # ]: 0 : assert(route);
2376 : :
2377 [ # # ]: 0 : if (!link->network)
2378 : 0 : return false;
2379 : :
2380 [ # # ]: 0 : LIST_FOREACH(routes, net_route, link->network->static_routes)
2381 [ # # ]: 0 : if (route_equal(net_route, route))
2382 : 0 : return true;
2383 : :
2384 : 0 : return false;
2385 : : }
2386 : :
2387 : 0 : static bool link_address_is_dynamic(Link *link, Address *address) {
2388 : : Route *route;
2389 : : Iterator i;
2390 : :
2391 [ # # ]: 0 : assert(link);
2392 [ # # ]: 0 : assert(address);
2393 : :
2394 [ # # ]: 0 : if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
2395 : 0 : return true;
2396 : :
2397 : : /* Even when the address is leased from a DHCP server, networkd assign the address
2398 : : * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
2399 : : * corresponding routes with RTPROT_DHCP. */
2400 [ # # ]: 0 : SET_FOREACH(route, link->routes_foreign, i) {
2401 [ # # ]: 0 : if (route->protocol != RTPROT_DHCP)
2402 : 0 : continue;
2403 : :
2404 [ # # ]: 0 : if (address->family != route->family)
2405 : 0 : continue;
2406 : :
2407 [ # # ]: 0 : if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
2408 : 0 : return true;
2409 : : }
2410 : :
2411 : 0 : return false;
2412 : : }
2413 : :
2414 : 0 : static int link_drop_foreign_config(Link *link) {
2415 : : Address *address;
2416 : : Neighbor *neighbor;
2417 : : Route *route;
2418 : : Iterator i;
2419 : : int r;
2420 : :
2421 [ # # ]: 0 : SET_FOREACH(address, link->addresses_foreign, i) {
2422 : : /* we consider IPv6LL addresses to be managed by the kernel */
2423 [ # # # # ]: 0 : if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2424 : 0 : continue;
2425 : :
2426 [ # # ]: 0 : if (link_address_is_dynamic(link, address)) {
2427 [ # # ]: 0 : if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
2428 : 0 : continue;
2429 [ # # ]: 0 : } else if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
2430 : 0 : continue;
2431 : :
2432 [ # # ]: 0 : if (link_is_static_address_configured(link, address)) {
2433 : 0 : r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
2434 [ # # ]: 0 : if (r < 0)
2435 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to add address: %m");
2436 : : } else {
2437 : 0 : r = address_remove(address, link, NULL);
2438 [ # # ]: 0 : if (r < 0)
2439 : 0 : return r;
2440 : : }
2441 : : }
2442 : :
2443 [ # # ]: 0 : SET_FOREACH(neighbor, link->neighbors_foreign, i) {
2444 [ # # ]: 0 : if (link_is_neighbor_configured(link, neighbor)) {
2445 : 0 : r = neighbor_add(link, neighbor->family, &neighbor->in_addr, &neighbor->lladdr, neighbor->lladdr_size, NULL);
2446 [ # # ]: 0 : if (r < 0)
2447 : 0 : return r;
2448 : : } else {
2449 : 0 : r = neighbor_remove(neighbor, link, NULL);
2450 [ # # ]: 0 : if (r < 0)
2451 : 0 : return r;
2452 : : }
2453 : : }
2454 : :
2455 [ # # ]: 0 : SET_FOREACH(route, link->routes_foreign, i) {
2456 : : /* do not touch routes managed by the kernel */
2457 [ # # ]: 0 : if (route->protocol == RTPROT_KERNEL)
2458 : 0 : continue;
2459 : :
2460 : : /* do not touch multicast route added by kernel */
2461 : : /* FIXME: Why the kernel adds this route with protocol RTPROT_BOOT??? We need to investigate that.
2462 : : * https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */
2463 [ # # ]: 0 : if (route->protocol == RTPROT_BOOT &&
2464 [ # # ]: 0 : route->family == AF_INET6 &&
2465 [ # # # # ]: 0 : route->dst_prefixlen == 8 &&
2466 : 0 : in_addr_equal(AF_INET6, &route->dst, &(union in_addr_union) { .in6 = {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}} }))
2467 : 0 : continue;
2468 : :
2469 [ # # ]: 0 : if (route->protocol == RTPROT_STATIC &&
2470 [ # # ]: 0 : FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
2471 : 0 : continue;
2472 : :
2473 [ # # ]: 0 : if (route->protocol == RTPROT_DHCP &&
2474 [ # # ]: 0 : FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
2475 : 0 : continue;
2476 : :
2477 [ # # ]: 0 : if (link_is_static_route_configured(link, route)) {
2478 : 0 : r = route_add(link, route->family, &route->dst, route->dst_prefixlen, &route->gw, route->tos, route->priority, route->table, NULL);
2479 [ # # ]: 0 : if (r < 0)
2480 : 0 : return r;
2481 : : } else {
2482 : 0 : r = route_remove(route, link, NULL);
2483 [ # # ]: 0 : if (r < 0)
2484 : 0 : return r;
2485 : : }
2486 : : }
2487 : :
2488 : 0 : return 0;
2489 : : }
2490 : :
2491 : 0 : static int link_drop_config(Link *link) {
2492 : : Address *address, *pool_address;
2493 : : Neighbor *neighbor;
2494 : : Route *route;
2495 : : Iterator i;
2496 : : int r;
2497 : :
2498 [ # # ]: 0 : SET_FOREACH(address, link->addresses, i) {
2499 : : /* we consider IPv6LL addresses to be managed by the kernel */
2500 [ # # # # ]: 0 : if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2501 : 0 : continue;
2502 : :
2503 : 0 : r = address_remove(address, link, NULL);
2504 [ # # ]: 0 : if (r < 0)
2505 : 0 : return r;
2506 : :
2507 : : /* If this address came from an address pool, clean up the pool */
2508 [ # # ]: 0 : LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
2509 [ # # ]: 0 : if (address_equal(address, pool_address)) {
2510 [ # # # # : 0 : LIST_REMOVE(addresses, link->pool_addresses, pool_address);
# # # # ]
2511 : 0 : address_free(pool_address);
2512 : 0 : break;
2513 : : }
2514 : : }
2515 : : }
2516 : :
2517 [ # # ]: 0 : SET_FOREACH(neighbor, link->neighbors, i) {
2518 : 0 : r = neighbor_remove(neighbor, link, NULL);
2519 [ # # ]: 0 : if (r < 0)
2520 : 0 : return r;
2521 : : }
2522 : :
2523 [ # # ]: 0 : SET_FOREACH(route, link->routes, i) {
2524 : : /* do not touch routes managed by the kernel */
2525 [ # # ]: 0 : if (route->protocol == RTPROT_KERNEL)
2526 : 0 : continue;
2527 : :
2528 : 0 : r = route_remove(route, link, NULL);
2529 [ # # ]: 0 : if (r < 0)
2530 : 0 : return r;
2531 : : }
2532 : :
2533 : 0 : ndisc_flush(link);
2534 : :
2535 : 0 : return 0;
2536 : : }
2537 : :
2538 : 0 : static int link_configure(Link *link) {
2539 : : int r;
2540 : :
2541 [ # # ]: 0 : assert(link);
2542 [ # # ]: 0 : assert(link->network);
2543 [ # # ]: 0 : assert(link->state == LINK_STATE_INITIALIZED);
2544 : :
2545 [ # # ]: 0 : if (link->iftype == ARPHRD_CAN)
2546 : 0 : return link_configure_can(link);
2547 : :
2548 : : /* Drop foreign config, but ignore loopback or critical devices.
2549 : : * We do not want to remove loopback address or addresses used for root NFS. */
2550 [ # # ]: 0 : if (!(link->flags & IFF_LOOPBACK) &&
2551 [ # # ]: 0 : link->network->keep_configuration != KEEP_CONFIGURATION_YES) {
2552 : 0 : r = link_drop_foreign_config(link);
2553 [ # # ]: 0 : if (r < 0)
2554 : 0 : return r;
2555 : : }
2556 : :
2557 : 0 : r = link_set_proxy_arp(link);
2558 [ # # ]: 0 : if (r < 0)
2559 : 0 : return r;
2560 : :
2561 : 0 : r = ipv6_proxy_ndp_addresses_configure(link);
2562 [ # # ]: 0 : if (r < 0)
2563 : 0 : return r;
2564 : :
2565 : 0 : r = link_set_ipv4_forward(link);
2566 [ # # ]: 0 : if (r < 0)
2567 : 0 : return r;
2568 : :
2569 : 0 : r = link_set_ipv6_forward(link);
2570 [ # # ]: 0 : if (r < 0)
2571 : 0 : return r;
2572 : :
2573 : 0 : r = link_set_ipv6_privacy_extensions(link);
2574 [ # # ]: 0 : if (r < 0)
2575 : 0 : return r;
2576 : :
2577 : 0 : r = link_set_ipv6_accept_ra(link);
2578 [ # # ]: 0 : if (r < 0)
2579 : 0 : return r;
2580 : :
2581 : 0 : r = link_set_ipv6_dad_transmits(link);
2582 [ # # ]: 0 : if (r < 0)
2583 : 0 : return r;
2584 : :
2585 : 0 : r = link_set_ipv6_hop_limit(link);
2586 [ # # ]: 0 : if (r < 0)
2587 : 0 : return r;
2588 : :
2589 : 0 : r = link_set_flags(link);
2590 [ # # ]: 0 : if (r < 0)
2591 : 0 : return r;
2592 : :
2593 : 0 : r = link_set_ipv6_mtu(link);
2594 [ # # ]: 0 : if (r < 0)
2595 : 0 : return r;
2596 : :
2597 [ # # ]: 0 : if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) {
2598 : 0 : r = ipv4ll_configure(link);
2599 [ # # ]: 0 : if (r < 0)
2600 : 0 : return r;
2601 : : }
2602 : :
2603 [ # # ]: 0 : if (link_dhcp4_enabled(link)) {
2604 : 0 : r = dhcp4_set_promote_secondaries(link);
2605 [ # # ]: 0 : if (r < 0)
2606 : 0 : return r;
2607 : :
2608 : 0 : r = dhcp4_configure(link);
2609 [ # # ]: 0 : if (r < 0)
2610 : 0 : return r;
2611 : : }
2612 : :
2613 [ # # ]: 0 : if (link_dhcp4_server_enabled(link)) {
2614 : 0 : r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2615 [ # # ]: 0 : if (r < 0)
2616 : 0 : return r;
2617 : :
2618 : 0 : r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2619 [ # # ]: 0 : if (r < 0)
2620 : 0 : return r;
2621 : : }
2622 : :
2623 [ # # # # ]: 0 : if (link_dhcp6_enabled(link) ||
2624 : 0 : link_ipv6_accept_ra_enabled(link)) {
2625 : 0 : r = dhcp6_configure(link);
2626 [ # # ]: 0 : if (r < 0)
2627 : 0 : return r;
2628 : : }
2629 : :
2630 [ # # ]: 0 : if (link_ipv6_accept_ra_enabled(link)) {
2631 : 0 : r = ndisc_configure(link);
2632 [ # # ]: 0 : if (r < 0)
2633 : 0 : return r;
2634 : : }
2635 : :
2636 [ # # ]: 0 : if (link_radv_enabled(link)) {
2637 : 0 : r = radv_configure(link);
2638 [ # # ]: 0 : if (r < 0)
2639 : 0 : return r;
2640 : : }
2641 : :
2642 [ # # ]: 0 : if (link_lldp_rx_enabled(link)) {
2643 : 0 : r = link_lldp_rx_configure(link);
2644 [ # # ]: 0 : if (r < 0)
2645 : 0 : return r;
2646 : : }
2647 : :
2648 : 0 : r = link_configure_mtu(link);
2649 [ # # ]: 0 : if (r < 0)
2650 : 0 : return r;
2651 : :
2652 : 0 : r = link_configure_addrgen_mode(link);
2653 [ # # ]: 0 : if (r < 0)
2654 : 0 : return r;
2655 : :
2656 : 0 : return link_configure_after_setting_mtu(link);
2657 : : }
2658 : :
2659 : 0 : static int link_configure_after_setting_mtu(Link *link) {
2660 : : int r;
2661 : :
2662 [ # # ]: 0 : assert(link);
2663 [ # # ]: 0 : assert(link->network);
2664 [ # # ]: 0 : assert(link->state == LINK_STATE_INITIALIZED);
2665 : :
2666 [ # # ]: 0 : if (link->setting_mtu)
2667 : 0 : return 0;
2668 : :
2669 [ # # # # ]: 0 : if (link_has_carrier(link) || link->network->configure_without_carrier) {
2670 : 0 : r = link_acquire_conf(link);
2671 [ # # ]: 0 : if (r < 0)
2672 : 0 : return r;
2673 : : }
2674 : :
2675 : 0 : return link_enter_join_netdev(link);
2676 : : }
2677 : :
2678 : 0 : static int duid_set_uuid(DUID *duid, sd_id128_t uuid) {
2679 [ # # ]: 0 : assert(duid);
2680 : :
2681 [ # # ]: 0 : if (duid->raw_data_len > 0)
2682 : 0 : return 0;
2683 : :
2684 [ # # ]: 0 : if (duid->type != DUID_TYPE_UUID)
2685 : 0 : return -EINVAL;
2686 : :
2687 : 0 : memcpy(&duid->raw_data, &uuid, sizeof(sd_id128_t));
2688 : 0 : duid->raw_data_len = sizeof(sd_id128_t);
2689 : :
2690 : 0 : return 1;
2691 : : }
2692 : :
2693 : 0 : int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
2694 : 0 : Manager *manager = userdata;
2695 : : const sd_bus_error *e;
2696 : : const void *a;
2697 : : size_t sz;
2698 : : DUID *duid;
2699 : : Link *link;
2700 : : int r;
2701 : :
2702 [ # # ]: 0 : assert(m);
2703 [ # # ]: 0 : assert(manager);
2704 : :
2705 : 0 : e = sd_bus_message_get_error(m);
2706 [ # # ]: 0 : if (e) {
2707 [ # # ]: 0 : log_error_errno(sd_bus_error_get_errno(e),
2708 : : "Could not get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %s",
2709 : : e->message);
2710 : 0 : goto configure;
2711 : : }
2712 : :
2713 : 0 : r = sd_bus_message_read_array(m, 'y', &a, &sz);
2714 [ # # ]: 0 : if (r < 0)
2715 : 0 : goto configure;
2716 : :
2717 [ # # ]: 0 : if (sz != sizeof(sd_id128_t)) {
2718 [ # # ]: 0 : log_error("Invalid product UUID. Falling back to use machine-app-specific ID as DUID-UUID.");
2719 : 0 : goto configure;
2720 : : }
2721 : :
2722 : 0 : memcpy(&manager->product_uuid, a, sz);
2723 [ # # ]: 0 : while ((duid = set_steal_first(manager->duids_requesting_uuid)))
2724 : 0 : (void) duid_set_uuid(duid, manager->product_uuid);
2725 : :
2726 : 0 : manager->duids_requesting_uuid = set_free(manager->duids_requesting_uuid);
2727 : :
2728 : 0 : configure:
2729 [ # # ]: 0 : while ((link = set_steal_first(manager->links_requesting_uuid))) {
2730 : 0 : link_unref(link);
2731 : :
2732 : 0 : r = link_configure(link);
2733 [ # # ]: 0 : if (r < 0)
2734 : 0 : link_enter_failed(link);
2735 : : }
2736 : :
2737 : 0 : manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
2738 : :
2739 : : /* To avoid calling GetProductUUID() bus method so frequently, set the flag below
2740 : : * even if the method fails. */
2741 : 0 : manager->has_product_uuid = true;
2742 : :
2743 : 0 : return 1;
2744 : : }
2745 : :
2746 : 0 : static bool link_requires_uuid(Link *link) {
2747 : : const DUID *duid;
2748 : :
2749 [ # # ]: 0 : assert(link);
2750 [ # # ]: 0 : assert(link->manager);
2751 [ # # ]: 0 : assert(link->network);
2752 : :
2753 : 0 : duid = link_get_duid(link);
2754 [ # # # # ]: 0 : if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
2755 : 0 : return false;
2756 : :
2757 [ # # # # : 0 : if (link_dhcp4_enabled(link) && IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
# # ]
2758 : 0 : return true;
2759 : :
2760 [ # # # # ]: 0 : if (link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link))
2761 : 0 : return true;
2762 : :
2763 : 0 : return false;
2764 : : }
2765 : :
2766 : 0 : static int link_configure_duid(Link *link) {
2767 : : Manager *m;
2768 : : DUID *duid;
2769 : : int r;
2770 : :
2771 [ # # ]: 0 : assert(link);
2772 [ # # ]: 0 : assert(link->manager);
2773 [ # # ]: 0 : assert(link->network);
2774 : :
2775 : 0 : m = link->manager;
2776 : 0 : duid = link_get_duid(link);
2777 : :
2778 [ # # ]: 0 : if (!link_requires_uuid(link))
2779 : 0 : return 1;
2780 : :
2781 [ # # ]: 0 : if (m->has_product_uuid) {
2782 : 0 : (void) duid_set_uuid(duid, m->product_uuid);
2783 : 0 : return 1;
2784 : : }
2785 : :
2786 [ # # ]: 0 : if (!m->links_requesting_uuid) {
2787 : 0 : r = manager_request_product_uuid(m, link);
2788 [ # # ]: 0 : if (r < 0) {
2789 [ # # ]: 0 : if (r == -ENOMEM)
2790 : 0 : return r;
2791 : :
2792 [ # # # # ]: 0 : log_link_warning_errno(link, r,
2793 : : "Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
2794 : 0 : return 1;
2795 : : }
2796 : : } else {
2797 : 0 : r = set_put(m->links_requesting_uuid, link);
2798 [ # # ]: 0 : if (r < 0)
2799 : 0 : return log_oom();
2800 : :
2801 : 0 : r = set_put(m->duids_requesting_uuid, duid);
2802 [ # # ]: 0 : if (r < 0)
2803 : 0 : return log_oom();
2804 : :
2805 : 0 : link_ref(link);
2806 : : }
2807 : :
2808 : 0 : return 0;
2809 : : }
2810 : :
2811 : 0 : static int link_initialized_and_synced(Link *link) {
2812 : : Network *network;
2813 : : int r;
2814 : :
2815 [ # # ]: 0 : assert(link);
2816 [ # # ]: 0 : assert(link->ifname);
2817 [ # # ]: 0 : assert(link->manager);
2818 : :
2819 : : /* We may get called either from the asynchronous netlink callback,
2820 : : * or directly for link_add() if running in a container. See link_add(). */
2821 [ # # # # ]: 0 : if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED))
2822 : 0 : return 0;
2823 : :
2824 [ # # # # ]: 0 : log_link_debug(link, "Link state is up-to-date");
2825 : 0 : link_set_state(link, LINK_STATE_INITIALIZED);
2826 : :
2827 : 0 : r = link_new_bound_by_list(link);
2828 [ # # ]: 0 : if (r < 0)
2829 : 0 : return r;
2830 : :
2831 : 0 : r = link_handle_bound_by_list(link);
2832 [ # # ]: 0 : if (r < 0)
2833 : 0 : return r;
2834 : :
2835 [ # # ]: 0 : if (!link->network) {
2836 : 0 : r = network_get(link->manager, link->sd_device, link->ifname,
2837 : 0 : &link->mac, &network);
2838 [ # # ]: 0 : if (r == -ENOENT) {
2839 : 0 : link_enter_unmanaged(link);
2840 : 0 : return 0;
2841 [ # # # # ]: 0 : } else if (r == 0 && network->unmanaged) {
2842 : 0 : link_enter_unmanaged(link);
2843 : 0 : return 0;
2844 [ # # ]: 0 : } else if (r < 0)
2845 : 0 : return r;
2846 : :
2847 [ # # ]: 0 : if (link->flags & IFF_LOOPBACK) {
2848 [ # # ]: 0 : if (network->link_local != ADDRESS_FAMILY_NO)
2849 [ # # # # ]: 0 : log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
2850 : :
2851 [ # # ]: 0 : if (network->dhcp != ADDRESS_FAMILY_NO)
2852 [ # # # # ]: 0 : log_link_debug(link, "Ignoring DHCP clients for loopback link");
2853 : :
2854 [ # # ]: 0 : if (network->dhcp_server)
2855 [ # # # # ]: 0 : log_link_debug(link, "Ignoring DHCP server for loopback link");
2856 : : }
2857 : :
2858 : 0 : r = network_apply(network, link);
2859 [ # # ]: 0 : if (r < 0)
2860 : 0 : return r;
2861 : : }
2862 : :
2863 : 0 : r = link_new_bound_to_list(link);
2864 [ # # ]: 0 : if (r < 0)
2865 : 0 : return r;
2866 : :
2867 : : /* link_configure_duid() returns 0 if it requests product UUID. In that case,
2868 : : * link_configure() is called later asynchronously. */
2869 : 0 : r = link_configure_duid(link);
2870 [ # # ]: 0 : if (r <= 0)
2871 : 0 : return r;
2872 : :
2873 : 0 : r = link_configure(link);
2874 [ # # ]: 0 : if (r < 0)
2875 : 0 : return r;
2876 : :
2877 : 0 : return 0;
2878 : : }
2879 : :
2880 : 0 : static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
2881 : : int r;
2882 : :
2883 : 0 : r = link_initialized_and_synced(link);
2884 [ # # ]: 0 : if (r < 0)
2885 : 0 : link_enter_failed(link);
2886 : 0 : return 1;
2887 : : }
2888 : :
2889 : 28 : int link_initialized(Link *link, sd_device *device) {
2890 : 28 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
2891 : : int r;
2892 : :
2893 [ - + ]: 28 : assert(link);
2894 [ - + ]: 28 : assert(link->manager);
2895 [ - + ]: 28 : assert(link->manager->rtnl);
2896 [ - + ]: 28 : assert(device);
2897 : :
2898 [ - + ]: 28 : if (link->state != LINK_STATE_PENDING)
2899 : 0 : return 0;
2900 : :
2901 [ - + ]: 28 : if (link->sd_device)
2902 : 0 : return 0;
2903 : :
2904 [ + - + - ]: 28 : log_link_debug(link, "udev initialized link");
2905 : 28 : link_set_state(link, LINK_STATE_INITIALIZED);
2906 : :
2907 : 28 : link->sd_device = sd_device_ref(device);
2908 : :
2909 : : /* udev has initialized the link, but we don't know if we have yet
2910 : : * processed the NEWLINK messages with the latest state. Do a GETLINK,
2911 : : * when it returns we know that the pending NEWLINKs have already been
2912 : : * processed and that we are up-to-date */
2913 : :
2914 : 28 : r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2915 : : link->ifindex);
2916 [ - + ]: 28 : if (r < 0)
2917 : 0 : return r;
2918 : :
2919 : 28 : r = netlink_call_async(link->manager->rtnl, NULL, req, link_initialized_handler,
2920 : : link_netlink_destroy_callback, link);
2921 [ - + ]: 28 : if (r < 0)
2922 : 0 : return r;
2923 : :
2924 : 28 : link_ref(link);
2925 : :
2926 : 28 : return 0;
2927 : : }
2928 : :
2929 : 28 : static int link_load(Link *link) {
2930 : 28 : _cleanup_free_ char *network_file = NULL,
2931 : 28 : *addresses = NULL,
2932 : 28 : *routes = NULL,
2933 : 28 : *dhcp4_address = NULL,
2934 : 28 : *ipv4ll_address = NULL;
2935 : : union in_addr_union address;
2936 : : union in_addr_union route_dst;
2937 : : const char *p;
2938 : : int r;
2939 : :
2940 [ - + ]: 28 : assert(link);
2941 : :
2942 : 28 : r = parse_env_file(NULL, link->state_file,
2943 : : "NETWORK_FILE", &network_file,
2944 : : "ADDRESSES", &addresses,
2945 : : "ROUTES", &routes,
2946 : : "DHCP4_ADDRESS", &dhcp4_address,
2947 : : "IPV4LL_ADDRESS", &ipv4ll_address);
2948 [ + - - + ]: 28 : if (r < 0 && r != -ENOENT)
2949 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2950 : :
2951 [ + - ]: 28 : if (network_file) {
2952 : : Network *network;
2953 : : char *suffix;
2954 : :
2955 : : /* drop suffix */
2956 : 0 : suffix = strrchr(network_file, '.');
2957 [ # # ]: 0 : if (!suffix) {
2958 [ # # # # ]: 0 : log_link_debug(link, "Failed to get network name from %s", network_file);
2959 : 0 : goto network_file_fail;
2960 : : }
2961 : 0 : *suffix = '\0';
2962 : :
2963 : 0 : r = network_get_by_name(link->manager, basename(network_file), &network);
2964 [ # # ]: 0 : if (r < 0) {
2965 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2966 : 0 : goto network_file_fail;
2967 : : }
2968 : :
2969 : 0 : r = network_apply(network, link);
2970 [ # # ]: 0 : if (r < 0)
2971 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2972 : : }
2973 : :
2974 : 28 : network_file_fail:
2975 : :
2976 [ - + ]: 28 : if (addresses) {
2977 : 0 : p = addresses;
2978 : :
2979 : 0 : for (;;) {
2980 [ # # # # ]: 0 : _cleanup_free_ char *address_str = NULL;
2981 : : char *prefixlen_str;
2982 : : int family;
2983 : : unsigned char prefixlen;
2984 : :
2985 : 0 : r = extract_first_word(&p, &address_str, NULL, 0);
2986 [ # # ]: 0 : if (r < 0) {
2987 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2988 : 0 : continue;
2989 : : }
2990 [ # # ]: 0 : if (r == 0)
2991 : 0 : break;
2992 : :
2993 : 0 : prefixlen_str = strchr(address_str, '/');
2994 [ # # ]: 0 : if (!prefixlen_str) {
2995 [ # # # # ]: 0 : log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
2996 : 0 : continue;
2997 : : }
2998 : :
2999 : 0 : *prefixlen_str++ = '\0';
3000 : :
3001 : 0 : r = sscanf(prefixlen_str, "%hhu", &prefixlen);
3002 [ # # ]: 0 : if (r != 1) {
3003 [ # # # # ]: 0 : log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
3004 : 0 : continue;
3005 : : }
3006 : :
3007 : 0 : r = in_addr_from_string_auto(address_str, &family, &address);
3008 [ # # ]: 0 : if (r < 0) {
3009 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
3010 : 0 : continue;
3011 : : }
3012 : :
3013 : 0 : r = address_add(link, family, &address, prefixlen, NULL);
3014 [ # # ]: 0 : if (r < 0)
3015 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to add address: %m");
3016 : : }
3017 : : }
3018 : :
3019 [ - + ]: 28 : if (routes) {
3020 : 0 : p = routes;
3021 : :
3022 : 0 : for (;;) {
3023 : : Route *route;
3024 [ # # # # ]: 0 : _cleanup_free_ char *route_str = NULL;
3025 [ # # # # ]: 0 : _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
3026 : : usec_t lifetime;
3027 : : char *prefixlen_str;
3028 : : int family;
3029 : : unsigned char prefixlen, tos, table;
3030 : : uint32_t priority;
3031 : :
3032 : 0 : r = extract_first_word(&p, &route_str, NULL, 0);
3033 [ # # ]: 0 : if (r < 0) {
3034 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to extract next route string: %m");
3035 : 0 : continue;
3036 : : }
3037 [ # # ]: 0 : if (r == 0)
3038 : 0 : break;
3039 : :
3040 : 0 : prefixlen_str = strchr(route_str, '/');
3041 [ # # ]: 0 : if (!prefixlen_str) {
3042 [ # # # # ]: 0 : log_link_debug(link, "Failed to parse route %s", route_str);
3043 : 0 : continue;
3044 : : }
3045 : :
3046 : 0 : *prefixlen_str++ = '\0';
3047 : :
3048 : 0 : r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
3049 [ # # ]: 0 : if (r != 5) {
3050 [ # # # # ]: 0 : log_link_debug(link,
3051 : : "Failed to parse destination prefix length, tos, priority, table or expiration %s",
3052 : : prefixlen_str);
3053 : 0 : continue;
3054 : : }
3055 : :
3056 : 0 : r = in_addr_from_string_auto(route_str, &family, &route_dst);
3057 [ # # ]: 0 : if (r < 0) {
3058 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
3059 : 0 : continue;
3060 : : }
3061 : :
3062 : 0 : r = route_add(link, family, &route_dst, prefixlen, NULL, tos, priority, table, &route);
3063 [ # # ]: 0 : if (r < 0)
3064 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to add route: %m");
3065 : :
3066 [ # # # # ]: 0 : if (lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
3067 : 0 : r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
3068 : : 0, route_expire_handler, route);
3069 [ # # ]: 0 : if (r < 0)
3070 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
3071 : : }
3072 : :
3073 : 0 : route->lifetime = lifetime;
3074 : 0 : sd_event_source_unref(route->expire);
3075 : 0 : route->expire = TAKE_PTR(expire);
3076 : : }
3077 : : }
3078 : :
3079 [ - + ]: 28 : if (dhcp4_address) {
3080 : 0 : r = in_addr_from_string(AF_INET, dhcp4_address, &address);
3081 [ # # ]: 0 : if (r < 0) {
3082 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to parse DHCPv4 address %s: %m", dhcp4_address);
3083 : 0 : goto dhcp4_address_fail;
3084 : : }
3085 : :
3086 [ # # ]: 0 : r = sd_dhcp_client_new(&link->dhcp_client, link->network ? link->network->dhcp_anonymize : 0);
3087 [ # # ]: 0 : if (r < 0)
3088 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to create DHCPv4 client: %m");
3089 : :
3090 : 0 : r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
3091 [ # # ]: 0 : if (r < 0)
3092 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to set initial DHCPv4 address %s: %m", dhcp4_address);
3093 : : }
3094 : :
3095 : 28 : dhcp4_address_fail:
3096 : :
3097 [ - + ]: 28 : if (ipv4ll_address) {
3098 : 0 : r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
3099 [ # # ]: 0 : if (r < 0) {
3100 [ # # # # ]: 0 : log_link_debug_errno(link, r, "Failed to parse IPv4LL address %s: %m", ipv4ll_address);
3101 : 0 : goto ipv4ll_address_fail;
3102 : : }
3103 : :
3104 : 0 : r = sd_ipv4ll_new(&link->ipv4ll);
3105 [ # # ]: 0 : if (r < 0)
3106 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to create IPv4LL client: %m");
3107 : :
3108 : 0 : r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
3109 [ # # ]: 0 : if (r < 0)
3110 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to set initial IPv4LL address %s: %m", ipv4ll_address);
3111 : : }
3112 : :
3113 : 28 : ipv4ll_address_fail:
3114 : :
3115 : 28 : return 0;
3116 : : }
3117 : :
3118 : 28 : int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
3119 : 28 : _cleanup_(sd_device_unrefp) sd_device *device = NULL;
3120 : : char ifindex_str[2 + DECIMAL_STR_MAX(int)];
3121 : : Link *link;
3122 : : int r;
3123 : :
3124 [ - + ]: 28 : assert(m);
3125 [ - + ]: 28 : assert(m->rtnl);
3126 [ - + ]: 28 : assert(message);
3127 [ - + ]: 28 : assert(ret);
3128 : :
3129 : 28 : r = link_new(m, message, ret);
3130 [ - + ]: 28 : if (r < 0)
3131 : 0 : return r;
3132 : :
3133 : 28 : link = *ret;
3134 : :
3135 [ + - + - ]: 28 : log_link_debug(link, "Link %d added", link->ifindex);
3136 : :
3137 : 28 : r = link_load(link);
3138 [ - + ]: 28 : if (r < 0)
3139 : 0 : return r;
3140 : :
3141 [ + - ]: 28 : if (detect_container() <= 0) {
3142 : : /* not in a container, udev will be around */
3143 : 28 : sprintf(ifindex_str, "n%d", link->ifindex);
3144 : 28 : r = sd_device_new_from_device_id(&device, ifindex_str);
3145 [ - + ]: 28 : if (r < 0) {
3146 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not find device: %m");
3147 : 0 : goto failed;
3148 : : }
3149 : :
3150 : 28 : r = sd_device_get_is_initialized(device);
3151 [ - + ]: 28 : if (r < 0) {
3152 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Could not determine whether the device is initialized or not: %m");
3153 : 0 : goto failed;
3154 : : }
3155 [ - + ]: 28 : if (r == 0) {
3156 : : /* not yet ready */
3157 [ # # # # ]: 0 : log_link_debug(link, "link pending udev initialization...");
3158 : 0 : return 0;
3159 : : }
3160 : :
3161 : 28 : r = device_is_renaming(device);
3162 [ - + ]: 28 : if (r < 0) {
3163 [ # # # # ]: 0 : log_link_warning_errno(link, r, "Failed to determine the device is renamed or not: %m");
3164 : 0 : goto failed;
3165 : : }
3166 [ - + ]: 28 : if (r > 0) {
3167 [ # # # # ]: 0 : log_link_debug(link, "Interface is under renaming, pending initialization.");
3168 : 0 : return 0;
3169 : : }
3170 : :
3171 : 28 : r = link_initialized(link, device);
3172 [ - + ]: 28 : if (r < 0)
3173 : 0 : goto failed;
3174 : : } else {
3175 : 0 : r = link_initialized_and_synced(link);
3176 [ # # ]: 0 : if (r < 0)
3177 : 0 : goto failed;
3178 : : }
3179 : :
3180 : 28 : return 0;
3181 : 0 : failed:
3182 : 0 : link_enter_failed(link);
3183 : 0 : return r;
3184 : : }
3185 : :
3186 : 0 : int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
3187 : : int r;
3188 : :
3189 [ # # ]: 0 : assert(link);
3190 : :
3191 [ # # # # ]: 0 : log_link_info(link, "Gained IPv6LL");
3192 : :
3193 : 0 : link->ipv6ll_address = *address;
3194 : 0 : link_check_ready(link);
3195 : :
3196 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
3197 : 0 : r = link_acquire_ipv6_conf(link);
3198 [ # # ]: 0 : if (r < 0) {
3199 : 0 : link_enter_failed(link);
3200 : 0 : return r;
3201 : : }
3202 : : }
3203 : :
3204 : 0 : return 0;
3205 : : }
3206 : :
3207 : 0 : static int link_carrier_gained(Link *link) {
3208 : : int r;
3209 : :
3210 [ # # ]: 0 : assert(link);
3211 : :
3212 [ # # # # ]: 0 : if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
3213 : 0 : r = link_acquire_conf(link);
3214 [ # # ]: 0 : if (r < 0) {
3215 : 0 : link_enter_failed(link);
3216 : 0 : return r;
3217 : : }
3218 : :
3219 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
3220 : 0 : r = link_request_set_addresses(link);
3221 [ # # ]: 0 : if (r < 0)
3222 : 0 : return r;
3223 : : }
3224 : :
3225 : 0 : r = link_handle_bound_by_list(link);
3226 [ # # ]: 0 : if (r < 0)
3227 : 0 : return r;
3228 : :
3229 : 0 : return 0;
3230 : : }
3231 : :
3232 : 0 : static int link_carrier_lost(Link *link) {
3233 : : int r;
3234 : :
3235 [ # # ]: 0 : assert(link);
3236 : :
3237 [ # # # # ]: 0 : if (link->network && link->network->ignore_carrier_loss)
3238 : 0 : return 0;
3239 : :
3240 : : /* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop.
3241 : : * setting_mtu keep track whether the device got reset because of setting MTU and does not drop the
3242 : : * configuration and stop the clients as well. */
3243 [ # # ]: 0 : if (link->setting_mtu)
3244 : 0 : return 0;
3245 : :
3246 : 0 : r = link_stop_clients(link, false);
3247 [ # # ]: 0 : if (r < 0) {
3248 : 0 : link_enter_failed(link);
3249 : 0 : return r;
3250 : : }
3251 : :
3252 [ # # ]: 0 : if (link_dhcp4_server_enabled(link))
3253 : 0 : (void) sd_dhcp_server_stop(link->dhcp_server);
3254 : :
3255 : 0 : r = link_drop_config(link);
3256 [ # # ]: 0 : if (r < 0)
3257 : 0 : return r;
3258 : :
3259 [ # # # # ]: 0 : if (!IN_SET(link->state, LINK_STATE_UNMANAGED, LINK_STATE_PENDING)) {
3260 [ # # # # ]: 0 : log_link_debug(link, "State is %s, dropping config", link_state_to_string(link->state));
3261 : 0 : r = link_drop_foreign_config(link);
3262 [ # # ]: 0 : if (r < 0)
3263 : 0 : return r;
3264 : : }
3265 : :
3266 : 0 : r = link_handle_bound_by_list(link);
3267 [ # # ]: 0 : if (r < 0)
3268 : 0 : return r;
3269 : :
3270 : 0 : return 0;
3271 : : }
3272 : :
3273 : 0 : int link_carrier_reset(Link *link) {
3274 : : int r;
3275 : :
3276 [ # # ]: 0 : assert(link);
3277 : :
3278 [ # # ]: 0 : if (link_has_carrier(link)) {
3279 : 0 : r = link_carrier_lost(link);
3280 [ # # ]: 0 : if (r < 0)
3281 : 0 : return r;
3282 : :
3283 : 0 : r = link_carrier_gained(link);
3284 [ # # ]: 0 : if (r < 0)
3285 : 0 : return r;
3286 : :
3287 [ # # # # ]: 0 : log_link_info(link, "Reset carrier");
3288 : : }
3289 : :
3290 : 0 : return 0;
3291 : : }
3292 : :
3293 : 28 : int link_update(Link *link, sd_netlink_message *m) {
3294 : : struct ether_addr mac;
3295 : : const char *ifname;
3296 : : uint32_t mtu;
3297 : : bool had_carrier, carrier_gained, carrier_lost;
3298 : : int old_master, r;
3299 : :
3300 [ - + ]: 28 : assert(link);
3301 [ - + ]: 28 : assert(link->ifname);
3302 [ - + ]: 28 : assert(m);
3303 : :
3304 [ - + ]: 28 : if (link->state == LINK_STATE_LINGER) {
3305 [ # # # # ]: 0 : log_link_info(link, "Link re-added");
3306 : 0 : link_set_state(link, LINK_STATE_CONFIGURING);
3307 : :
3308 : 0 : r = link_new_carrier_maps(link);
3309 [ # # ]: 0 : if (r < 0)
3310 : 0 : return r;
3311 : : }
3312 : :
3313 : 28 : r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
3314 [ + - - + ]: 28 : if (r >= 0 && !streq(ifname, link->ifname)) {
3315 : 0 : Manager *manager = link->manager;
3316 : :
3317 [ # # # # ]: 0 : log_link_info(link, "Interface name change detected, %s has been renamed to %s.", link->ifname, ifname);
3318 : :
3319 : 0 : link_drop(link);
3320 : 0 : r = link_add(manager, m, &link);
3321 [ # # ]: 0 : if (r < 0)
3322 : 0 : return r;
3323 : : }
3324 : :
3325 : 28 : r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
3326 [ + - + - ]: 28 : if (r >= 0 && mtu > 0) {
3327 : 28 : link->mtu = mtu;
3328 [ + - ]: 28 : if (link->original_mtu == 0) {
3329 : 28 : link->original_mtu = mtu;
3330 [ + - + - ]: 28 : log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
3331 : : }
3332 : :
3333 [ - + ]: 28 : if (link->dhcp_client) {
3334 : 0 : r = sd_dhcp_client_set_mtu(link->dhcp_client,
3335 : 0 : link->mtu);
3336 [ # # ]: 0 : if (r < 0)
3337 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
3338 : : }
3339 : :
3340 [ - + ]: 28 : if (link->radv) {
3341 : 0 : r = sd_radv_set_mtu(link->radv, link->mtu);
3342 [ # # ]: 0 : if (r < 0)
3343 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not set MTU for Router Advertisement: %m");
3344 : : }
3345 : : }
3346 : :
3347 : : /* The kernel may broadcast NEWLINK messages without the MAC address
3348 : : set, simply ignore them. */
3349 : 28 : r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
3350 [ + + ]: 28 : if (r >= 0) {
3351 [ - + ]: 20 : if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
3352 : : ETH_ALEN)) {
3353 : :
3354 : 0 : memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
3355 : : ETH_ALEN);
3356 : :
3357 [ # # # # ]: 0 : log_link_debug(link, "MAC address: "
3358 : : "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
3359 : : mac.ether_addr_octet[0],
3360 : : mac.ether_addr_octet[1],
3361 : : mac.ether_addr_octet[2],
3362 : : mac.ether_addr_octet[3],
3363 : : mac.ether_addr_octet[4],
3364 : : mac.ether_addr_octet[5]);
3365 : :
3366 [ # # ]: 0 : if (link->ipv4ll) {
3367 : 0 : r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
3368 [ # # ]: 0 : if (r < 0)
3369 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
3370 : : }
3371 : :
3372 [ # # ]: 0 : if (link->dhcp_client) {
3373 : 0 : r = sd_dhcp_client_set_mac(link->dhcp_client,
3374 : 0 : (const uint8_t *) &link->mac,
3375 : : sizeof (link->mac),
3376 : : ARPHRD_ETHER);
3377 [ # # ]: 0 : if (r < 0)
3378 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
3379 : :
3380 : 0 : r = dhcp4_set_client_identifier(link);
3381 [ # # ]: 0 : if (r < 0)
3382 : 0 : return r;
3383 : : }
3384 : :
3385 [ # # ]: 0 : if (link->dhcp6_client) {
3386 : 0 : const DUID* duid = link_get_duid(link);
3387 : :
3388 : 0 : r = sd_dhcp6_client_set_mac(link->dhcp6_client,
3389 : 0 : (const uint8_t *) &link->mac,
3390 : : sizeof (link->mac),
3391 : : ARPHRD_ETHER);
3392 [ # # ]: 0 : if (r < 0)
3393 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
3394 : :
3395 [ # # ]: 0 : if (link->network->iaid_set) {
3396 : 0 : r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
3397 : 0 : link->network->iaid);
3398 [ # # ]: 0 : if (r < 0)
3399 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
3400 : : }
3401 : :
3402 : 0 : r = sd_dhcp6_client_set_duid(link->dhcp6_client,
3403 : 0 : duid->type,
3404 : 0 : duid->raw_data_len > 0 ? duid->raw_data : NULL,
3405 [ # # ]: 0 : duid->raw_data_len);
3406 [ # # ]: 0 : if (r < 0)
3407 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
3408 : : }
3409 : :
3410 [ # # ]: 0 : if (link->radv) {
3411 : 0 : r = sd_radv_set_mac(link->radv, &link->mac);
3412 [ # # ]: 0 : if (r < 0)
3413 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
3414 : : }
3415 : :
3416 [ # # ]: 0 : if (link->ndisc) {
3417 : 0 : r = sd_ndisc_set_mac(link->ndisc, &link->mac);
3418 [ # # ]: 0 : if (r < 0)
3419 [ # # # # ]: 0 : return log_link_warning_errno(link, r, "Could not update MAC for ndisc: %m");
3420 : : }
3421 : : }
3422 : : }
3423 : :
3424 : 28 : old_master = link->master_ifindex;
3425 : 28 : (void) sd_netlink_message_read_u32(m, IFLA_MASTER, (uint32_t *) &link->master_ifindex);
3426 : :
3427 : 28 : had_carrier = link_has_carrier(link);
3428 : :
3429 : 28 : r = link_update_flags(link, m, old_master != link->master_ifindex);
3430 [ - + ]: 28 : if (r < 0)
3431 : 0 : return r;
3432 : :
3433 : 28 : r = link_update_lldp(link);
3434 [ - + ]: 28 : if (r < 0)
3435 : 0 : return r;
3436 : :
3437 [ + + - + ]: 28 : carrier_gained = !had_carrier && link_has_carrier(link);
3438 [ + + - + ]: 28 : carrier_lost = had_carrier && !link_has_carrier(link);
3439 : :
3440 [ - + ]: 28 : if (carrier_gained) {
3441 [ # # # # ]: 0 : log_link_info(link, "Gained carrier");
3442 : :
3443 : 0 : r = link_carrier_gained(link);
3444 [ # # ]: 0 : if (r < 0)
3445 : 0 : return r;
3446 [ - + ]: 28 : } else if (carrier_lost) {
3447 [ # # # # ]: 0 : log_link_info(link, "Lost carrier");
3448 : :
3449 : 0 : r = link_carrier_lost(link);
3450 [ # # ]: 0 : if (r < 0)
3451 : 0 : return r;
3452 : : }
3453 : :
3454 : 28 : return 0;
3455 : : }
3456 : :
3457 : 0 : static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
3458 : 0 : bool space = false;
3459 : : Iterator i;
3460 : : Link *link;
3461 : :
3462 [ # # ]: 0 : assert(f);
3463 [ # # ]: 0 : assert(prefix);
3464 : :
3465 [ # # ]: 0 : if (hashmap_isempty(h))
3466 : 0 : return;
3467 : :
3468 : 0 : fputs(prefix, f);
3469 [ # # ]: 0 : HASHMAP_FOREACH(link, h, i) {
3470 [ # # ]: 0 : if (space)
3471 : 0 : fputc(' ', f);
3472 : :
3473 : 0 : fprintf(f, "%i", link->ifindex);
3474 : 0 : space = true;
3475 : : }
3476 : :
3477 : 0 : fputc('\n', f);
3478 : : }
3479 : :
3480 : 0 : static void link_save_dns(FILE *f, struct in_addr_data *dns, unsigned n_dns, bool *space) {
3481 : : unsigned j;
3482 : : int r;
3483 : :
3484 [ # # ]: 0 : for (j = 0; j < n_dns; j++) {
3485 [ # # ]: 0 : _cleanup_free_ char *b = NULL;
3486 : :
3487 : 0 : r = in_addr_to_string(dns[j].family, &dns[j].address, &b);
3488 [ # # ]: 0 : if (r < 0) {
3489 [ # # ]: 0 : log_debug_errno(r, "Failed to format address, ignoring: %m");
3490 : 0 : continue;
3491 : : }
3492 : :
3493 [ # # ]: 0 : if (*space)
3494 : 0 : fputc(' ', f);
3495 : 0 : fputs(b, f);
3496 : 0 : *space = true;
3497 : : }
3498 : 0 : }
3499 : :
3500 : 0 : int link_save(Link *link) {
3501 : 0 : _cleanup_free_ char *temp_path = NULL;
3502 : 0 : _cleanup_fclose_ FILE *f = NULL;
3503 : : const char *admin_state, *oper_state, *carrier_state, *address_state;
3504 : : Address *a;
3505 : : Route *route;
3506 : : Iterator i;
3507 : : int r;
3508 : :
3509 [ # # ]: 0 : assert(link);
3510 [ # # ]: 0 : assert(link->state_file);
3511 [ # # ]: 0 : assert(link->lease_file);
3512 [ # # ]: 0 : assert(link->manager);
3513 : :
3514 [ # # ]: 0 : if (link->state == LINK_STATE_LINGER) {
3515 : 0 : (void) unlink(link->state_file);
3516 : 0 : return 0;
3517 : : }
3518 : :
3519 : 0 : link_lldp_save(link);
3520 : :
3521 : 0 : admin_state = link_state_to_string(link->state);
3522 [ # # ]: 0 : assert(admin_state);
3523 : :
3524 : 0 : oper_state = link_operstate_to_string(link->operstate);
3525 [ # # ]: 0 : assert(oper_state);
3526 : :
3527 : 0 : carrier_state = link_carrier_state_to_string(link->carrier_state);
3528 [ # # ]: 0 : assert(carrier_state);
3529 : :
3530 : 0 : address_state = link_address_state_to_string(link->address_state);
3531 [ # # ]: 0 : assert(address_state);
3532 : :
3533 : 0 : r = fopen_temporary(link->state_file, &f, &temp_path);
3534 [ # # ]: 0 : if (r < 0)
3535 : 0 : goto fail;
3536 : :
3537 : 0 : (void) fchmod(fileno(f), 0644);
3538 : :
3539 : 0 : fprintf(f,
3540 : : "# This is private data. Do not parse.\n"
3541 : : "ADMIN_STATE=%s\n"
3542 : : "OPER_STATE=%s\n"
3543 : : "CARRIER_STATE=%s\n"
3544 : : "ADDRESS_STATE=%s\n",
3545 : : admin_state, oper_state, carrier_state, address_state);
3546 : :
3547 [ # # ]: 0 : if (link->network) {
3548 : 0 : char **dhcp6_domains = NULL, **dhcp_domains = NULL;
3549 : 0 : const char *dhcp_domainname = NULL, *p;
3550 : 0 : sd_dhcp6_lease *dhcp6_lease = NULL;
3551 : : bool space;
3552 : :
3553 : 0 : fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
3554 : 0 : yes_no(link->network->required_for_online));
3555 : :
3556 : 0 : fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s\n",
3557 : 0 : strempty(link_operstate_to_string(link->network->required_operstate_for_online)));
3558 : :
3559 [ # # ]: 0 : if (link->dhcp6_client) {
3560 : 0 : r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
3561 [ # # # # ]: 0 : if (r < 0 && r != -ENOMSG)
3562 [ # # # # ]: 0 : log_link_debug(link, "No DHCPv6 lease");
3563 : : }
3564 : :
3565 : 0 : fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
3566 : :
3567 : 0 : fputs("DNS=", f);
3568 : 0 : space = false;
3569 : :
3570 [ # # ]: 0 : if (link->n_dns != (unsigned) -1)
3571 : 0 : link_save_dns(f, link->dns, link->n_dns, &space);
3572 : : else
3573 : 0 : link_save_dns(f, link->network->dns, link->network->n_dns, &space);
3574 : :
3575 [ # # ]: 0 : if (link->network->dhcp_use_dns &&
3576 [ # # ]: 0 : link->dhcp_lease) {
3577 : : const struct in_addr *addresses;
3578 : :
3579 : 0 : r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
3580 [ # # ]: 0 : if (r > 0)
3581 [ # # ]: 0 : if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
3582 : 0 : space = true;
3583 : : }
3584 : :
3585 [ # # # # ]: 0 : if (link->network->dhcp6_use_dns && dhcp6_lease) {
3586 : : struct in6_addr *in6_addrs;
3587 : :
3588 : 0 : r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
3589 [ # # ]: 0 : if (r > 0) {
3590 [ # # ]: 0 : if (space)
3591 : 0 : fputc(' ', f);
3592 : 0 : serialize_in6_addrs(f, in6_addrs, r);
3593 : 0 : space = true;
3594 : : }
3595 : : }
3596 : :
3597 : : /* Make sure to flush out old entries before we use the NDISC data */
3598 : 0 : ndisc_vacuum(link);
3599 : :
3600 [ # # # # ]: 0 : if (link->network->ipv6_accept_ra_use_dns && link->ndisc_rdnss) {
3601 : : NDiscRDNSS *dd;
3602 : :
3603 [ # # ]: 0 : SET_FOREACH(dd, link->ndisc_rdnss, i) {
3604 [ # # ]: 0 : if (space)
3605 : 0 : fputc(' ', f);
3606 : :
3607 : 0 : serialize_in6_addrs(f, &dd->address, 1);
3608 : 0 : space = true;
3609 : : }
3610 : : }
3611 : :
3612 : 0 : fputc('\n', f);
3613 : :
3614 : 0 : fputs("NTP=", f);
3615 : 0 : space = false;
3616 [ # # ]: 0 : fputstrv(f, link->ntp ?: link->network->ntp, NULL, &space);
3617 : :
3618 [ # # ]: 0 : if (link->network->dhcp_use_ntp &&
3619 [ # # ]: 0 : link->dhcp_lease) {
3620 : : const struct in_addr *addresses;
3621 : :
3622 : 0 : r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
3623 [ # # ]: 0 : if (r > 0)
3624 [ # # ]: 0 : if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
3625 : 0 : space = true;
3626 : : }
3627 : :
3628 [ # # # # ]: 0 : if (link->network->dhcp6_use_ntp && dhcp6_lease) {
3629 : : struct in6_addr *in6_addrs;
3630 : : char **hosts;
3631 : :
3632 : 0 : r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
3633 : : &in6_addrs);
3634 [ # # ]: 0 : if (r > 0) {
3635 [ # # ]: 0 : if (space)
3636 : 0 : fputc(' ', f);
3637 : 0 : serialize_in6_addrs(f, in6_addrs, r);
3638 : 0 : space = true;
3639 : : }
3640 : :
3641 : 0 : r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
3642 [ # # ]: 0 : if (r > 0)
3643 : 0 : fputstrv(f, hosts, NULL, &space);
3644 : : }
3645 : :
3646 : 0 : fputc('\n', f);
3647 : :
3648 [ # # ]: 0 : if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
3649 [ # # ]: 0 : if (link->dhcp_lease) {
3650 : 0 : (void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
3651 : 0 : (void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
3652 : : }
3653 [ # # ]: 0 : if (dhcp6_lease)
3654 : 0 : (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
3655 : : }
3656 : :
3657 : 0 : fputs("DOMAINS=", f);
3658 : 0 : space = false;
3659 [ # # # # ]: 0 : ORDERED_SET_FOREACH(p, link->search_domains ?: link->network->search_domains, i)
3660 : 0 : fputs_with_space(f, p, NULL, &space);
3661 : :
3662 [ # # ]: 0 : if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
3663 [ # # ]: 0 : if (dhcp_domainname)
3664 : 0 : fputs_with_space(f, dhcp_domainname, NULL, &space);
3665 [ # # ]: 0 : if (dhcp_domains)
3666 : 0 : fputstrv(f, dhcp_domains, NULL, &space);
3667 [ # # ]: 0 : if (dhcp6_domains)
3668 : 0 : fputstrv(f, dhcp6_domains, NULL, &space);
3669 : : }
3670 : :
3671 [ # # ]: 0 : if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_YES) {
3672 : : NDiscDNSSL *dd;
3673 : :
3674 [ # # ]: 0 : SET_FOREACH(dd, link->ndisc_dnssl, i)
3675 : 0 : fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
3676 : : }
3677 : :
3678 : 0 : fputc('\n', f);
3679 : :
3680 : 0 : fputs("ROUTE_DOMAINS=", f);
3681 : 0 : space = false;
3682 [ # # # # ]: 0 : ORDERED_SET_FOREACH(p, link->route_domains ?: link->network->route_domains, i)
3683 : 0 : fputs_with_space(f, p, NULL, &space);
3684 : :
3685 [ # # ]: 0 : if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
3686 [ # # ]: 0 : if (dhcp_domainname)
3687 : 0 : fputs_with_space(f, dhcp_domainname, NULL, &space);
3688 [ # # ]: 0 : if (dhcp_domains)
3689 : 0 : fputstrv(f, dhcp_domains, NULL, &space);
3690 [ # # ]: 0 : if (dhcp6_domains)
3691 : 0 : fputstrv(f, dhcp6_domains, NULL, &space);
3692 : : }
3693 : :
3694 [ # # ]: 0 : if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_ROUTE) {
3695 : : NDiscDNSSL *dd;
3696 : :
3697 [ # # ]: 0 : SET_FOREACH(dd, link->ndisc_dnssl, i)
3698 : 0 : fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
3699 : : }
3700 : :
3701 : 0 : fputc('\n', f);
3702 : :
3703 : 0 : fprintf(f, "LLMNR=%s\n",
3704 [ # # ]: 0 : resolve_support_to_string(link->llmnr >= 0 ? link->llmnr : link->network->llmnr));
3705 : 0 : fprintf(f, "MDNS=%s\n",
3706 [ # # ]: 0 : resolve_support_to_string(link->mdns >= 0 ? link->mdns : link->network->mdns));
3707 [ # # ]: 0 : if (link->dns_default_route >= 0)
3708 : 0 : fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->dns_default_route));
3709 [ # # ]: 0 : else if (link->network->dns_default_route >= 0)
3710 : 0 : fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->network->dns_default_route));
3711 : :
3712 [ # # ]: 0 : if (link->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
3713 : 0 : fprintf(f, "DNS_OVER_TLS=%s\n",
3714 : : dns_over_tls_mode_to_string(link->dns_over_tls_mode));
3715 [ # # ]: 0 : else if (link->network->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
3716 : 0 : fprintf(f, "DNS_OVER_TLS=%s\n",
3717 : 0 : dns_over_tls_mode_to_string(link->network->dns_over_tls_mode));
3718 : :
3719 [ # # ]: 0 : if (link->dnssec_mode != _DNSSEC_MODE_INVALID)
3720 : 0 : fprintf(f, "DNSSEC=%s\n",
3721 : : dnssec_mode_to_string(link->dnssec_mode));
3722 [ # # ]: 0 : else if (link->network->dnssec_mode != _DNSSEC_MODE_INVALID)
3723 : 0 : fprintf(f, "DNSSEC=%s\n",
3724 : 0 : dnssec_mode_to_string(link->network->dnssec_mode));
3725 : :
3726 [ # # ]: 0 : if (!set_isempty(link->dnssec_negative_trust_anchors)) {
3727 : : const char *n;
3728 : :
3729 : 0 : fputs("DNSSEC_NTA=", f);
3730 : 0 : space = false;
3731 [ # # ]: 0 : SET_FOREACH(n, link->dnssec_negative_trust_anchors, i)
3732 : 0 : fputs_with_space(f, n, NULL, &space);
3733 : 0 : fputc('\n', f);
3734 [ # # ]: 0 : } else if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
3735 : : const char *n;
3736 : :
3737 : 0 : fputs("DNSSEC_NTA=", f);
3738 : 0 : space = false;
3739 [ # # ]: 0 : SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
3740 : 0 : fputs_with_space(f, n, NULL, &space);
3741 : 0 : fputc('\n', f);
3742 : : }
3743 : :
3744 : 0 : fputs("ADDRESSES=", f);
3745 : 0 : space = false;
3746 [ # # ]: 0 : SET_FOREACH(a, link->addresses, i) {
3747 [ # # ]: 0 : _cleanup_free_ char *address_str = NULL;
3748 : :
3749 : 0 : r = in_addr_to_string(a->family, &a->in_addr, &address_str);
3750 [ # # ]: 0 : if (r < 0)
3751 : 0 : goto fail;
3752 : :
3753 [ # # ]: 0 : fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
3754 : 0 : space = true;
3755 : : }
3756 : 0 : fputc('\n', f);
3757 : :
3758 : 0 : fputs("ROUTES=", f);
3759 : 0 : space = false;
3760 [ # # ]: 0 : SET_FOREACH(route, link->routes, i) {
3761 [ # # ]: 0 : _cleanup_free_ char *route_str = NULL;
3762 : :
3763 : 0 : r = in_addr_to_string(route->family, &route->dst, &route_str);
3764 [ # # ]: 0 : if (r < 0)
3765 : 0 : goto fail;
3766 : :
3767 : 0 : fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%"PRIu32"/"USEC_FMT,
3768 : 0 : space ? " " : "", route_str,
3769 [ # # ]: 0 : route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
3770 : 0 : space = true;
3771 : : }
3772 : :
3773 : 0 : fputc('\n', f);
3774 : : }
3775 : :
3776 : 0 : print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
3777 : 0 : print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
3778 : :
3779 [ # # ]: 0 : if (link->dhcp_lease) {
3780 : : struct in_addr address;
3781 : 0 : const char *tz = NULL;
3782 : :
3783 [ # # ]: 0 : assert(link->network);
3784 : :
3785 : 0 : r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
3786 [ # # ]: 0 : if (r >= 0)
3787 : 0 : fprintf(f, "TIMEZONE=%s\n", tz);
3788 : :
3789 : 0 : r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
3790 [ # # ]: 0 : if (r >= 0) {
3791 : 0 : fputs("DHCP4_ADDRESS=", f);
3792 : 0 : serialize_in_addrs(f, &address, 1, false, NULL);
3793 : 0 : fputc('\n', f);
3794 : : }
3795 : :
3796 : 0 : r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
3797 [ # # ]: 0 : if (r < 0)
3798 : 0 : goto fail;
3799 : :
3800 : 0 : fprintf(f,
3801 : : "DHCP_LEASE=%s\n",
3802 : : link->lease_file);
3803 : : } else
3804 : 0 : (void) unlink(link->lease_file);
3805 : :
3806 [ # # ]: 0 : if (link->ipv4ll) {
3807 : : struct in_addr address;
3808 : :
3809 : 0 : r = sd_ipv4ll_get_address(link->ipv4ll, &address);
3810 [ # # ]: 0 : if (r >= 0) {
3811 : 0 : fputs("IPV4LL_ADDRESS=", f);
3812 : 0 : serialize_in_addrs(f, &address, 1, false, NULL);
3813 : 0 : fputc('\n', f);
3814 : : }
3815 : : }
3816 : :
3817 : 0 : r = fflush_and_check(f);
3818 [ # # ]: 0 : if (r < 0)
3819 : 0 : goto fail;
3820 : :
3821 [ # # ]: 0 : if (rename(temp_path, link->state_file) < 0) {
3822 : 0 : r = -errno;
3823 : 0 : goto fail;
3824 : : }
3825 : :
3826 : 0 : return 0;
3827 : :
3828 : 0 : fail:
3829 : 0 : (void) unlink(link->state_file);
3830 [ # # ]: 0 : if (temp_path)
3831 : 0 : (void) unlink(temp_path);
3832 : :
3833 [ # # # # ]: 0 : return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
3834 : : }
3835 : :
3836 : : /* The serialized state in /run is no longer up-to-date. */
3837 : 24 : void link_dirty(Link *link) {
3838 : : int r;
3839 : :
3840 [ - + ]: 24 : assert(link);
3841 : :
3842 : : /* mark manager dirty as link is dirty */
3843 : 24 : manager_dirty(link->manager);
3844 : :
3845 : 24 : r = set_ensure_allocated(&link->manager->dirty_links, NULL);
3846 [ - + ]: 24 : if (r < 0)
3847 : : /* allocation errors are ignored */
3848 : 0 : return;
3849 : :
3850 : 24 : r = set_put(link->manager->dirty_links, link);
3851 [ - + ]: 24 : if (r <= 0)
3852 : : /* don't take another ref if the link was already dirty */
3853 : 0 : return;
3854 : :
3855 : 24 : link_ref(link);
3856 : : }
3857 : :
3858 : : /* The serialized state in /run is up-to-date */
3859 : 0 : void link_clean(Link *link) {
3860 [ # # ]: 0 : assert(link);
3861 [ # # ]: 0 : assert(link->manager);
3862 : :
3863 : 0 : link_unref(set_remove(link->manager->dirty_links, link));
3864 : 0 : }
3865 : :
3866 : : static const char* const link_state_table[_LINK_STATE_MAX] = {
3867 : : [LINK_STATE_PENDING] = "pending",
3868 : : [LINK_STATE_INITIALIZED] = "initialized",
3869 : : [LINK_STATE_CONFIGURING] = "configuring",
3870 : : [LINK_STATE_CONFIGURED] = "configured",
3871 : : [LINK_STATE_UNMANAGED] = "unmanaged",
3872 : : [LINK_STATE_FAILED] = "failed",
3873 : : [LINK_STATE_LINGER] = "linger",
3874 : : };
3875 : :
3876 [ + - - + ]: 56 : DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|