]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
networkd: unset master if not enslaved with networkd
[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
4cef7fe3
TY
113 /* DHCPv6 client will not be started if no IPv6 link-local address is configured. */
114 return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
439689c6
SS
115}
116
8e1ad1ea 117static bool link_lldp_rx_enabled(Link *link) {
b710e6b6
LP
118 assert(link);
119
ce43e484
SS
120 if (link->flags & IFF_LOOPBACK)
121 return false;
122
b710e6b6
LP
123 if (link->iftype != ARPHRD_ETHER)
124 return false;
125
ce43e484
SS
126 if (!link->network)
127 return false;
128
5a8bcb67 129 if (link->network->bridge)
ce43e484
SS
130 return false;
131
34437b4f 132 return link->network->lldp_mode != LLDP_MODE_NO;
ce43e484
SS
133}
134
7272b25e 135static bool link_lldp_emit_enabled(Link *link) {
8e1ad1ea
LP
136 assert(link);
137
138 if (link->flags & IFF_LOOPBACK)
139 return false;
140
141 if (link->iftype != ARPHRD_ETHER)
142 return false;
143
144 if (!link->network)
145 return false;
146
7272b25e 147 return link->network->lldp_emit != LLDP_EMIT_NO;
8e1ad1ea
LP
148}
149
769d324c 150static bool link_ipv4_forward_enabled(Link *link) {
b9d74c40
LP
151 assert(link);
152
5a8bcb67
LP
153 if (link->flags & IFF_LOOPBACK)
154 return false;
155
156 if (!link->network)
157 return false;
158
765afd5c
LP
159 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
160 return false;
161
e0ee46f2 162 return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
769d324c
LP
163}
164
165static bool link_ipv6_forward_enabled(Link *link) {
b9d74c40 166 assert(link);
765afd5c
LP
167
168 if (!socket_ipv6_is_supported())
169 return false;
170
769d324c
LP
171 if (link->flags & IFF_LOOPBACK)
172 return false;
173
174 if (!link->network)
175 return false;
176
765afd5c
LP
177 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
178 return false;
179
e0ee46f2 180 return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
5a8bcb67
LP
181}
182
23d8b221
SS
183static bool link_proxy_arp_enabled(Link *link) {
184 assert(link);
185
186 if (link->flags & IFF_LOOPBACK)
187 return false;
188
189 if (!link->network)
190 return false;
191
192 if (link->network->proxy_arp < 0)
193 return false;
194
195 return true;
196}
197
b9d74c40
LP
198static bool link_ipv6_accept_ra_enabled(Link *link) {
199 assert(link);
200
fa709992
LP
201 if (!socket_ipv6_is_supported())
202 return false;
203
f5a8c43f
TG
204 if (link->flags & IFF_LOOPBACK)
205 return false;
206
207 if (!link->network)
208 return false;
209
210 /* If unset use system default (enabled if local forwarding is disabled.
211 * disabled if local forwarding is enabled).
212 * If set, ignore or enforce RA independent of local forwarding state.
213 */
214 if (link->network->ipv6_accept_ra < 0)
215 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
216 return !link_ipv6_forward_enabled(link);
217 else if (link->network->ipv6_accept_ra > 0)
218 /* accept RA even if ip_forward is enabled */
219 return true;
220 else
221 /* ignore RA */
222 return false;
223}
224
1f0d9695 225static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
fa709992 226 assert(link);
d68e2e59
LP
227
228 if (!socket_ipv6_is_supported())
229 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
230
49092e22 231 if (link->flags & IFF_LOOPBACK)
1f0d9695 232 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
49092e22
SS
233
234 if (!link->network)
1f0d9695 235 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
49092e22
SS
236
237 return link->network->ipv6_privacy_extensions;
238}
239
439689c6
SS
240static int link_enable_ipv6(Link *link) {
241 const char *p = NULL;
242 bool disabled;
243 int r;
244
245 if (link->flags & IFF_LOOPBACK)
246 return 0;
247
248 disabled = !link_ipv6_enabled(link);
249
250 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6");
251
252 r = write_string_file(p, one_zero(disabled), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
253 if (r < 0)
254 log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m", disabled ? "disable" : "enable", link->ifname);
255 else {
256 if (disabled)
257 log_link_info(link, "IPv6 disabled for interface: %m");
258 else
259 log_link_info(link, "IPv6 enabled for interface: %m");
260 }
261
262 return 0;
263}
264
84de38c5
TG
265void link_update_operstate(Link *link) {
266 LinkOperationalState operstate;
267 assert(link);
268
269 if (link->kernel_operstate == IF_OPER_DORMANT)
270 operstate = LINK_OPERSTATE_DORMANT;
271 else if (link_has_carrier(link)) {
272 Address *address;
273 uint8_t scope = RT_SCOPE_NOWHERE;
274 Iterator i;
275
276 /* if we have carrier, check what addresses we have */
277 SET_FOREACH(address, link->addresses, i) {
278 if (!address_is_ready(address))
279 continue;
280
281 if (address->scope < scope)
282 scope = address->scope;
283 }
284
285 /* for operstate we also take foreign addresses into account */
286 SET_FOREACH(address, link->addresses_foreign, i) {
287 if (!address_is_ready(address))
288 continue;
289
290 if (address->scope < scope)
291 scope = address->scope;
292 }
293
294 if (scope < RT_SCOPE_SITE)
295 /* universally accessible addresses found */
296 operstate = LINK_OPERSTATE_ROUTABLE;
297 else if (scope < RT_SCOPE_HOST)
298 /* only link or site local addresses found */
299 operstate = LINK_OPERSTATE_DEGRADED;
300 else
301 /* no useful addresses found */
302 operstate = LINK_OPERSTATE_CARRIER;
303 } else if (link->flags & IFF_UP)
304 operstate = LINK_OPERSTATE_NO_CARRIER;
305 else
306 operstate = LINK_OPERSTATE_OFF;
307
308 if (link->operstate != operstate) {
309 link->operstate = operstate;
310 link_send_changed(link, "OperationalState", NULL);
311 link_dirty(link);
84de38c5
TG
312 }
313}
314
51d18171
TG
315#define FLAG_STRING(string, flag, old, new) \
316 (((old ^ new) & flag) \
317 ? ((old & flag) ? (" -" string) : (" +" string)) \
318 : "")
319
1c4baffc 320static int link_update_flags(Link *link, sd_netlink_message *m) {
51d18171
TG
321 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
322 uint8_t operstate;
323 int r;
324
325 assert(link);
326
327 r = sd_rtnl_message_link_get_flags(m, &flags);
6a7a4e4d
LP
328 if (r < 0)
329 return log_link_warning_errno(link, r, "Could not get link flags: %m");
51d18171 330
1c4baffc 331 r = sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &operstate);
51d18171
TG
332 if (r < 0)
333 /* if we got a message without operstate, take it to mean
334 the state was unchanged */
335 operstate = link->kernel_operstate;
336
337 if ((link->flags == flags) && (link->kernel_operstate == operstate))
338 return 0;
339
340 if (link->flags != flags) {
6a7a4e4d 341 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
342 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
343 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
344 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
345 FLAG_STRING("UP", IFF_UP, link->flags, flags),
346 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
347 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
348 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
349 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
350 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
351 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
352 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
353 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
354 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
355 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
356 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
357 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
358 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
359 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
360 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
361
362 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
363 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
364 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
365 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
366 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
367 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
368 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
369 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
370
371 /* link flags are currently at most 18 bits, let's align to
372 * printing 20 */
373 if (unknown_flags_added)
79008bdd 374 log_link_debug(link,
6a7a4e4d 375 "Unknown link flags gained: %#.5x (ignoring)",
51d18171
TG
376 unknown_flags_added);
377
378 if (unknown_flags_removed)
79008bdd 379 log_link_debug(link,
6a7a4e4d 380 "Unknown link flags lost: %#.5x (ignoring)",
51d18171
TG
381 unknown_flags_removed);
382 }
383
384 link->flags = flags;
385 link->kernel_operstate = operstate;
386
84de38c5 387 link_update_operstate(link);
51d18171
TG
388
389 return 0;
390}
391
1c4baffc 392static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
14b746f7 393 _cleanup_link_unref_ Link *link = NULL;
505f8da7 394 uint16_t type;
ca4e095a 395 const char *ifname;
505f8da7 396 int r, ifindex;
b710e6b6 397 unsigned short iftype;
f579559b 398
0c2f9b84 399 assert(manager);
505f8da7 400 assert(message);
f579559b
TG
401 assert(ret);
402
1c4baffc 403 r = sd_netlink_message_get_type(message, &type);
505f8da7
TG
404 if (r < 0)
405 return r;
406 else if (type != RTM_NEWLINK)
407 return -EINVAL;
408
409 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
410 if (r < 0)
411 return r;
412 else if (ifindex <= 0)
413 return -EINVAL;
414
b710e6b6
LP
415 r = sd_rtnl_message_link_get_type(message, &iftype);
416 if (r < 0)
417 return r;
418
1c4baffc 419 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
505f8da7
TG
420 if (r < 0)
421 return r;
422
f579559b
TG
423 link = new0(Link, 1);
424 if (!link)
425 return -ENOMEM;
426
14b746f7 427 link->n_ref = 1;
5a3eb5a7 428 link->manager = manager;
8434fd5c 429 link->state = LINK_STATE_PENDING;
be3a09b7 430 link->rtnl_extended_attrs = true;
505f8da7 431 link->ifindex = ifindex;
b710e6b6 432 link->iftype = iftype;
505f8da7
TG
433 link->ifname = strdup(ifname);
434 if (!link->ifname)
435 return -ENOMEM;
f579559b 436
1c4baffc 437 r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
512922f8 438 if (r < 0)
34437b4f 439 log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
512922f8 440
34437b4f 441 if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
315db1a8 442 return -ENOMEM;
fe8db0c5 443
34437b4f 444 if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
68a8723c
TG
445 return -ENOMEM;
446
34437b4f 447 if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
49699bac
SS
448 return -ENOMEM;
449
d5099efc 450 r = hashmap_ensure_allocated(&manager->links, NULL);
ae06ab10
TG
451 if (r < 0)
452 return r;
453
454 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
f579559b
TG
455 if (r < 0)
456 return r;
457
51d18171
TG
458 r = link_update_flags(link, message);
459 if (r < 0)
460 return r;
461
f579559b
TG
462 *ret = link;
463 link = NULL;
464
465 return 0;
466}
467
14b746f7 468static void link_free(Link *link) {
428fd0a7 469 Address *address;
0d4ad91d
AR
470 Iterator i;
471 Link *carrier;
428fd0a7 472
f579559b
TG
473 if (!link)
474 return;
475
cf1d700d
TG
476 while (!set_isempty(link->addresses))
477 address_free(set_first(link->addresses));
478
adda1ed9
TG
479 while (!set_isempty(link->addresses_foreign))
480 address_free(set_first(link->addresses_foreign));
481
4701725c
HV
482 link->addresses = set_free(link->addresses);
483
484 link->addresses_foreign = set_free(link->addresses_foreign);
adda1ed9 485
11bf3cce
LP
486 while ((address = link->pool_addresses)) {
487 LIST_REMOVE(addresses, link->pool_addresses, address);
488 address_free(address);
489 }
490
bfcdba8d 491 sd_dhcp_server_unref(link->dhcp_server);
e5b04c8d 492 sd_dhcp_client_unref(link->dhcp_client);
a6cc569e 493 sd_dhcp_lease_unref(link->dhcp_lease);
f5be5601 494
7272b25e 495 link_lldp_emit_stop(link);
8e1ad1ea 496
68a8723c
TG
497 free(link->lease_file);
498
4afd3348 499 sd_lldp_unref(link->lldp);
49699bac
SS
500 free(link->lldp_file);
501
56cd007a 502 sd_ipv4ll_unref(link->ipv4ll);
4138fb2c 503 sd_dhcp6_client_unref(link->dhcp6_client);
de1e9928 504 sd_ndisc_unref(link->ndisc_router_discovery);
4138fb2c 505
28aeb07f 506 if (link->manager)
ae06ab10 507 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
f579559b 508
c166a070 509 free(link->ifname);
68a8723c 510
84de38c5 511 (void)unlink(link->state_file);
fe8db0c5 512 free(link->state_file);
c166a070 513
b5db00e5
UTL
514 udev_device_unref(link->udev_device);
515
0d4ad91d
AR
516 HASHMAP_FOREACH (carrier, link->bound_to_links, i)
517 hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex));
518 hashmap_free(link->bound_to_links);
519
520 HASHMAP_FOREACH (carrier, link->bound_by_links, i)
521 hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
522 hashmap_free(link->bound_by_links);
523
f579559b
TG
524 free(link);
525}
526
14b746f7 527Link *link_unref(Link *link) {
957325b7
TG
528 if (!link)
529 return NULL;
530
531 assert(link->n_ref > 0);
532
313cefa1 533 link->n_ref--;
957325b7
TG
534
535 if (link->n_ref > 0)
536 return NULL;
537
538 link_free(link);
14b746f7
TG
539
540 return NULL;
541}
542
543Link *link_ref(Link *link) {
957325b7
TG
544 if (!link)
545 return NULL;
546
547 assert(link->n_ref > 0);
548
313cefa1 549 link->n_ref++;
14b746f7
TG
550
551 return link;
552}
553
11a7f229
TG
554int link_get(Manager *m, int ifindex, Link **ret) {
555 Link *link;
11a7f229
TG
556
557 assert(m);
11a7f229
TG
558 assert(ifindex);
559 assert(ret);
560
ae06ab10 561 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
11a7f229
TG
562 if (!link)
563 return -ENODEV;
564
565 *ret = link;
566
567 return 0;
568}
569
e331e246
TG
570static void link_set_state(Link *link, LinkState state) {
571 assert(link);
572
573 if (link->state == state)
574 return;
575
576 link->state = state;
577
578 link_send_changed(link, "AdministrativeState", NULL);
e331e246
TG
579}
580
57bd6899
TG
581static void link_enter_unmanaged(Link *link) {
582 assert(link);
583
6a7a4e4d 584 log_link_debug(link, "Unmanaged");
57bd6899 585
e331e246 586 link_set_state(link, LINK_STATE_UNMANAGED);
57bd6899 587
84de38c5 588 link_dirty(link);
57bd6899
TG
589}
590
111bb8f9
TG
591static int link_stop_clients(Link *link) {
592 int r = 0, k;
593
594 assert(link);
595 assert(link->manager);
596 assert(link->manager->event);
597
ba179154 598 if (link->dhcp_client) {
111bb8f9 599 k = sd_dhcp_client_stop(link->dhcp_client);
6a7a4e4d 600 if (k < 0)
36c7d709 601 r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
111bb8f9
TG
602 }
603
ba179154 604 if (link->ipv4ll) {
111bb8f9 605 k = sd_ipv4ll_stop(link->ipv4ll);
6a7a4e4d 606 if (k < 0)
36c7d709 607 r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
dd43110f
TG
608 }
609
f5a8c43f
TG
610 if (link->dhcp6_client) {
611 k = sd_dhcp6_client_stop(link->dhcp6_client);
612 if (k < 0)
36c7d709 613 r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
f5a8c43f 614 }
4138fb2c 615
f5a8c43f 616 if (link->ndisc_router_discovery) {
de1e9928 617 k = sd_ndisc_stop(link->ndisc_router_discovery);
6a7a4e4d 618 if (k < 0)
36c7d709 619 r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
4138fb2c
PF
620 }
621
7272b25e 622 link_lldp_emit_stop(link);
111bb8f9
TG
623 return r;
624}
625
b22d8a00 626void link_enter_failed(Link *link) {
ef1ba606 627 assert(link);
f882c247 628
370e9930 629 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2139694e
TG
630 return;
631
6a7a4e4d 632 log_link_warning(link, "Failed");
449f7554 633
e331e246 634 link_set_state(link, LINK_STATE_FAILED);
fe8db0c5 635
111bb8f9
TG
636 link_stop_clients(link);
637
84de38c5 638 link_dirty(link);
f882c247
TG
639}
640
4f434938
LP
641static Address* link_find_dhcp_server_address(Link *link) {
642 Address *address;
643
644 assert(link);
645 assert(link->network);
646
d4cdbea5 647 /* The first statically configured address if there is any */
4f434938
LP
648 LIST_FOREACH(addresses, address, link->network->static_addresses) {
649
650 if (address->family != AF_INET)
651 continue;
652
af93291c 653 if (in_addr_is_null(address->family, &address->in_addr))
4f434938
LP
654 continue;
655
656 return address;
657 }
658
659 /* If that didn't work, find a suitable address we got from the pool */
660 LIST_FOREACH(addresses, address, link->pool_addresses) {
661 if (address->family != AF_INET)
662 continue;
663
664 return address;
665 }
666
667 return NULL;
668}
669
dd43110f 670static int link_enter_configured(Link *link) {
dd43110f
TG
671 assert(link);
672 assert(link->network);
673 assert(link->state == LINK_STATE_SETTING_ROUTES);
674
6a7a4e4d 675 log_link_info(link, "Configured");
dd43110f 676
e331e246 677 link_set_state(link, LINK_STATE_CONFIGURED);
dd43110f 678
84de38c5 679 link_dirty(link);
dd43110f
TG
680
681 return 0;
682}
683
8012cd39
TG
684void link_check_ready(Link *link) {
685 Address *a;
686 Iterator i;
687
3c9b8860 688 assert(link);
adda1ed9 689
7209086d
SS
690 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
691 return;
692
adda1ed9
TG
693 if (!link->network)
694 return;
3c9b8860
TG
695
696 if (!link->static_configured)
697 return;
698
78c958f8 699 if (link_ipv4ll_enabled(link))
3c9b8860
TG
700 if (!link->ipv4ll_address ||
701 !link->ipv4ll_route)
702 return;
703
e7ab854c 704 if (link_ipv6ll_enabled(link))
c601ebf7 705 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
e7ab854c
TG
706 return;
707
3ada37a2
PF
708 if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
709 !link->dhcp4_configured) ||
710 (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
711 !link->dhcp6_configured) ||
712 (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
713 !link->dhcp4_configured && !link->dhcp6_configured))
18d29550
PF
714 return;
715
fe307276
TG
716 if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
717 return;
718
8012cd39
TG
719 SET_FOREACH(a, link->addresses, i)
720 if (!address_is_ready(a))
721 return;
722
9fdaa992
TG
723 if (link->state != LINK_STATE_CONFIGURED)
724 link_enter_configured(link);
3c9b8860
TG
725
726 return;
727}
728
1c4baffc 729static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 730 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
731 int r;
732
3c9b8860 733 assert(link->link_messages > 0);
370e9930
TG
734 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
735 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
736 LINK_STATE_LINGER));
f882c247 737
313cefa1 738 link->link_messages--;
f882c247 739
77a008c0 740 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
741 return 1;
742
1c4baffc 743 r = sd_netlink_message_get_errno(m);
c166a070 744 if (r < 0 && r != -EEXIST)
a2fae7bb 745 log_link_warning_errno(link, r, "Could not set route: %m");
f882c247 746
3c9b8860 747 if (link->link_messages == 0) {
6a7a4e4d 748 log_link_debug(link, "Routes set");
3c9b8860 749 link->static_configured = true;
8012cd39 750 link_check_ready(link);
dd3efc09 751 }
f882c247
TG
752
753 return 1;
754}
755
756static int link_enter_set_routes(Link *link) {
a6cc569e 757 Route *rt;
f882c247
TG
758 int r;
759
760 assert(link);
761 assert(link->network);
ef1ba606 762 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 763
e331e246 764 link_set_state(link, LINK_STATE_SETTING_ROUTES);
f882c247 765
3d3d4255 766 LIST_FOREACH(routes, rt, link->network->static_routes) {
483d099e 767 r = route_configure(rt, link, route_handler);
dd3efc09 768 if (r < 0) {
6a7a4e4d 769 log_link_warning_errno(link, r, "Could not set routes: %m");
3c9b8860 770 link_enter_failed(link);
a6cc569e
TG
771 return r;
772 }
773
313cefa1 774 link->link_messages++;
8ddbeaa2 775 }
f5be5601 776
3c9b8860
TG
777 if (link->link_messages == 0) {
778 link->static_configured = true;
8012cd39 779 link_check_ready(link);
431ca2ce 780 } else
6a7a4e4d 781 log_link_debug(link, "Setting routes");
f882c247
TG
782
783 return 0;
784}
785
91b5f997 786int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 787 _cleanup_link_unref_ Link *link = userdata;
5c1d3fc9
UTL
788 int r;
789
790 assert(m);
791 assert(link);
792 assert(link->ifname);
793
5da8149f 794 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
5c1d3fc9
UTL
795 return 1;
796
1c4baffc 797 r = sd_netlink_message_get_errno(m);
b90b025a 798 if (r < 0 && r != -ESRCH)
a2fae7bb 799 log_link_warning_errno(link, r, "Could not drop route: %m");
5c1d3fc9 800
5bdd314c 801 return 1;
5c1d3fc9
UTL
802}
803
1c4baffc 804static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 805 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
806 int r;
807
4958aee4 808 assert(rtnl);
f5be5601
TG
809 assert(m);
810 assert(link);
811 assert(link->ifname);
3c9b8860 812 assert(link->link_messages > 0);
370e9930
TG
813 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
814 LINK_STATE_FAILED, LINK_STATE_LINGER));
f882c247 815
313cefa1 816 link->link_messages--;
f882c247 817
5da8149f 818 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
819 return 1;
820
1c4baffc 821 r = sd_netlink_message_get_errno(m);
c166a070 822 if (r < 0 && r != -EEXIST)
a2fae7bb 823 log_link_warning_errno(link, r, "could not set address: %m");
45af44d4 824 else if (r >= 0)
200a0868 825 manager_rtnl_process_address(rtnl, m, link->manager);
f882c247 826
3c9b8860 827 if (link->link_messages == 0) {
6a7a4e4d 828 log_link_debug(link, "Addresses set");
ef1ba606 829 link_enter_set_routes(link);
dd3efc09 830 }
f882c247
TG
831
832 return 1;
833}
834
4f5f911e
LP
835static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
836 _cleanup_free_ struct in_addr *addresses = NULL;
837 size_t n_addresses = 0, n_allocated = 0;
838 char **a;
839
840 log_debug("Copying DNS server information from %s", link->ifname);
841
842 if (!link->network)
843 return 0;
844
845 STRV_FOREACH(a, link->network->dns) {
846 struct in_addr ia;
847
848 /* Only look for IPv4 addresses */
849 if (inet_pton(AF_INET, *a, &ia) <= 0)
850 continue;
851
852 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
853 return log_oom();
854
855 addresses[n_addresses++] = ia;
856 }
857
27cb34f5 858 if (link->network->dhcp_use_dns &&
4f5f911e
LP
859 link->dhcp_lease) {
860 const struct in_addr *da = NULL;
861 int n;
862
863 n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
864 if (n > 0) {
865
866 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
867 return log_oom();
868
869 memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
870 n_addresses += n;
871 }
872 }
873
874 if (n_addresses <= 0)
875 return 0;
876
877 return sd_dhcp_server_set_dns(s, addresses, n_addresses);
878}
879
880static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
881 _cleanup_free_ struct in_addr *addresses = NULL;
882 size_t n_addresses = 0, n_allocated = 0;
883 char **a;
884
885 if (!link->network)
886 return 0;
887
888 log_debug("Copying NTP server information from %s", link->ifname);
889
890 STRV_FOREACH(a, link->network->ntp) {
891 struct in_addr ia;
892
893 /* Only look for IPv4 addresses */
894 if (inet_pton(AF_INET, *a, &ia) <= 0)
895 continue;
896
897 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
898 return log_oom();
899
900 addresses[n_addresses++] = ia;
901 }
902
27cb34f5 903 if (link->network->dhcp_use_ntp &&
4f5f911e
LP
904 link->dhcp_lease) {
905 const struct in_addr *da = NULL;
906 int n;
907
908 n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
909 if (n > 0) {
910
911 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
912 return log_oom();
913
914 memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
915 n_addresses += n;
916 }
917 }
918
919 if (n_addresses <= 0)
920 return 0;
921
922 return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
923}
924
f882c247 925static int link_enter_set_addresses(Link *link) {
a6cc569e 926 Address *ad;
f882c247
TG
927 int r;
928
929 assert(link);
930 assert(link->network);
f5be5601 931 assert(link->state != _LINK_STATE_INVALID);
f882c247 932
e331e246 933 link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
f882c247 934
3d3d4255 935 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
483d099e 936 r = address_configure(ad, link, address_handler, false);
dd3efc09 937 if (r < 0) {
5a8bcb67 938 log_link_warning_errno(link, r, "Could not set addresses: %m");
f5be5601
TG
939 link_enter_failed(link);
940 return r;
941 }
942
313cefa1 943 link->link_messages++;
f882c247
TG
944 }
945
d4cdbea5
TG
946 /* now that we can figure out a default address for the dhcp server,
947 start it */
948 if (link_dhcp4_server_enabled(link)) {
d4cdbea5 949 Address *address;
4f5f911e
LP
950 Link *uplink = NULL;
951 bool acquired_uplink = false;
d4cdbea5
TG
952
953 address = link_find_dhcp_server_address(link);
954 if (!address) {
6a7a4e4d 955 log_link_warning(link, "Failed to find suitable address for DHCPv4 server instance.");
d4cdbea5
TG
956 link_enter_failed(link);
957 return 0;
958 }
959
61986155 960 /* use the server address' subnet as the pool */
9b3a67c5
TG
961 r = sd_dhcp_server_configure_pool(link->dhcp_server, &address->in_addr.in, address->prefixlen,
962 link->network->dhcp_server_pool_offset, link->network->dhcp_server_pool_size);
d4cdbea5
TG
963 if (r < 0)
964 return r;
965
966 /* TODO:
967 r = sd_dhcp_server_set_router(link->dhcp_server,
968 &main_address->in_addr.in);
969 if (r < 0)
970 return r;
d4cdbea5
TG
971 */
972
586ac6f7
LP
973 if (link->network->dhcp_server_max_lease_time_usec > 0) {
974 r = sd_dhcp_server_set_max_lease_time(
975 link->dhcp_server,
976 DIV_ROUND_UP(link->network->dhcp_server_max_lease_time_usec, USEC_PER_SEC));
977 if (r < 0)
978 return r;
979 }
980
981 if (link->network->dhcp_server_default_lease_time_usec > 0) {
982 r = sd_dhcp_server_set_default_lease_time(
983 link->dhcp_server,
984 DIV_ROUND_UP(link->network->dhcp_server_default_lease_time_usec, USEC_PER_SEC));
985 if (r < 0)
986 return r;
987 }
988
1a04db0f
LP
989 if (link->network->dhcp_server_emit_dns) {
990
4f5f911e 991 if (link->network->n_dhcp_server_dns > 0)
1a04db0f 992 r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns);
4f5f911e
LP
993 else {
994 uplink = manager_find_uplink(link->manager, link);
995 acquired_uplink = true;
996
997 if (!uplink) {
998 log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
999 r = 0;
1000 } else
1001 r = link_push_dns_to_dhcp_server(uplink, link->dhcp_server);
1002 }
1003 if (r < 0)
1004 log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
1a04db0f
LP
1005 }
1006
1007
1008 if (link->network->dhcp_server_emit_ntp) {
1009
4f5f911e 1010 if (link->network->n_dhcp_server_ntp > 0)
1a04db0f 1011 r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp);
4f5f911e
LP
1012 else {
1013 if (!acquired_uplink)
1014 uplink = manager_find_uplink(link->manager, link);
1015
1016 if (!uplink) {
1017 log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
1018 r = 0;
1019 } else
1020 r = link_push_ntp_to_dhcp_server(uplink, link->dhcp_server);
1021
1022 }
1023 if (r < 0)
1024 log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
1a04db0f
LP
1025 }
1026
77ff6022
CG
1027 r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
1028 if (r < 0) {
1029 log_link_warning_errno(link, r, "Failed to set router emission for DHCP server: %m");
1030 return r;
1031 }
1032
8eb9058d
LP
1033 if (link->network->dhcp_server_emit_timezone) {
1034 _cleanup_free_ char *buffer = NULL;
0ab8a1b6 1035 const char *tz = NULL;
8eb9058d
LP
1036
1037 if (link->network->dhcp_server_timezone)
1038 tz = link->network->dhcp_server_timezone;
1039 else {
1040 r = get_timezone(&buffer);
1041 if (r < 0)
1042 log_warning_errno(r, "Failed to determine timezone: %m");
1043 else
1044 tz = buffer;
1045 }
1046
1047 if (tz) {
1048 r = sd_dhcp_server_set_timezone(link->dhcp_server, tz);
1049 if (r < 0)
1050 return r;
1051 }
1052 }
1053
d4cdbea5
TG
1054 r = sd_dhcp_server_start(link->dhcp_server);
1055 if (r < 0) {
6a7a4e4d 1056 log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
d4cdbea5
TG
1057
1058 link_enter_failed(link);
1059
1060 return 0;
1061 }
1062
6a7a4e4d 1063 log_link_debug(link, "Offering DHCPv4 leases");
d4cdbea5
TG
1064 }
1065
6a7a4e4d 1066 if (link->link_messages == 0)
431ca2ce 1067 link_enter_set_routes(link);
6a7a4e4d
LP
1068 else
1069 log_link_debug(link, "Setting addresses");
431ca2ce 1070
f882c247
TG
1071 return 0;
1072}
1073
91b5f997 1074int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1075 _cleanup_link_unref_ Link *link = userdata;
ff254138
TG
1076 int r;
1077
1078 assert(m);
1079 assert(link);
1080 assert(link->ifname);
1081
5da8149f 1082 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ff254138
TG
1083 return 1;
1084
1c4baffc 1085 r = sd_netlink_message_get_errno(m);
b90b025a 1086 if (r < 0 && r != -EADDRNOTAVAIL)
a2fae7bb 1087 log_link_warning_errno(link, r, "Could not drop address: %m");
ff254138 1088
5bdd314c 1089 return 1;
ff254138
TG
1090}
1091
a245ced0 1092static int link_set_bridge_fdb(Link *const link) {
b98b483b
AR
1093 FdbEntry *fdb_entry;
1094 int r = 0;
1095
1096 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
ea6ec096 1097 r = fdb_entry_configure(link, fdb_entry);
9ed794a3 1098 if (r < 0) {
6a7a4e4d 1099 log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
b98b483b
AR
1100 break;
1101 }
1102 }
1103
1104 return r;
1105}
1106
23d8b221
SS
1107static int link_set_proxy_arp(Link *const link) {
1108 const char *p = NULL;
1109 int r;
1110
1111 if (!link_proxy_arp_enabled(link))
1112 return 0;
1113
1114 p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/proxy_arp");
1115
1116 r = write_string_file(p, one_zero(link->network->proxy_arp), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1117 if (r < 0)
1118 log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
1119
1120 return 0;
1121}
1122
1c4baffc 1123static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
e1853b00
SS
1124 _cleanup_link_unref_ Link *link = userdata;
1125 int r;
1126
6a7a4e4d 1127 log_link_debug(link, "Set link");
e1853b00 1128
1c4baffc 1129 r = sd_netlink_message_get_errno(m);
e1853b00 1130 if (r < 0 && r != -EEXIST) {
f2341e0a 1131 log_link_error_errno(link, r, "Could not join netdev: %m");
e1853b00
SS
1132 link_enter_failed(link);
1133 return 1;
1134 }
1135
1136 return 0;
1137}
1138
19070062 1139static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
5da8149f 1140 _cleanup_link_unref_ Link *link = userdata;
21b80ad1 1141 const sd_bus_error *e;
1346b1f0 1142
19070062 1143 assert(m);
b226d99b
TG
1144 assert(link);
1145
5da8149f 1146 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
370e9930 1147 return 1;
370e9930 1148
21b80ad1
LP
1149 e = sd_bus_message_get_error(m);
1150 if (e)
1151 log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1346b1f0
TG
1152
1153 return 1;
1154}
1155
3c9b8860 1156int link_set_hostname(Link *link, const char *hostname) {
21b80ad1 1157 int r;
1346b1f0 1158
b226d99b
TG
1159 assert(link);
1160 assert(link->manager);
1346b1f0 1161
dce391e7 1162 log_link_debug(link, "Setting transient hostname: '%s'", strna(hostname));
1346b1f0 1163
3c9b8860
TG
1164 if (!link->manager->bus) {
1165 /* TODO: replace by assert when we can rely on kdbus */
6a7a4e4d 1166 log_link_info(link, "Not connected to system bus, ignoring transient hostname.");
bcbca829
TG
1167 return 0;
1168 }
1169
9c34154a 1170 r = sd_bus_call_method_async(
b226d99b 1171 link->manager->bus,
9c34154a 1172 NULL,
1346b1f0
TG
1173 "org.freedesktop.hostname1",
1174 "/org/freedesktop/hostname1",
1175 "org.freedesktop.hostname1",
9c34154a
UTL
1176 "SetHostname",
1177 set_hostname_handler,
1178 link,
1179 "sb",
1180 hostname,
1181 false);
1346b1f0 1182
6a7a4e4d
LP
1183 if (r < 0)
1184 return log_link_error_errno(link, r, "Could not set transient hostname: %m");
b226d99b
TG
1185
1186 link_ref(link);
1346b1f0 1187
5da8149f 1188 return 0;
1346b1f0
TG
1189}
1190
21b80ad1
LP
1191static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1192 _cleanup_link_unref_ Link *link = userdata;
1193 const sd_bus_error *e;
1194
1195 assert(m);
1196 assert(link);
1197
1198 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1199 return 1;
1200
1201 e = sd_bus_message_get_error(m);
1202 if (e)
1203 log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1204
1205 return 1;
1206}
1207
64d6c229 1208int link_set_timezone(Link *link, const char *tz) {
21b80ad1
LP
1209 int r;
1210
1211 assert(link);
1212 assert(link->manager);
64d6c229 1213 assert(tz);
21b80ad1 1214
64d6c229 1215 log_link_debug(link, "Setting system timezone: '%s'", tz);
21b80ad1
LP
1216
1217 if (!link->manager->bus) {
1218 log_link_info(link, "Not connected to system bus, ignoring timezone.");
1219 return 0;
1220 }
1221
1222 r = sd_bus_call_method_async(
1223 link->manager->bus,
1224 NULL,
1225 "org.freedesktop.timedate1",
1226 "/org/freedesktop/timedate1",
1227 "org.freedesktop.timedate1",
1228 "SetTimezone",
1229 set_timezone_handler,
1230 link,
1231 "sb",
64d6c229 1232 tz,
21b80ad1
LP
1233 false);
1234 if (r < 0)
1235 return log_link_error_errno(link, r, "Could not set timezone: %m");
1236
1237 link_ref(link);
1238
1239 return 0;
1240}
1241
1c4baffc 1242static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1243 _cleanup_link_unref_ Link *link = userdata;
4f882b2a
TG
1244 int r;
1245
1246 assert(m);
1247 assert(link);
1248 assert(link->ifname);
1249
5da8149f 1250 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
4f882b2a
TG
1251 return 1;
1252
1c4baffc 1253 r = sd_netlink_message_get_errno(m);
c9ccc19f 1254 if (r < 0)
a2fae7bb 1255 log_link_warning_errno(link, r, "Could not set MTU: %m");
4f882b2a
TG
1256
1257 return 1;
1258}
1259
3c9b8860 1260int link_set_mtu(Link *link, uint32_t mtu) {
4afd3348 1261 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
4f882b2a
TG
1262 int r;
1263
1264 assert(link);
1265 assert(link->manager);
1266 assert(link->manager->rtnl);
1267
6a7a4e4d 1268 log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
4f882b2a 1269
6a7a4e4d
LP
1270 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1271 if (r < 0)
1272 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
4f882b2a 1273
1c4baffc 1274 r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
6a7a4e4d
LP
1275 if (r < 0)
1276 return log_link_error_errno(link, r, "Could not append MTU: %m");
4f882b2a 1277
1c4baffc 1278 r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
6a7a4e4d
LP
1279 if (r < 0)
1280 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
4f882b2a 1281
ae941762 1282 link_ref(link);
b226d99b 1283
4f882b2a
TG
1284 return 0;
1285}
1286
e1853b00 1287static int link_set_bridge(Link *link) {
4afd3348 1288 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
e1853b00
SS
1289 int r;
1290
1291 assert(link);
1292 assert(link->network);
1293
6a7a4e4d
LP
1294 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1295 if (r < 0)
1296 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
e1853b00
SS
1297
1298 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
6a7a4e4d
LP
1299 if (r < 0)
1300 return log_link_error_errno(link, r, "Could not set message family: %m");
e1853b00 1301
1c4baffc 1302 r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
6a7a4e4d
LP
1303 if (r < 0)
1304 return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
e1853b00 1305
84c34096 1306 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, !link->network->use_bpdu);
eb7ff4dd
SS
1307 if (r < 0)
1308 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
1309
1310 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
1311 if (r < 0)
1312 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
1313
1314 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
1315 if (r < 0)
1316 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
1317
23da66bb 1318 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, !link->network->allow_port_to_be_root);
eb7ff4dd
SS
1319 if (r < 0)
1320 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
1321
1322 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
1323 if (r < 0)
1324 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
1325
34437b4f 1326 if (link->network->cost != 0) {
1c4baffc 1327 r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
6a7a4e4d
LP
1328 if (r < 0)
1329 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
e1853b00
SS
1330 }
1331
1c4baffc 1332 r = sd_netlink_message_close_container(req);
6a7a4e4d
LP
1333 if (r < 0)
1334 return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
e1853b00 1335
1c4baffc 1336 r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
6a7a4e4d
LP
1337 if (r < 0)
1338 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
e1853b00
SS
1339
1340 link_ref(link);
1341
1342 return r;
1343}
1344
34437b4f
LP
1345static int link_lldp_save(Link *link) {
1346 _cleanup_free_ char *temp_path = NULL;
1347 _cleanup_fclose_ FILE *f = NULL;
1348 sd_lldp_neighbor **l = NULL;
1349 int n = 0, r, i;
49699bac
SS
1350
1351 assert(link);
34437b4f
LP
1352 assert(link->lldp_file);
1353
1354 if (!link->lldp) {
1355 (void) unlink(link->lldp_file);
1356 return 0;
1357 }
1358
1359 r = sd_lldp_get_neighbors(link->lldp, &l);
1360 if (r < 0)
1361 goto finish;
1362 if (r == 0) {
1363 (void) unlink(link->lldp_file);
1364 goto finish;
1365 }
1366
1367 n = r;
1368
1369 r = fopen_temporary(link->lldp_file, &f, &temp_path);
1370 if (r < 0)
1371 goto finish;
1372
1373 fchmod(fileno(f), 0644);
49699bac 1374
34437b4f
LP
1375 for (i = 0; i < n; i++) {
1376 const void *p;
1377 le64_t u;
1378 size_t sz;
1379
1380 r = sd_lldp_neighbor_get_raw(l[i], &p, &sz);
9ef61f2e 1381 if (r < 0)
34437b4f
LP
1382 goto finish;
1383
1384 u = htole64(sz);
1385 (void) fwrite(&u, 1, sizeof(u), f);
1386 (void) fwrite(p, 1, sz, f);
1387 }
49699bac 1388
34437b4f
LP
1389 r = fflush_and_check(f);
1390 if (r < 0)
1391 goto finish;
1392
1393 if (rename(temp_path, link->lldp_file) < 0) {
1394 r = -errno;
1395 goto finish;
9ef61f2e 1396 }
34437b4f
LP
1397
1398finish:
1399 if (r < 0) {
1400 (void) unlink(link->lldp_file);
1401 if (temp_path)
1402 (void) unlink(temp_path);
1403
1404 log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file);
1405 }
1406
1407 if (l) {
1408 for (i = 0; i < n; i++)
1409 sd_lldp_neighbor_unref(l[i]);
1410 free(l);
1411 }
1412
1413 return r;
1414}
1415
90dffb22 1416static void lldp_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) {
34437b4f 1417 Link *link = userdata;
90dffb22 1418 int r;
34437b4f
LP
1419
1420 assert(link);
1421
1422 (void) link_lldp_save(link);
90dffb22 1423
7272b25e 1424 if (link_lldp_emit_enabled(link) && event == SD_LLDP_EVENT_ADDED) {
90dffb22
LP
1425 /* If we received information about a new neighbor, restart the LLDP "fast" logic */
1426
1427 log_link_debug(link, "Received LLDP datagram from previously unknown neighbor, restarting 'fast' LLDP transmission.");
1428
7272b25e 1429 r = link_lldp_emit_start(link);
90dffb22
LP
1430 if (r < 0)
1431 log_link_warning_errno(link, r, "Failed to restart LLDP transmission: %m");
1432 }
49699bac
SS
1433}
1434
e7ab854c
TG
1435static int link_acquire_ipv6_conf(Link *link) {
1436 int r;
1437
1438 assert(link);
1439
1440 if (link_dhcp6_enabled(link)) {
1441 assert(link->dhcp6_client);
c601ebf7 1442 assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
e7ab854c
TG
1443
1444 log_link_debug(link, "Acquiring DHCPv6 lease");
1445
c601ebf7
TG
1446 r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
1447 if (r < 0 && r != -EBUSY)
1448 return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
1449
e7ab854c 1450 r = sd_dhcp6_client_start(link->dhcp6_client);
63348d13 1451 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1452 return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
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)
439689c6
SS
1589 for this interface then disable IPv6 else enable it. */
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
fe307276
TG
2170 /* We handle router advertisments ourselves, tell the kernel to GTFO */
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);