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