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