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