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