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