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