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