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