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