]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
sd-netlink: fix sd_netlink_inc_rcvbuf() prototype
[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 1446
720bec40
TY
1447 /* start DHCPv6 client in stateless mode */
1448 r = dhcp6_request_address(link, true);
63348d13 1449 if (r < 0 && r != -EBUSY)
e7ab854c 1450 return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
720bec40
TY
1451 else
1452 log_link_debug(link, "Acquiring DHCPv6 lease");
e7ab854c
TG
1453 }
1454
1455 if (link_ipv6_accept_ra_enabled(link)) {
1456 assert(link->ndisc_router_discovery);
1457
1458 log_link_debug(link, "Discovering IPv6 routers");
1459
1460 r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
63348d13 1461 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1462 return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
1463 }
1464
1465 return 0;
1466}
1467
6fc25497 1468static int link_acquire_ipv4_conf(Link *link) {
ff254138
TG
1469 int r;
1470
1471 assert(link);
1472 assert(link->network);
ff254138
TG
1473 assert(link->manager);
1474 assert(link->manager->event);
1475
78c958f8 1476 if (link_ipv4ll_enabled(link)) {
eb34d4af 1477 assert(link->ipv4ll);
ff254138 1478
6a7a4e4d 1479 log_link_debug(link, "Acquiring IPv4 link-local address");
5c1d3fc9
UTL
1480
1481 r = sd_ipv4ll_start(link->ipv4ll);
6a7a4e4d
LP
1482 if (r < 0)
1483 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
5c1d3fc9
UTL
1484 }
1485
78c958f8 1486 if (link_dhcp4_enabled(link)) {
eb34d4af 1487 assert(link->dhcp_client);
ff254138 1488
6a7a4e4d 1489 log_link_debug(link, "Acquiring DHCPv4 lease");
ab47d620 1490
5c1d3fc9 1491 r = sd_dhcp_client_start(link->dhcp_client);
6a7a4e4d
LP
1492 if (r < 0)
1493 return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
5c1d3fc9 1494 }
ff254138 1495
6fc25497
SS
1496 return 0;
1497}
1498
1499static int link_acquire_conf(Link *link) {
1500 int r;
1501
1502 assert(link);
1503
1504 r = link_acquire_ipv4_conf(link);
1505 if (r < 0)
1506 return r;
1507
1508 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
1509 r = link_acquire_ipv6_conf(link);
1510 if (r < 0)
1511 return r;
1512 }
1513
7272b25e
LP
1514 if (link_lldp_emit_enabled(link)) {
1515 r = link_lldp_emit_start(link);
8e1ad1ea
LP
1516 if (r < 0)
1517 return log_link_warning_errno(link, r, "Failed to start LLDP transmission: %m");
1518 }
1519
ff254138
TG
1520 return 0;
1521}
1522
a61bb41c 1523bool link_has_carrier(Link *link) {
deb2e523
TG
1524 /* see Documentation/networking/operstates.txt in the kernel sources */
1525
a61bb41c 1526 if (link->kernel_operstate == IF_OPER_UP)
deb2e523
TG
1527 return true;
1528
a61bb41c 1529 if (link->kernel_operstate == IF_OPER_UNKNOWN)
deb2e523 1530 /* operstate may not be implemented, so fall back to flags */
a61bb41c 1531 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
deb2e523
TG
1532 return true;
1533
1534 return false;
1535}
1536
1c4baffc 1537static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1538 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
1539 int r;
1540
1746cf2a
TG
1541 assert(link);
1542
5da8149f 1543 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
1544 return 1;
1545
1c4baffc 1546 r = sd_netlink_message_get_errno(m);
6a7a4e4d
LP
1547 if (r < 0)
1548 /* we warn but don't fail the link, as it may be
1549 brought up later */
a2fae7bb 1550 log_link_warning_errno(link, r, "Could not bring up interface: %m");
45ad2c13 1551
f882c247
TG
1552 return 1;
1553}
1554
1555static int link_up(Link *link) {
4afd3348 1556 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
5c3072ea 1557 uint8_t ipv6ll_mode;
f579559b
TG
1558 int r;
1559
f882c247 1560 assert(link);
c106cc36 1561 assert(link->network);
f882c247
TG
1562 assert(link->manager);
1563 assert(link->manager->rtnl);
1564
6a7a4e4d 1565 log_link_debug(link, "Bringing link up");
449f7554 1566
6a7a4e4d
LP
1567 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1568 if (r < 0)
1569 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
f579559b 1570
2b2d8603
TY
1571 /* set it free if not enslaved with networkd */
1572 if (!link->network->bridge && !link->network->bond) {
1573 r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
1574 if (r < 0)
1575 return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
1576 }
1577
5d4795f3 1578 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
6a7a4e4d
LP
1579 if (r < 0)
1580 return log_link_error_errno(link, r, "Could not set link flags: %m");
fc25d7f8 1581
c106cc36 1582 if (link->network->mac) {
1c4baffc 1583 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
6a7a4e4d
LP
1584 if (r < 0)
1585 return log_link_error_errno(link, r, "Could not set MAC address: %m");
c106cc36
TG
1586 }
1587
4cef7fe3 1588 /* If IPv6 not configured (no static IPv6 address and IPv6LL autoconfiguration is disabled)
2b00a4e0 1589 for this interface, or if it is a bridge slave, then disable IPv6 else enable it. */
439689c6
SS
1590 (void) link_enable_ipv6(link);
1591
c106cc36 1592 if (link->network->mtu) {
439689c6
SS
1593 /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
1594 on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
1595 if (link_ipv6_enabled(link) && link->network->mtu < IPV6_MIN_MTU) {
1596
1597 log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as "
1598 "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m");
1599
1600 link->network->mtu = IPV6_MIN_MTU;
1601 }
1602
1c4baffc 1603 r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
6a7a4e4d
LP
1604 if (r < 0)
1605 return log_link_error_errno(link, r, "Could not set MTU: %m");
c106cc36
TG
1606 }
1607
1c4baffc 1608 r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
6a7a4e4d
LP
1609 if (r < 0)
1610 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
d0d6a4cd 1611
439689c6 1612 if (link_ipv6_enabled(link)) {
01d28f81 1613 /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
1c4baffc 1614 r = sd_netlink_message_open_container(req, AF_INET6);
01d28f81
TG
1615 if (r < 0)
1616 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
d0d6a4cd 1617
fbc38f23
TY
1618 if (!link_ipv6ll_enabled(link))
1619 ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
1620 else {
1621 const char *p = NULL;
1622 _cleanup_free_ char *stable_secret = NULL;
1623
1624 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/stable_secret");
1625 r = read_one_line_file(p, &stable_secret);
1626
1627 if (r < 0)
1628 ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
1629 else
1630 ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
1631 }
1c4baffc 1632 r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
01d28f81
TG
1633 if (r < 0)
1634 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
d0d6a4cd 1635
01d28f81 1636 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1c4baffc 1637 r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
01d28f81
TG
1638 if (r < 0)
1639 return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
1640 }
1641
1c4baffc 1642 r = sd_netlink_message_close_container(req);
6a7a4e4d 1643 if (r < 0)
01d28f81 1644 return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
7f77697a 1645 }
d0d6a4cd 1646
1c4baffc 1647 r = sd_netlink_message_close_container(req);
6a7a4e4d
LP
1648 if (r < 0)
1649 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
d0d6a4cd 1650
1c4baffc 1651 r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
6a7a4e4d
LP
1652 if (r < 0)
1653 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
f579559b 1654
b226d99b
TG
1655 link_ref(link);
1656
f882c247
TG
1657 return 0;
1658}
1659
1c4baffc 1660static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
0d4ad91d
AR
1661 _cleanup_link_unref_ Link *link = userdata;
1662 int r;
1663
1664 assert(link);
1665
1666 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1667 return 1;
1668
1c4baffc 1669 r = sd_netlink_message_get_errno(m);
0d4ad91d 1670 if (r < 0)
a2fae7bb 1671 log_link_warning_errno(link, r, "Could not bring down interface: %m");
0d4ad91d
AR
1672
1673 return 1;
1674}
1675
1676static int link_down(Link *link) {
4afd3348 1677 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
0d4ad91d
AR
1678 int r;
1679
1680 assert(link);
1681 assert(link->manager);
1682 assert(link->manager->rtnl);
1683
6a7a4e4d 1684 log_link_debug(link, "Bringing link down");
0d4ad91d
AR
1685
1686 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1687 RTM_SETLINK, link->ifindex);
6a7a4e4d
LP
1688 if (r < 0)
1689 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
0d4ad91d
AR
1690
1691 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
6a7a4e4d
LP
1692 if (r < 0)
1693 return log_link_error_errno(link, r, "Could not set link flags: %m");
0d4ad91d 1694
1c4baffc 1695 r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
6a7a4e4d
LP
1696 if (r < 0)
1697 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
0d4ad91d
AR
1698
1699 link_ref(link);
1700
1701 return 0;
1702}
1703
1704static int link_handle_bound_to_list(Link *link) {
1705 Link *l;
1706 Iterator i;
1707 int r;
1708 bool required_up = false;
1709 bool link_is_up = false;
1710
1711 assert(link);
1712
1713 if (hashmap_isempty(link->bound_to_links))
1714 return 0;
1715
1716 if (link->flags & IFF_UP)
1717 link_is_up = true;
1718
1719 HASHMAP_FOREACH (l, link->bound_to_links, i)
1720 if (link_has_carrier(l)) {
1721 required_up = true;
1722 break;
1723 }
1724
1725 if (!required_up && link_is_up) {
1726 r = link_down(link);
1727 if (r < 0)
1728 return r;
1729 } else if (required_up && !link_is_up) {
1730 r = link_up(link);
1731 if (r < 0)
1732 return r;
1733 }
1734
1735 return 0;
1736}
1737
1738static int link_handle_bound_by_list(Link *link) {
1739 Iterator i;
1740 Link *l;
1741 int r;
1742
1743 assert(link);
1744
1745 if (hashmap_isempty(link->bound_by_links))
1746 return 0;
1747
1748 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1749 r = link_handle_bound_to_list(l);
1750 if (r < 0)
1751 return r;
1752 }
1753
1754 return 0;
1755}
1756
1757static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1758 int r;
1759
1760 assert(link);
1761 assert(carrier);
1762
1763 if (link == carrier)
1764 return 0;
1765
1766 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1767 return 0;
1768
1769 r = hashmap_ensure_allocated(h, NULL);
1770 if (r < 0)
1771 return r;
1772
1773 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1774 if (r < 0)
1775 return r;
1776
1777 return 0;
1778}
1779
1780static int link_new_bound_by_list(Link *link) {
1781 Manager *m;
1782 Link *carrier;
1783 Iterator i;
1784 int r;
1785 bool list_updated = false;
1786
1787 assert(link);
1788 assert(link->manager);
1789
1790 m = link->manager;
1791
b295beea 1792 HASHMAP_FOREACH(carrier, m->links, i) {
0d4ad91d
AR
1793 if (!carrier->network)
1794 continue;
1795
1796 if (strv_isempty(carrier->network->bind_carrier))
1797 continue;
1798
1799 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1800 r = link_put_carrier(link, carrier, &link->bound_by_links);
1801 if (r < 0)
1802 return r;
1803
1804 list_updated = true;
1805 }
1806 }
1807
1808 if (list_updated)
84de38c5 1809 link_dirty(link);
0d4ad91d 1810
b295beea 1811 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
0d4ad91d
AR
1812 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1813 if (r < 0)
1814 return r;
1815
84de38c5 1816 link_dirty(carrier);
0d4ad91d
AR
1817 }
1818
1819 return 0;
1820}
1821
1822static int link_new_bound_to_list(Link *link) {
1823 Manager *m;
1824 Link *carrier;
1825 Iterator i;
1826 int r;
1827 bool list_updated = false;
1828
1829 assert(link);
1830 assert(link->manager);
1831
1832 if (!link->network)
1833 return 0;
1834
1835 if (strv_isempty(link->network->bind_carrier))
1836 return 0;
1837
1838 m = link->manager;
1839
1840 HASHMAP_FOREACH (carrier, m->links, i) {
1841 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1842 r = link_put_carrier(link, carrier, &link->bound_to_links);
1843 if (r < 0)
1844 return r;
1845
1846 list_updated = true;
1847 }
1848 }
1849
1850 if (list_updated)
84de38c5 1851 link_dirty(link);
0d4ad91d
AR
1852
1853 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1854 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1855 if (r < 0)
1856 return r;
1857
84de38c5 1858 link_dirty(carrier);
0d4ad91d
AR
1859 }
1860
1861 return 0;
1862}
1863
1864static int link_new_carrier_maps(Link *link) {
1865 int r;
1866
1867 r = link_new_bound_by_list(link);
1868 if (r < 0)
1869 return r;
1870
1871 r = link_handle_bound_by_list(link);
1872 if (r < 0)
1873 return r;
1874
1875 r = link_new_bound_to_list(link);
1876 if (r < 0)
1877 return r;
1878
1879 r = link_handle_bound_to_list(link);
1880 if (r < 0)
1881 return r;
1882
1883 return 0;
1884}
1885
1886static void link_free_bound_to_list(Link *link) {
1887 Link *bound_to;
1888 Iterator i;
1889
1890 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1891 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1892
1893 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
84de38c5 1894 link_dirty(bound_to);
0d4ad91d
AR
1895 }
1896
1897 return;
1898}
1899
1900static void link_free_bound_by_list(Link *link) {
1901 Link *bound_by;
1902 Iterator i;
1903
1904 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1905 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1906
1907 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
84de38c5 1908 link_dirty(bound_by);
0d4ad91d
AR
1909 link_handle_bound_to_list(bound_by);
1910 }
1911 }
1912
1913 return;
1914}
1915
1916static void link_free_carrier_maps(Link *link) {
1917 bool list_updated = false;
1918
1919 assert(link);
1920
1921 if (!hashmap_isempty(link->bound_to_links)) {
1922 link_free_bound_to_list(link);
1923 list_updated = true;
1924 }
1925
1926 if (!hashmap_isempty(link->bound_by_links)) {
1927 link_free_bound_by_list(link);
1928 list_updated = true;
1929 }
1930
1931 if (list_updated)
84de38c5 1932 link_dirty(link);
0d4ad91d
AR
1933
1934 return;
1935}
1936
1937void link_drop(Link *link) {
1938 if (!link || link->state == LINK_STATE_LINGER)
1939 return;
1940
1941 link_set_state(link, LINK_STATE_LINGER);
1942
1943 link_free_carrier_maps(link);
1944
6a7a4e4d 1945 log_link_debug(link, "Link removed");
0d4ad91d 1946
84de38c5 1947 (void)unlink(link->state_file);
0d4ad91d
AR
1948 link_unref(link);
1949
1950 return;
1951}
1952
3f265037 1953static int link_joined(Link *link) {
f882c247
TG
1954 int r;
1955
ef1ba606 1956 assert(link);
f5be5601 1957 assert(link->network);
dd3efc09 1958
0d4ad91d
AR
1959 if (!hashmap_isempty(link->bound_to_links)) {
1960 r = link_handle_bound_to_list(link);
1961 if (r < 0)
1962 return r;
1963 } else if (!(link->flags & IFF_UP)) {
505f8da7
TG
1964 r = link_up(link);
1965 if (r < 0) {
1966 link_enter_failed(link);
1967 return r;
1968 }
ef1ba606 1969 }
f882c247 1970
9ed794a3 1971 if (link->network->bridge) {
e1853b00 1972 r = link_set_bridge(link);
6a7a4e4d
LP
1973 if (r < 0)
1974 log_link_error_errno(link, r, "Could not set bridge message: %m");
e1853b00
SS
1975 }
1976
fb6730c4 1977 return link_enter_set_addresses(link);
02b59d57
TG
1978}
1979
62e2d5bb 1980static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1981 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1982 int r;
1983
1746cf2a 1984 assert(link);
ef1ba606 1985 assert(link->network);
02b59d57 1986
313cefa1 1987 link->enslaving--;
52433f6b 1988
5da8149f 1989 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1990 return 1;
1991
1c4baffc 1992 r = sd_netlink_message_get_errno(m);
856f962c 1993 if (r < 0 && r != -EEXIST) {
a2fae7bb 1994 log_link_error_errno(link, r, "Could not join netdev: %m");
ef1ba606
TG
1995 link_enter_failed(link);
1996 return 1;
ba179154 1997 } else
6a7a4e4d 1998 log_link_debug(link, "Joined netdev");
02b59d57 1999
856f962c 2000 if (link->enslaving <= 0)
3f265037 2001 link_joined(link);
02b59d57
TG
2002
2003 return 1;
2004}
2005
3f265037 2006static int link_enter_join_netdev(Link *link) {
6a0a2f86 2007 NetDev *netdev;
672682a6 2008 Iterator i;
02b59d57
TG
2009 int r;
2010
2011 assert(link);
2012 assert(link->network);
8434fd5c 2013 assert(link->state == LINK_STATE_PENDING);
02b59d57 2014
e331e246 2015 link_set_state(link, LINK_STATE_ENSLAVING);
02b59d57 2016
84de38c5 2017 link_dirty(link);
fe8db0c5 2018
7951dea2
SS
2019 if (!link->network->bridge &&
2020 !link->network->bond &&
6a0a2f86 2021 hashmap_isempty(link->network->stacked_netdevs))
3f265037 2022 return link_joined(link);
02b59d57 2023
d9c67ea1 2024 if (link->network->bond) {
f2341e0a
LP
2025 log_struct(LOG_DEBUG,
2026 LOG_LINK_INTERFACE(link),
2027 LOG_NETDEV_INTERFACE(link->network->bond),
2028 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
2029 NULL);
2030
2031 r = netdev_join(link->network->bond, link, netdev_join_handler);
52433f6b 2032 if (r < 0) {
f2341e0a
LP
2033 log_struct_errno(LOG_WARNING, r,
2034 LOG_LINK_INTERFACE(link),
2035 LOG_NETDEV_INTERFACE(link->network->bond),
2036 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
2037 NULL);
2038
52433f6b
TG
2039 link_enter_failed(link);
2040 return r;
2041 }
2042
313cefa1 2043 link->enslaving++;
0ad6148e
MO
2044 }
2045
d9c67ea1 2046 if (link->network->bridge) {
f2341e0a
LP
2047 log_struct(LOG_DEBUG,
2048 LOG_LINK_INTERFACE(link),
2049 LOG_NETDEV_INTERFACE(link->network->bridge),
2050 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
2051 NULL);
2052
2053 r = netdev_join(link->network->bridge, link, netdev_join_handler);
0ad6148e 2054 if (r < 0) {
f2341e0a
LP
2055 log_struct_errno(LOG_WARNING, r,
2056 LOG_LINK_INTERFACE(link),
2057 LOG_NETDEV_INTERFACE(link->network->bridge),
2058 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
2059 NULL),
0ad6148e
MO
2060 link_enter_failed(link);
2061 return r;
2062 }
2063
313cefa1 2064 link->enslaving++;
52433f6b
TG
2065 }
2066
6a0a2f86 2067 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
7951dea2 2068
f2341e0a
LP
2069 log_struct(LOG_DEBUG,
2070 LOG_LINK_INTERFACE(link),
2071 LOG_NETDEV_INTERFACE(netdev),
2072 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
2073 NULL);
2074
2075 r = netdev_join(netdev, link, netdev_join_handler);
7951dea2 2076 if (r < 0) {
f2341e0a
LP
2077 log_struct_errno(LOG_WARNING, r,
2078 LOG_LINK_INTERFACE(link),
2079 LOG_NETDEV_INTERFACE(netdev),
2080 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
2081 NULL);
326cb406
SS
2082 link_enter_failed(link);
2083 return r;
2084 }
2085
313cefa1 2086 link->enslaving++;
326cb406
SS
2087 }
2088
ef1ba606
TG
2089 return 0;
2090}
2091
769d324c 2092static int link_set_ipv4_forward(Link *link) {
5a8bcb67
LP
2093 int r;
2094
765afd5c 2095 if (!link_ipv4_forward_enabled(link))
15dee3f0
LP
2096 return 0;
2097
765afd5c
LP
2098 /* We propagate the forwarding flag from one interface to the
2099 * global setting one way. This means: as long as at least one
2100 * interface was configured at any time that had IP forwarding
2101 * enabled the setting will stay on for good. We do this
2102 * primarily to keep IPv4 and IPv6 packet forwarding behaviour
2103 * somewhat in sync (see below). */
15dee3f0 2104
765afd5c 2105 r = write_string_file("/proc/sys/net/ipv4/ip_forward", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 2106 if (r < 0)
765afd5c 2107 log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
43c6d5ab 2108
769d324c
LP
2109 return 0;
2110}
2111
2112static int link_set_ipv6_forward(Link *link) {
769d324c
LP
2113 int r;
2114
765afd5c 2115 if (!link_ipv6_forward_enabled(link))
8add5f79
NO
2116 return 0;
2117
765afd5c
LP
2118 /* On Linux, the IPv6 stack does not not know a per-interface
2119 * packet forwarding setting: either packet forwarding is on
2120 * for all, or off for all. We hence don't bother with a
2121 * per-interface setting, but simply propagate the interface
2122 * flag, if it is set, to the global flag, one-way. Note that
2123 * while IPv4 would allow a per-interface flag, we expose the
2124 * same behaviour there and also propagate the setting from
2125 * one to all, to keep things simple (see above). */
15dee3f0 2126
765afd5c 2127 r = write_string_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 2128 if (r < 0)
765afd5c 2129 log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
5a8bcb67
LP
2130
2131 return 0;
2132}
2133
49092e22 2134static int link_set_ipv6_privacy_extensions(Link *link) {
1f0d9695
LP
2135 char buf[DECIMAL_STR_MAX(unsigned) + 1];
2136 IPv6PrivacyExtensions s;
49092e22
SS
2137 const char *p = NULL;
2138 int r;
2139
1f0d9695 2140 s = link_ipv6_privacy_extensions(link);
66a6bd68 2141 if (s < 0)
49092e22
SS
2142 return 0;
2143
2144 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
66a6bd68 2145 xsprintf(buf, "%u", (unsigned) link->network->ipv6_privacy_extensions);
49092e22 2146
eb3da901
LP
2147 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
2148 if (r < 0)
49092e22
SS
2149 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
2150
2151 return 0;
2152}
2153
4f2e437a 2154static int link_set_ipv6_accept_ra(Link *link) {
3b015d40 2155 const char *p = NULL;
4f2e437a
SS
2156 int r;
2157
2158 /* Make this a NOP if IPv6 is not available */
2159 if (!socket_ipv6_is_supported())
2160 return 0;
2161
2162 if (link->flags & IFF_LOOPBACK)
2163 return 0;
2164
d68e2e59
LP
2165 if (!link->network)
2166 return 0;
2167
4f2e437a 2168 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
4f2e437a 2169
0053598f 2170 /* We handle router advertisements ourselves, tell the kernel to GTFO */
fe307276 2171 r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 2172 if (r < 0)
fe307276 2173 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
4f2e437a
SS
2174
2175 return 0;
2176}
2177
8749cbcd 2178static int link_set_ipv6_dad_transmits(Link *link) {
66a6bd68 2179 char buf[DECIMAL_STR_MAX(int) + 1];
8749cbcd
SS
2180 const char *p = NULL;
2181 int r;
2182
2183 /* Make this a NOP if IPv6 is not available */
2184 if (!socket_ipv6_is_supported())
2185 return 0;
2186
2187 if (link->flags & IFF_LOOPBACK)
2188 return 0;
2189
d68e2e59
LP
2190 if (!link->network)
2191 return 0;
2192
8749cbcd
SS
2193 if (link->network->ipv6_dad_transmits < 0)
2194 return 0;
2195
2196 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
66a6bd68 2197 xsprintf(buf, "%i", link->network->ipv6_dad_transmits);
8749cbcd 2198
eb3da901
LP
2199 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
2200 if (r < 0)
8749cbcd 2201 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
8749cbcd
SS
2202
2203 return 0;
2204}
2205
b69c3180 2206static int link_set_ipv6_hop_limit(Link *link) {
66a6bd68 2207 char buf[DECIMAL_STR_MAX(int) + 1];
b69c3180
SS
2208 const char *p = NULL;
2209 int r;
2210
2211 /* Make this a NOP if IPv6 is not available */
2212 if (!socket_ipv6_is_supported())
2213 return 0;
2214
2215 if (link->flags & IFF_LOOPBACK)
2216 return 0;
2217
d68e2e59
LP
2218 if (!link->network)
2219 return 0;
2220
b69c3180
SS
2221 if (link->network->ipv6_hop_limit < 0)
2222 return 0;
2223
2224 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
66a6bd68 2225 xsprintf(buf, "%i", link->network->ipv6_hop_limit);
b69c3180 2226
eb3da901
LP
2227 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
2228 if (r < 0)
b69c3180 2229 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
b69c3180
SS
2230
2231 return 0;
2232}
2233
5e5b137a
TG
2234static int link_drop_foreign_config(Link *link) {
2235 Address *address;
2236 Route *route;
2237 Iterator i;
2238 int r;
2239
2240 SET_FOREACH(address, link->addresses_foreign, i) {
fe307276 2241 /* we consider IPv6LL addresses to be managed by the kernel */
5e5b137a
TG
2242 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2243 continue;
2244
2245 r = address_remove(address, link, link_address_remove_handler);
2246 if (r < 0)
2247 return r;
2248 }
2249
2250 SET_FOREACH(route, link->routes_foreign, i) {
fe307276 2251 /* do not touch routes managed by the kernel */
5e5b137a
TG
2252 if (route->protocol == RTPROT_KERNEL)
2253 continue;
2254
2255 r = route_remove(route, link, link_address_remove_handler);
2256 if (r < 0)
2257 return r;
2258 }
2259
2260 return 0;
2261}
2262
273eec24
LP
2263static int link_update_lldp(Link *link) {
2264 int r;
2265
2266 assert(link);
2267
2268 if (!link->lldp)
2269 return 0;
2270
2271 if (link->flags & IFF_UP) {
2272 r = sd_lldp_start(link->lldp);
2273 if (r > 0)
2274 log_link_debug(link, "Started LLDP.");
2275 } else {
2276 r = sd_lldp_stop(link->lldp);
2277 if (r > 0)
2278 log_link_debug(link, "Stopped LLDP.");
2279 }
2280
2281 return r;
2282}
2283
a748b692 2284static int link_configure(Link *link) {
02b59d57
TG
2285 int r;
2286
ef1ba606 2287 assert(link);
b22d8a00 2288 assert(link->network);
8434fd5c 2289 assert(link->state == LINK_STATE_PENDING);
a748b692 2290
02e28621
ДГ
2291 /* Drop foreign config, but ignore loopback or critical devices.
2292 * We do not want to remove loopback address or addresses used for root NFS. */
2293 if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) {
e5d44b34
CH
2294 r = link_drop_foreign_config(link);
2295 if (r < 0)
2296 return r;
2297 }
5e5b137a 2298
b98b483b
AR
2299 r = link_set_bridge_fdb(link);
2300 if (r < 0)
2301 return r;
2302
23d8b221
SS
2303 r = link_set_proxy_arp(link);
2304 if (r < 0)
2305 return r;
2306
769d324c
LP
2307 r = link_set_ipv4_forward(link);
2308 if (r < 0)
2309 return r;
2310
2311 r = link_set_ipv6_forward(link);
5a8bcb67
LP
2312 if (r < 0)
2313 return r;
2314
49092e22
SS
2315 r = link_set_ipv6_privacy_extensions(link);
2316 if (r < 0)
2317 return r;
2318
4f2e437a
SS
2319 r = link_set_ipv6_accept_ra(link);
2320 if (r < 0)
2321 return r;
2322
8749cbcd
SS
2323 r = link_set_ipv6_dad_transmits(link);
2324 if (r < 0)
2325 return r;
b69c3180
SS
2326
2327 r = link_set_ipv6_hop_limit(link);
2328 if (r < 0)
2329 return r;
8749cbcd 2330
78c958f8 2331 if (link_ipv4ll_enabled(link)) {
b22d8a00 2332 r = ipv4ll_configure(link);
eb34d4af
TG
2333 if (r < 0)
2334 return r;
2335 }
2336
78c958f8 2337 if (link_dhcp4_enabled(link)) {
3c9b8860 2338 r = dhcp4_configure(link);
eb34d4af
TG
2339 if (r < 0)
2340 return r;
eb34d4af
TG
2341 }
2342
78c958f8 2343 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
2344 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2345 if (r < 0)
2346 return r;
2347
2348 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2349 if (r < 0)
2350 return r;
dd43110f
TG
2351 }
2352
62379e88
TG
2353 if (link_dhcp6_enabled(link) ||
2354 link_ipv6_accept_ra_enabled(link)) {
f5a8c43f
TG
2355 r = dhcp6_configure(link);
2356 if (r < 0)
2357 return r;
2358 }
2359
2360 if (link_ipv6_accept_ra_enabled(link)) {
de1e9928 2361 r = ndisc_configure(link);
4138fb2c
PF
2362 if (r < 0)
2363 return r;
2364 }
2365
8e1ad1ea 2366 if (link_lldp_rx_enabled(link)) {
34437b4f
LP
2367 r = sd_lldp_new(&link->lldp, link->ifindex);
2368 if (r < 0)
2369 return r;
2370
2371 r = sd_lldp_match_capabilities(link->lldp,
2372 link->network->lldp_mode == LLDP_MODE_ROUTERS_ONLY ?
6afa6767
BG
2373 SD_LLDP_SYSTEM_CAPABILITIES_ALL_ROUTERS :
2374 SD_LLDP_SYSTEM_CAPABILITIES_ALL);
ce43e484
SS
2375 if (r < 0)
2376 return r;
2377
b553a6b1
LP
2378 r = sd_lldp_set_filter_address(link->lldp, &link->mac);
2379 if (r < 0)
2380 return r;
2381
ce43e484
SS
2382 r = sd_lldp_attach_event(link->lldp, NULL, 0);
2383 if (r < 0)
2384 return r;
49699bac 2385
032b27f5 2386 r = sd_lldp_set_callback(link->lldp, lldp_handler, link);
49699bac
SS
2387 if (r < 0)
2388 return r;
273eec24
LP
2389
2390 r = link_update_lldp(link);
2391 if (r < 0)
2392 return r;
ce43e484
SS
2393 }
2394
a61bb41c 2395 if (link_has_carrier(link)) {
1e9be60b
TG
2396 r = link_acquire_conf(link);
2397 if (r < 0)
2398 return r;
cc544d5f 2399 }
1e9be60b 2400
3f265037 2401 return link_enter_join_netdev(link);
505f8da7
TG
2402}
2403
1c4baffc 2404static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860 2405 void *userdata) {
5da8149f 2406 _cleanup_link_unref_ Link *link = userdata;
505f8da7 2407 Network *network;
505f8da7
TG
2408 int r;
2409
2410 assert(link);
2411 assert(link->ifname);
2412 assert(link->manager);
2413
8434fd5c 2414 if (link->state != LINK_STATE_PENDING)
5da8149f 2415 return 1;
505f8da7 2416
6a7a4e4d 2417 log_link_debug(link, "Link state is up-to-date");
505f8da7 2418
0d4ad91d
AR
2419 r = link_new_bound_by_list(link);
2420 if (r < 0)
2421 return r;
2422
2423 r = link_handle_bound_by_list(link);
2424 if (r < 0)
2425 return r;
2426
c4a03a56
TG
2427 if (!link->network) {
2428 r = network_get(link->manager, link->udev_device, link->ifname,
2429 &link->mac, &network);
2430 if (r == -ENOENT) {
2431 link_enter_unmanaged(link);
2432 return 1;
2433 } else if (r < 0)
2434 return r;
505f8da7 2435
c4a03a56
TG
2436 if (link->flags & IFF_LOOPBACK) {
2437 if (network->link_local != ADDRESS_FAMILY_NO)
2438 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
78c958f8 2439
c4a03a56
TG
2440 if (network->dhcp != ADDRESS_FAMILY_NO)
2441 log_link_debug(link, "Ignoring DHCP clients for loopback link");
78c958f8 2442
c4a03a56
TG
2443 if (network->dhcp_server)
2444 log_link_debug(link, "Ignoring DHCP server for loopback link");
2445 }
bd2efe92 2446
c4a03a56
TG
2447 r = network_apply(link->manager, network, link);
2448 if (r < 0)
2449 return r;
2450 }
505f8da7 2451
0d4ad91d
AR
2452 r = link_new_bound_to_list(link);
2453 if (r < 0)
2454 return r;
2455
a748b692
TG
2456 r = link_configure(link);
2457 if (r < 0)
2458 return r;
2459
5da8149f 2460 return 1;
505f8da7
TG
2461}
2462
4f561e8e 2463int link_initialized(Link *link, struct udev_device *device) {
4afd3348 2464 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
4f561e8e
TG
2465 int r;
2466
2467 assert(link);
2468 assert(link->manager);
2469 assert(link->manager->rtnl);
2470 assert(device);
2471
8434fd5c 2472 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
2473 return 0;
2474
679b3605
TG
2475 if (link->udev_device)
2476 return 0;
2477
79008bdd 2478 log_link_debug(link, "udev initialized link");
4f561e8e
TG
2479
2480 link->udev_device = udev_device_ref(device);
2481
3c9b8860
TG
2482 /* udev has initialized the link, but we don't know if we have yet
2483 * processed the NEWLINK messages with the latest state. Do a GETLINK,
2484 * when it returns we know that the pending NEWLINKs have already been
2485 * processed and that we are up-to-date */
4f561e8e 2486
3c9b8860
TG
2487 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2488 link->ifindex);
4f561e8e
TG
2489 if (r < 0)
2490 return r;
2491
1c4baffc 2492 r = sd_netlink_call_async(link->manager->rtnl, req,
3c9b8860 2493 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
2494 if (r < 0)
2495 return r;
2496
5da8149f
TG
2497 link_ref(link);
2498
4f561e8e
TG
2499 return 0;
2500}
2501
c4a03a56 2502static int link_load(Link *link) {
0bc70f1d
TG
2503 _cleanup_free_ char *network_file = NULL,
2504 *addresses = NULL,
f703cc2c 2505 *routes = NULL,
0bc70f1d
TG
2506 *dhcp4_address = NULL,
2507 *ipv4ll_address = NULL;
2508 union in_addr_union address;
f703cc2c 2509 union in_addr_union route_dst;
c598ac76 2510 const char *p;
c4a03a56
TG
2511 int r;
2512
2513 assert(link);
2514
2515 r = parse_env_file(link->state_file, NEWLINE,
2516 "NETWORK_FILE", &network_file,
2517 "ADDRESSES", &addresses,
f703cc2c 2518 "ROUTES", &routes,
0bc70f1d
TG
2519 "DHCP4_ADDRESS", &dhcp4_address,
2520 "IPV4LL_ADDRESS", &ipv4ll_address,
c4a03a56
TG
2521 NULL);
2522 if (r < 0 && r != -ENOENT)
2523 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2524
2525 if (network_file) {
2526 Network *network;
2527 char *suffix;
2528
2529 /* drop suffix */
2530 suffix = strrchr(network_file, '.');
2531 if (!suffix) {
2532 log_link_debug(link, "Failed to get network name from %s", network_file);
2533 goto network_file_fail;
2534 }
2535 *suffix = '\0';
2536
2537 r = network_get_by_name(link->manager, basename(network_file), &network);
2538 if (r < 0) {
2539 log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2540 goto network_file_fail;
2541 }
2542
2543 r = network_apply(link->manager, network, link);
2544 if (r < 0)
2545 return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2546 }
2547
2548network_file_fail:
2549
2550 if (addresses) {
c598ac76 2551 p = addresses;
c4a03a56 2552
c598ac76
TG
2553 for (;;) {
2554 _cleanup_free_ char *address_str = NULL;
c4a03a56
TG
2555 char *prefixlen_str;
2556 int family;
2557 unsigned char prefixlen;
c4a03a56 2558
c598ac76
TG
2559 r = extract_first_word(&p, &address_str, NULL, 0);
2560 if (r < 0) {
2561 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2562 continue;
928bc597
TA
2563 }
2564 if (r == 0)
c598ac76
TG
2565 break;
2566
2567 prefixlen_str = strchr(address_str, '/');
c4a03a56 2568 if (!prefixlen_str) {
c598ac76 2569 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
c4a03a56
TG
2570 continue;
2571 }
2572
313cefa1 2573 *prefixlen_str++ = '\0';
c4a03a56
TG
2574
2575 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
2576 if (r != 1) {
2577 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
2578 continue;
2579 }
2580
c598ac76 2581 r = in_addr_from_string_auto(address_str, &family, &address);
c4a03a56 2582 if (r < 0) {
c598ac76 2583 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
c4a03a56
TG
2584 continue;
2585 }
2586
2587 r = address_add(link, family, &address, prefixlen, NULL);
2588 if (r < 0)
2589 return log_link_error_errno(link, r, "Failed to add address: %m");
2590 }
2591 }
2592
f703cc2c 2593 if (routes) {
74544b4e
TA
2594 p = routes;
2595
c598ac76 2596 for (;;) {
f833694d 2597 Route *route;
c598ac76 2598 _cleanup_free_ char *route_str = NULL;
4afd3348 2599 _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
f833694d 2600 usec_t lifetime;
f703cc2c
TG
2601 char *prefixlen_str;
2602 int family;
2603 unsigned char prefixlen, tos, table;
2604 uint32_t priority;
2605
c598ac76
TG
2606 r = extract_first_word(&p, &route_str, NULL, 0);
2607 if (r < 0) {
2608 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
2609 continue;
928bc597
TA
2610 }
2611 if (r == 0)
c598ac76
TG
2612 break;
2613
2614 prefixlen_str = strchr(route_str, '/');
f703cc2c 2615 if (!prefixlen_str) {
c598ac76 2616 log_link_debug(link, "Failed to parse route %s", route_str);
f703cc2c
TG
2617 continue;
2618 }
2619
313cefa1 2620 *prefixlen_str++ = '\0';
f703cc2c 2621
f833694d
TG
2622 r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
2623 if (r != 5) {
2624 log_link_debug(link,
2625 "Failed to parse destination prefix length, tos, priority, table or expiration %s",
2626 prefixlen_str);
f703cc2c
TG
2627 continue;
2628 }
2629
c598ac76 2630 r = in_addr_from_string_auto(route_str, &family, &route_dst);
f703cc2c 2631 if (r < 0) {
c598ac76 2632 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
f703cc2c
TG
2633 continue;
2634 }
2635
f833694d 2636 r = route_add(link, family, &route_dst, prefixlen, tos, priority, table, &route);
f703cc2c
TG
2637 if (r < 0)
2638 return log_link_error_errno(link, r, "Failed to add route: %m");
f833694d
TG
2639
2640 if (lifetime != USEC_INFINITY) {
2641 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
2642 0, route_expire_handler, route);
2643 if (r < 0)
2644 log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
2645 }
2646
2647 route->lifetime = lifetime;
2648 sd_event_source_unref(route->expire);
2649 route->expire = expire;
2650 expire = NULL;
f703cc2c
TG
2651 }
2652 }
2653
0bc70f1d
TG
2654 if (dhcp4_address) {
2655 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
2656 if (r < 0) {
2657 log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address);
2658 goto dhcp4_address_fail;
2659 }
2660
2661 r = sd_dhcp_client_new(&link->dhcp_client);
2662 if (r < 0)
2663 return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m");
2664
2665 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
2666 if (r < 0)
2667 return log_link_error_errno(link, r, "Falied to set inital DHCPv4 address %s: %m", dhcp4_address);
2668 }
2669
2670dhcp4_address_fail:
2671
2672 if (ipv4ll_address) {
2673 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
2674 if (r < 0) {
2675 log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address);
2676 goto ipv4ll_address_fail;
2677 }
2678
2679 r = sd_ipv4ll_new(&link->ipv4ll);
2680 if (r < 0)
2681 return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m");
2682
2683 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
2684 if (r < 0)
2685 return log_link_error_errno(link, r, "Falied to set inital IPv4LL address %s: %m", ipv4ll_address);
2686 }
2687
2688ipv4ll_address_fail:
2689
c4a03a56
TG
2690 return 0;
2691}
2692
1c4baffc 2693int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
505f8da7
TG
2694 Link *link;
2695 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2696 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2697 int r;
2698
2699 assert(m);
fbbeb65a 2700 assert(m->rtnl);
505f8da7
TG
2701 assert(message);
2702 assert(ret);
2703
2704 r = link_new(m, message, ret);
2705 if (r < 0)
2706 return r;
2707
2708 link = *ret;
2709
6a7a4e4d 2710 log_link_debug(link, "Link %d added", link->ifindex);
505f8da7 2711
c4a03a56
TG
2712 r = link_load(link);
2713 if (r < 0)
2714 return r;
2715
75f86906 2716 if (detect_container() <= 0) {
505f8da7 2717 /* not in a container, udev will be around */
ae06ab10 2718 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7 2719 device = udev_device_new_from_device_id(m->udev, ifindex_str);
5c416fc4
TG
2720 if (!device) {
2721 r = log_link_warning_errno(link, errno, "Could not find udev device: %m");
2722 goto failed;
2723 }
505f8da7 2724
3c4cb064 2725 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 2726 /* not yet ready */
79008bdd 2727 log_link_debug(link, "link pending udev initialization...");
505f8da7 2728 return 0;
3c4cb064 2729 }
505f8da7 2730
4f561e8e
TG
2731 r = link_initialized(link, device);
2732 if (r < 0)
5c416fc4 2733 goto failed;
4f561e8e 2734 } else {
5da8149f
TG
2735 /* we are calling a callback directly, so must take a ref */
2736 link_ref(link);
2737
4f561e8e
TG
2738 r = link_initialized_and_synced(m->rtnl, NULL, link);
2739 if (r < 0)
5c416fc4 2740 goto failed;
4f561e8e 2741 }
505f8da7 2742
a748b692 2743 return 0;
5c416fc4
TG
2744failed:
2745 link_enter_failed(link);
2746 return r;
a748b692
TG
2747}
2748
c601ebf7 2749int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
e7ab854c
TG
2750 int r;
2751
2752 assert(link);
2753
2754 log_link_info(link, "Gained IPv6LL");
2755
c601ebf7 2756 link->ipv6ll_address = *address;
e7ab854c
TG
2757 link_check_ready(link);
2758
201f0c91 2759 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
e7ab854c
TG
2760 r = link_acquire_ipv6_conf(link);
2761 if (r < 0) {
2762 link_enter_failed(link);
2763 return r;
2764 }
2765 }
2766
2767 return 0;
2768}
2769
9c0a72f9
TG
2770static int link_carrier_gained(Link *link) {
2771 int r;
2772
2773 assert(link);
2774
201f0c91 2775 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
9c0a72f9
TG
2776 r = link_acquire_conf(link);
2777 if (r < 0) {
2778 link_enter_failed(link);
2779 return r;
2780 }
6fc25497
SS
2781
2782 r = link_enter_set_addresses(link);
2783 if (r < 0)
2784 return r;
9c0a72f9
TG
2785 }
2786
0d4ad91d
AR
2787 r = link_handle_bound_by_list(link);
2788 if (r < 0)
2789 return r;
2790
9c0a72f9
TG
2791 return 0;
2792}
2793
2794static int link_carrier_lost(Link *link) {
2795 int r;
2796
2797 assert(link);
2798
2799 r = link_stop_clients(link);
2800 if (r < 0) {
2801 link_enter_failed(link);
2802 return r;
2803 }
2804
0d4ad91d
AR
2805 r = link_handle_bound_by_list(link);
2806 if (r < 0)
2807 return r;
2808
9c0a72f9
TG
2809 return 0;
2810}
2811
2812int link_carrier_reset(Link *link) {
2813 int r;
2814
2815 assert(link);
2816
2817 if (link_has_carrier(link)) {
2818 r = link_carrier_lost(link);
2819 if (r < 0)
2820 return r;
2821
2822 r = link_carrier_gained(link);
2823 if (r < 0)
2824 return r;
2825
6a7a4e4d 2826 log_link_info(link, "Reset carrier");
9c0a72f9
TG
2827 }
2828
2829 return 0;
2830}
2831
1c4baffc 2832int link_update(Link *link, sd_netlink_message *m) {
c49b33ac 2833 struct ether_addr mac;
ca4e095a 2834 const char *ifname;
afe7fd56 2835 uint32_t mtu;
a61bb41c 2836 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
2837 int r;
2838
dd3efc09 2839 assert(link);
b8941f74 2840 assert(link->ifname);
22936833
TG
2841 assert(m);
2842
7619683b
TG
2843 if (link->state == LINK_STATE_LINGER) {
2844 link_ref(link);
6a7a4e4d 2845 log_link_info(link, "Link readded");
e331e246 2846 link_set_state(link, LINK_STATE_ENSLAVING);
0d4ad91d
AR
2847
2848 r = link_new_carrier_maps(link);
2849 if (r < 0)
2850 return r;
7619683b
TG
2851 }
2852
1c4baffc 2853 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
b8941f74 2854 if (r >= 0 && !streq(ifname, link->ifname)) {
6a7a4e4d 2855 log_link_info(link, "Renamed to %s", ifname);
b8941f74 2856
0d4ad91d
AR
2857 link_free_carrier_maps(link);
2858
2fc09a9c
DM
2859 r = free_and_strdup(&link->ifname, ifname);
2860 if (r < 0)
2861 return r;
0d4ad91d
AR
2862
2863 r = link_new_carrier_maps(link);
2864 if (r < 0)
2865 return r;
b8941f74
TG
2866 }
2867
1c4baffc 2868 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
afe7fd56
TG
2869 if (r >= 0 && mtu > 0) {
2870 link->mtu = mtu;
2871 if (!link->original_mtu) {
2872 link->original_mtu = mtu;
6a7a4e4d 2873 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
afe7fd56
TG
2874 }
2875
2876 if (link->dhcp_client) {
3c9b8860
TG
2877 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2878 link->mtu);
afe7fd56 2879 if (r < 0) {
6a7a4e4d 2880 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
afe7fd56
TG
2881 return r;
2882 }
2883 }
9842de0d 2884 }
69629de9 2885
e9189a1f
TG
2886 /* The kernel may broadcast NEWLINK messages without the MAC address
2887 set, simply ignore them. */
1c4baffc 2888 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 2889 if (r >= 0) {
3c9b8860
TG
2890 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2891 ETH_ALEN)) {
c49b33ac 2892
3c9b8860
TG
2893 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2894 ETH_ALEN);
c49b33ac 2895
79008bdd 2896 log_link_debug(link, "MAC address: "
20861203
TG
2897 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2898 mac.ether_addr_octet[0],
2899 mac.ether_addr_octet[1],
2900 mac.ether_addr_octet[2],
2901 mac.ether_addr_octet[3],
2902 mac.ether_addr_octet[4],
2903 mac.ether_addr_octet[5]);
c49b33ac 2904
20861203
TG
2905 if (link->ipv4ll) {
2906 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
6a7a4e4d
LP
2907 if (r < 0)
2908 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
c49b33ac 2909 }
c49b33ac 2910
20861203 2911 if (link->dhcp_client) {
8341a5c3
ZJS
2912 const DUID *duid = link_duid(link);
2913
3c9b8860 2914 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
2915 (const uint8_t *) &link->mac,
2916 sizeof (link->mac),
2917 ARPHRD_ETHER);
6a7a4e4d
LP
2918 if (r < 0)
2919 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
413708d1 2920
8341a5c3
ZJS
2921 r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
2922 link->network->iaid,
2923 duid->type,
2924 duid->raw_data_len > 0 ? duid->raw_data : NULL,
2925 duid->raw_data_len);
413708d1
VK
2926 if (r < 0)
2927 return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
c49b33ac 2928 }
4138fb2c
PF
2929
2930 if (link->dhcp6_client) {
8341a5c3
ZJS
2931 const DUID* duid = link_duid(link);
2932
4138fb2c 2933 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
2934 (const uint8_t *) &link->mac,
2935 sizeof (link->mac),
2936 ARPHRD_ETHER);
6a7a4e4d
LP
2937 if (r < 0)
2938 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
413708d1
VK
2939
2940 r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
2941 link->network->iaid);
2942 if (r < 0)
2943 return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
2944
8341a5c3
ZJS
2945 r = sd_dhcp6_client_set_duid(link->dhcp6_client,
2946 duid->type,
2947 duid->raw_data_len > 0 ? duid->raw_data : NULL,
2948 duid->raw_data_len);
413708d1
VK
2949 if (r < 0)
2950 return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
4138fb2c 2951 }
c49b33ac 2952 }
4f882b2a
TG
2953 }
2954
a61bb41c
TG
2955 had_carrier = link_has_carrier(link);
2956
2957 r = link_update_flags(link, m);
2958 if (r < 0)
2959 return r;
2960
273eec24
LP
2961 r = link_update_lldp(link);
2962 if (r < 0)
2963 return r;
2964
a61bb41c
TG
2965 carrier_gained = !had_carrier && link_has_carrier(link);
2966 carrier_lost = had_carrier && !link_has_carrier(link);
2967
2968 if (carrier_gained) {
6a7a4e4d 2969 log_link_info(link, "Gained carrier");
a61bb41c 2970
9c0a72f9
TG
2971 r = link_carrier_gained(link);
2972 if (r < 0)
2973 return r;
a61bb41c 2974 } else if (carrier_lost) {
6a7a4e4d 2975 log_link_info(link, "Lost carrier");
a61bb41c 2976
9c0a72f9
TG
2977 r = link_carrier_lost(link);
2978 if (r < 0)
a61bb41c 2979 return r;
a61bb41c
TG
2980 }
2981
2982 return 0;
dd3efc09 2983}
fe8db0c5 2984
b295beea
LP
2985static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
2986 bool space = false;
2987 Iterator i;
2988 Link *link;
2989
2990 assert(f);
2991 assert(prefix);
2992
2993 if (hashmap_isempty(h))
2994 return;
2995
2996 fputs(prefix, f);
2997 HASHMAP_FOREACH(link, h, i) {
2998 if (space)
2999 fputc(' ', f);
3000
3001 fprintf(f, "%i", link->ifindex);
3002 space = true;
3003 }
3004
3005 fputc('\n', f);
3006}
3007
fe8db0c5 3008int link_save(Link *link) {
68a8723c 3009 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 3010 _cleanup_fclose_ FILE *f = NULL;
e375dcde 3011 const char *admin_state, *oper_state;
e7780c8d 3012 Address *a;
c1eb9872 3013 Route *route;
e7780c8d 3014 Iterator i;
fe8db0c5
TG
3015 int r;
3016
3017 assert(link);
3018 assert(link->state_file);
68a8723c 3019 assert(link->lease_file);
bbf7c048
TG
3020 assert(link->manager);
3021
370e9930
TG
3022 if (link->state == LINK_STATE_LINGER) {
3023 unlink(link->state_file);
3024 return 0;
3025 }
3026
34437b4f
LP
3027 link_lldp_save(link);
3028
deb2e523
TG
3029 admin_state = link_state_to_string(link->state);
3030 assert(admin_state);
3031
e375dcde
TG
3032 oper_state = link_operstate_to_string(link->operstate);
3033 assert(oper_state);
deb2e523 3034
fe8db0c5
TG
3035 r = fopen_temporary(link->state_file, &f, &temp_path);
3036 if (r < 0)
6a7a4e4d 3037 goto fail;
fe8db0c5
TG
3038
3039 fchmod(fileno(f), 0644);
3040
3041 fprintf(f,
3042 "# This is private data. Do not parse.\n"
deb2e523 3043 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
3044 "OPER_STATE=%s\n",
3045 admin_state, oper_state);
fe8db0c5 3046
bcb7a07e 3047 if (link->network) {
ea352b40 3048 bool space;
07bdc70d 3049 sd_dhcp6_lease *dhcp6_lease = NULL;
b2a81c0b
LP
3050 const char *dhcp_domainname = NULL;
3051 char **dhcp6_domains = NULL;
07bdc70d
PF
3052
3053 if (link->dhcp6_client) {
4058d339
TG
3054 r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
3055 if (r < 0 && r != -ENOMSG)
07bdc70d
PF
3056 log_link_debug(link, "No DHCPv6 lease");
3057 }
b0e39c82 3058
adc5b2e2
TG
3059 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
3060
b0e39c82 3061 fputs("DNS=", f);
ea352b40 3062 space = false;
3df9bec5 3063 fputstrv(f, link->network->dns, NULL, &space);
d5314fff 3064
27cb34f5 3065 if (link->network->dhcp_use_dns &&
b0e39c82
TG
3066 link->dhcp_lease) {
3067 const struct in_addr *addresses;
3068
3069 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
3070 if (r > 0) {
ea352b40
LP
3071 if (space)
3072 fputc(' ', f);
b0e39c82 3073 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
3074 space = true;
3075 }
3076 }
3077
27cb34f5 3078 if (link->network->dhcp_use_dns && dhcp6_lease) {
07bdc70d
PF
3079 struct in6_addr *in6_addrs;
3080
3081 r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
3082 if (r > 0) {
3083 if (space)
3084 fputc(' ', f);
3085 serialize_in6_addrs(f, in6_addrs, r);
b0e39c82
TG
3086 }
3087 }
3088
2ce40956 3089 fputc('\n', f);
b0e39c82 3090
2ce40956 3091 fputs("NTP=", f);
ea352b40 3092 space = false;
3df9bec5 3093 fputstrv(f, link->network->ntp, NULL, &space);
d5314fff 3094
27cb34f5 3095 if (link->network->dhcp_use_ntp &&
b0e39c82
TG
3096 link->dhcp_lease) {
3097 const struct in_addr *addresses;
3098
3099 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
3100 if (r > 0) {
ea352b40
LP
3101 if (space)
3102 fputc(' ', f);
b0e39c82 3103 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
3104 space = true;
3105 }
3106 }
3107
27cb34f5 3108 if (link->network->dhcp_use_ntp && dhcp6_lease) {
07bdc70d
PF
3109 struct in6_addr *in6_addrs;
3110 char **hosts;
07bdc70d
PF
3111
3112 r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
3113 &in6_addrs);
3114 if (r > 0) {
3115 if (space)
3116 fputc(' ', f);
3117 serialize_in6_addrs(f, in6_addrs, r);
3118 space = true;
3119 }
3120
3121 r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
3df9bec5
LP
3122 if (r > 0)
3123 fputstrv(f, hosts, NULL, &space);
b0e39c82
TG
3124 }
3125
2ce40956 3126 fputc('\n', f);
bd8f6538 3127
b2a81c0b
LP
3128 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
3129 if (link->dhcp_lease)
3130 (void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
9b4d1882 3131
b2a81c0b
LP
3132 if (dhcp6_lease)
3133 (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
07bdc70d
PF
3134 }
3135
b2a81c0b
LP
3136 fputs("DOMAINS=", f);
3137 fputstrv(f, link->network->search_domains, NULL, &space);
07bdc70d 3138
d390f8ef
LP
3139 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES && dhcp_domainname)
3140 fputs_with_space(f, dhcp_domainname, NULL, &space);
9b4d1882 3141
b2a81c0b
LP
3142 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES && dhcp6_domains)
3143 fputstrv(f, dhcp6_domains, NULL, &space);
3144
2ce40956 3145 fputc('\n', f);
6192b846 3146
3df9bec5
LP
3147 fputs("ROUTE_DOMAINS=", f);
3148 fputstrv(f, link->network->route_domains, NULL, NULL);
b2a81c0b 3149
d390f8ef
LP
3150 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE && dhcp_domainname)
3151 fputs_with_space(f, dhcp_domainname, NULL, &space);
b2a81c0b
LP
3152
3153 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE && dhcp6_domains)
3154 fputstrv(f, dhcp6_domains, NULL, &space);
3155
3df9bec5 3156 fputc('\n', f);
67272d15 3157
3c9b8860 3158 fprintf(f, "LLMNR=%s\n",
a7e5da6e 3159 resolve_support_to_string(link->network->llmnr));
aaa297d4
LP
3160 fprintf(f, "MDNS=%s\n",
3161 resolve_support_to_string(link->network->mdns));
e7780c8d 3162
ad6c0475
LP
3163 if (link->network->dnssec_mode != _DNSSEC_MODE_INVALID)
3164 fprintf(f, "DNSSEC=%s\n",
3165 dnssec_mode_to_string(link->network->dnssec_mode));
3166
8a516214
LP
3167 if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
3168 const char *n;
3169
3170 fputs("DNSSEC_NTA=", f);
3171 space = false;
d390f8ef
LP
3172 SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
3173 fputs_with_space(f, n, NULL, &space);
8a516214
LP
3174 fputc('\n', f);
3175 }
3176
2ce40956 3177 fputs("ADDRESSES=", f);
e7780c8d
TG
3178 space = false;
3179 SET_FOREACH(a, link->addresses, i) {
3180 _cleanup_free_ char *address_str = NULL;
3181
3182 r = in_addr_to_string(a->family, &a->in_addr, &address_str);
3183 if (r < 0)
3184 goto fail;
3185
e7780c8d
TG
3186 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
3187 space = true;
3188 }
2ce40956 3189 fputc('\n', f);
c1eb9872
TG
3190
3191 fputs("ROUTES=", f);
3192 space = false;
3193 SET_FOREACH(route, link->routes, i) {
3194 _cleanup_free_ char *route_str = NULL;
3195
3196 r = in_addr_to_string(route->family, &route->dst, &route_str);
3197 if (r < 0)
3198 goto fail;
3199
f833694d
TG
3200 fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
3201 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
c1eb9872
TG
3202 space = true;
3203 }
3204
3205 fputc('\n', f);
bcb7a07e 3206 }
7374f9d8 3207
b295beea
LP
3208 print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
3209 print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
0d4ad91d 3210
8eb9058d 3211 if (link->dhcp_lease) {
0bc70f1d 3212 struct in_addr address;
8eb9058d
LP
3213 const char *tz = NULL;
3214
0bc70f1d
TG
3215 assert(link->network);
3216
8eb9058d
LP
3217 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
3218 if (r >= 0)
3219 fprintf(f, "TIMEZONE=%s\n", tz);
8eb9058d 3220
0bc70f1d
TG
3221 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
3222 if (r >= 0) {
3223 fputs("DHCP4_ADDRESS=", f);
3224 serialize_in_addrs(f, &address, 1);
3225 fputc('\n', f);
3226 }
d9876a52 3227
bd91b83e 3228 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 3229 if (r < 0)
c2d6bd61 3230 goto fail;
fe8db0c5 3231
7374f9d8 3232 fprintf(f,
b0e39c82
TG
3233 "DHCP_LEASE=%s\n",
3234 link->lease_file);
deb2e523 3235 } else
68a8723c 3236 unlink(link->lease_file);
fe8db0c5 3237
0bc70f1d
TG
3238 if (link->ipv4ll) {
3239 struct in_addr address;
3240
3241 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
3242 if (r >= 0) {
3243 fputs("IPV4LL_ADDRESS=", f);
3244 serialize_in_addrs(f, &address, 1);
3245 fputc('\n', f);
3246 }
3247 }
3248
c2d6bd61
LP
3249 r = fflush_and_check(f);
3250 if (r < 0)
3251 goto fail;
fe8db0c5 3252
c2d6bd61 3253 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 3254 r = -errno;
c2d6bd61 3255 goto fail;
fe8db0c5
TG
3256 }
3257
c2d6bd61 3258 return 0;
dacd6cee 3259
c2d6bd61 3260fail:
6a7a4e4d 3261 (void) unlink(link->state_file);
6a7a4e4d
LP
3262 if (temp_path)
3263 (void) unlink(temp_path);
3264
dacd6cee 3265 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
fe8db0c5
TG
3266}
3267
84de38c5
TG
3268/* The serialized state in /run is no longer up-to-date. */
3269void link_dirty(Link *link) {
3270 int r;
3271
3272 assert(link);
3273
0c241a37
SS
3274 /* mark manager dirty as link is dirty */
3275 manager_dirty(link->manager);
3276
84de38c5
TG
3277 r = set_ensure_allocated(&link->manager->dirty_links, NULL);
3278 if (r < 0)
3279 /* allocation errors are ignored */
3280 return;
3281
3282 r = set_put(link->manager->dirty_links, link);
0c241a37
SS
3283 if (r <= 0)
3284 /* don't take another ref if the link was already dirty */
84de38c5
TG
3285 return;
3286
3287 link_ref(link);
3288}
3289
3290/* The serialized state in /run is up-to-date */
3291void link_clean(Link *link) {
3292 assert(link);
3293 assert(link->manager);
3294
3295 set_remove(link->manager->dirty_links, link);
3296 link_unref(link);
3297}
3298
fe8db0c5 3299static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 3300 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
3301 [LINK_STATE_ENSLAVING] = "configuring",
3302 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
3303 [LINK_STATE_SETTING_ROUTES] = "configuring",
3304 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 3305 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 3306 [LINK_STATE_FAILED] = "failed",
370e9930 3307 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
3308};
3309
3310DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
3311
3312static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
3313 [LINK_OPERSTATE_OFF] = "off",
3314 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
3315 [LINK_OPERSTATE_DORMANT] = "dormant",
3316 [LINK_OPERSTATE_CARRIER] = "carrier",
3317 [LINK_OPERSTATE_DEGRADED] = "degraded",
3318 [LINK_OPERSTATE_ROUTABLE] = "routable",
3319};
3320
3321DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);