]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-link.c
Merge pull request #1979 from evverx/build-install-systemd-path-completion
[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 (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
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 assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
1264
1265 log_link_debug(link, "Acquiring DHCPv6 lease");
1266
1267 r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
1268 if (r < 0 && r != -EBUSY)
1269 return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
1270
1271 r = sd_dhcp6_client_start(link->dhcp6_client);
1272 if (r < 0 && r != -EBUSY)
1273 return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
1274 }
1275
1276 if (link_ipv6_accept_ra_enabled(link)) {
1277 assert(link->ndisc_router_discovery);
1278
1279 log_link_debug(link, "Discovering IPv6 routers");
1280
1281 r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
1282 if (r < 0 && r != -EBUSY)
1283 return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
1284 }
1285
1286 return 0;
1287 }
1288
1289 static int link_acquire_conf(Link *link) {
1290 int r;
1291
1292 assert(link);
1293 assert(link->network);
1294 assert(link->manager);
1295 assert(link->manager->event);
1296
1297 if (link_ipv4ll_enabled(link)) {
1298 assert(link->ipv4ll);
1299
1300 log_link_debug(link, "Acquiring IPv4 link-local address");
1301
1302 r = sd_ipv4ll_start(link->ipv4ll);
1303 if (r < 0)
1304 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
1305 }
1306
1307 if (link_dhcp4_enabled(link)) {
1308 assert(link->dhcp_client);
1309
1310 log_link_debug(link, "Acquiring DHCPv4 lease");
1311
1312 r = sd_dhcp_client_start(link->dhcp_client);
1313 if (r < 0)
1314 return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
1315 }
1316
1317 if (link_lldp_enabled(link)) {
1318 assert(link->lldp);
1319
1320 log_link_debug(link, "Starting LLDP");
1321
1322 r = sd_lldp_start(link->lldp);
1323 if (r < 0)
1324 return log_link_warning_errno(link, r, "Could not start LLDP: %m");
1325 }
1326
1327 return 0;
1328 }
1329
1330 bool link_has_carrier(Link *link) {
1331 /* see Documentation/networking/operstates.txt in the kernel sources */
1332
1333 if (link->kernel_operstate == IF_OPER_UP)
1334 return true;
1335
1336 if (link->kernel_operstate == IF_OPER_UNKNOWN)
1337 /* operstate may not be implemented, so fall back to flags */
1338 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
1339 return true;
1340
1341 return false;
1342 }
1343
1344 static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1345 _cleanup_link_unref_ Link *link = userdata;
1346 int r;
1347
1348 assert(link);
1349
1350 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1351 return 1;
1352
1353 r = sd_netlink_message_get_errno(m);
1354 if (r < 0)
1355 /* we warn but don't fail the link, as it may be
1356 brought up later */
1357 log_link_warning_errno(link, r, "Could not bring up interface: %m");
1358
1359 return 1;
1360 }
1361
1362 static int link_up(Link *link) {
1363 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
1364 uint8_t ipv6ll_mode;
1365 int r;
1366
1367 assert(link);
1368 assert(link->network);
1369 assert(link->manager);
1370 assert(link->manager->rtnl);
1371
1372 log_link_debug(link, "Bringing link up");
1373
1374 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1375 if (r < 0)
1376 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1377
1378 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1379 if (r < 0)
1380 return log_link_error_errno(link, r, "Could not set link flags: %m");
1381
1382 if (link->network->mac) {
1383 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1384 if (r < 0)
1385 return log_link_error_errno(link, r, "Could not set MAC address: %m");
1386 }
1387
1388 if (link->network->mtu) {
1389 r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
1390 if (r < 0)
1391 return log_link_error_errno(link, r, "Could not set MTU: %m");
1392 }
1393
1394 r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
1395 if (r < 0)
1396 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
1397
1398 if (socket_ipv6_is_supported()) {
1399 /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
1400 r = sd_netlink_message_open_container(req, AF_INET6);
1401 if (r < 0)
1402 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
1403
1404 ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
1405 r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
1406 if (r < 0)
1407 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
1408
1409 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1410 r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
1411 if (r < 0)
1412 return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %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 AF_INET6 container: %m");
1418 }
1419
1420 r = sd_netlink_message_close_container(req);
1421 if (r < 0)
1422 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
1423
1424 r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1425 if (r < 0)
1426 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1427
1428 link_ref(link);
1429
1430 return 0;
1431 }
1432
1433 static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1434 _cleanup_link_unref_ Link *link = userdata;
1435 int r;
1436
1437 assert(link);
1438
1439 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1440 return 1;
1441
1442 r = sd_netlink_message_get_errno(m);
1443 if (r < 0)
1444 log_link_warning_errno(link, r, "Could not bring down interface: %m");
1445
1446 return 1;
1447 }
1448
1449 static int link_down(Link *link) {
1450 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
1451 int r;
1452
1453 assert(link);
1454 assert(link->manager);
1455 assert(link->manager->rtnl);
1456
1457 log_link_debug(link, "Bringing link down");
1458
1459 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1460 RTM_SETLINK, link->ifindex);
1461 if (r < 0)
1462 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1463
1464 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
1465 if (r < 0)
1466 return log_link_error_errno(link, r, "Could not set link flags: %m");
1467
1468 r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
1469 if (r < 0)
1470 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1471
1472 link_ref(link);
1473
1474 return 0;
1475 }
1476
1477 static int link_handle_bound_to_list(Link *link) {
1478 Link *l;
1479 Iterator i;
1480 int r;
1481 bool required_up = false;
1482 bool link_is_up = false;
1483
1484 assert(link);
1485
1486 if (hashmap_isempty(link->bound_to_links))
1487 return 0;
1488
1489 if (link->flags & IFF_UP)
1490 link_is_up = true;
1491
1492 HASHMAP_FOREACH (l, link->bound_to_links, i)
1493 if (link_has_carrier(l)) {
1494 required_up = true;
1495 break;
1496 }
1497
1498 if (!required_up && link_is_up) {
1499 r = link_down(link);
1500 if (r < 0)
1501 return r;
1502 } else if (required_up && !link_is_up) {
1503 r = link_up(link);
1504 if (r < 0)
1505 return r;
1506 }
1507
1508 return 0;
1509 }
1510
1511 static int link_handle_bound_by_list(Link *link) {
1512 Iterator i;
1513 Link *l;
1514 int r;
1515
1516 assert(link);
1517
1518 if (hashmap_isempty(link->bound_by_links))
1519 return 0;
1520
1521 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1522 r = link_handle_bound_to_list(l);
1523 if (r < 0)
1524 return r;
1525 }
1526
1527 return 0;
1528 }
1529
1530 static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1531 int r;
1532
1533 assert(link);
1534 assert(carrier);
1535
1536 if (link == carrier)
1537 return 0;
1538
1539 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1540 return 0;
1541
1542 r = hashmap_ensure_allocated(h, NULL);
1543 if (r < 0)
1544 return r;
1545
1546 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1547 if (r < 0)
1548 return r;
1549
1550 return 0;
1551 }
1552
1553 static int link_new_bound_by_list(Link *link) {
1554 Manager *m;
1555 Link *carrier;
1556 Iterator i;
1557 int r;
1558 bool list_updated = false;
1559
1560 assert(link);
1561 assert(link->manager);
1562
1563 m = link->manager;
1564
1565 HASHMAP_FOREACH (carrier, m->links, i) {
1566 if (!carrier->network)
1567 continue;
1568
1569 if (strv_isempty(carrier->network->bind_carrier))
1570 continue;
1571
1572 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1573 r = link_put_carrier(link, carrier, &link->bound_by_links);
1574 if (r < 0)
1575 return r;
1576
1577 list_updated = true;
1578 }
1579 }
1580
1581 if (list_updated)
1582 link_dirty(link);
1583
1584 HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
1585 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1586 if (r < 0)
1587 return r;
1588
1589 link_dirty(carrier);
1590 }
1591
1592 return 0;
1593 }
1594
1595 static int link_new_bound_to_list(Link *link) {
1596 Manager *m;
1597 Link *carrier;
1598 Iterator i;
1599 int r;
1600 bool list_updated = false;
1601
1602 assert(link);
1603 assert(link->manager);
1604
1605 if (!link->network)
1606 return 0;
1607
1608 if (strv_isempty(link->network->bind_carrier))
1609 return 0;
1610
1611 m = link->manager;
1612
1613 HASHMAP_FOREACH (carrier, m->links, i) {
1614 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1615 r = link_put_carrier(link, carrier, &link->bound_to_links);
1616 if (r < 0)
1617 return r;
1618
1619 list_updated = true;
1620 }
1621 }
1622
1623 if (list_updated)
1624 link_dirty(link);
1625
1626 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1627 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1628 if (r < 0)
1629 return r;
1630
1631 link_dirty(carrier);
1632 }
1633
1634 return 0;
1635 }
1636
1637 static int link_new_carrier_maps(Link *link) {
1638 int r;
1639
1640 r = link_new_bound_by_list(link);
1641 if (r < 0)
1642 return r;
1643
1644 r = link_handle_bound_by_list(link);
1645 if (r < 0)
1646 return r;
1647
1648 r = link_new_bound_to_list(link);
1649 if (r < 0)
1650 return r;
1651
1652 r = link_handle_bound_to_list(link);
1653 if (r < 0)
1654 return r;
1655
1656 return 0;
1657 }
1658
1659 static void link_free_bound_to_list(Link *link) {
1660 Link *bound_to;
1661 Iterator i;
1662
1663 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1664 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1665
1666 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
1667 link_dirty(bound_to);
1668 }
1669
1670 return;
1671 }
1672
1673 static void link_free_bound_by_list(Link *link) {
1674 Link *bound_by;
1675 Iterator i;
1676
1677 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1678 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1679
1680 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
1681 link_dirty(bound_by);
1682 link_handle_bound_to_list(bound_by);
1683 }
1684 }
1685
1686 return;
1687 }
1688
1689 static void link_free_carrier_maps(Link *link) {
1690 bool list_updated = false;
1691
1692 assert(link);
1693
1694 if (!hashmap_isempty(link->bound_to_links)) {
1695 link_free_bound_to_list(link);
1696 list_updated = true;
1697 }
1698
1699 if (!hashmap_isempty(link->bound_by_links)) {
1700 link_free_bound_by_list(link);
1701 list_updated = true;
1702 }
1703
1704 if (list_updated)
1705 link_dirty(link);
1706
1707 return;
1708 }
1709
1710 void link_drop(Link *link) {
1711 if (!link || link->state == LINK_STATE_LINGER)
1712 return;
1713
1714 link_set_state(link, LINK_STATE_LINGER);
1715
1716 link_free_carrier_maps(link);
1717
1718 log_link_debug(link, "Link removed");
1719
1720 (void)unlink(link->state_file);
1721 link_unref(link);
1722
1723 return;
1724 }
1725
1726 static int link_joined(Link *link) {
1727 int r;
1728
1729 assert(link);
1730 assert(link->network);
1731
1732 if (!hashmap_isempty(link->bound_to_links)) {
1733 r = link_handle_bound_to_list(link);
1734 if (r < 0)
1735 return r;
1736 } else if (!(link->flags & IFF_UP)) {
1737 r = link_up(link);
1738 if (r < 0) {
1739 link_enter_failed(link);
1740 return r;
1741 }
1742 }
1743
1744 if(link->network->bridge) {
1745 r = link_set_bridge(link);
1746 if (r < 0)
1747 log_link_error_errno(link, r, "Could not set bridge message: %m");
1748 }
1749
1750 return link_enter_set_addresses(link);
1751 }
1752
1753 static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1754 _cleanup_link_unref_ Link *link = userdata;
1755 int r;
1756
1757 assert(link);
1758 assert(link->network);
1759
1760 link->enslaving --;
1761
1762 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1763 return 1;
1764
1765 r = sd_netlink_message_get_errno(m);
1766 if (r < 0 && r != -EEXIST) {
1767 log_link_error_errno(link, r, "Could not join netdev: %m");
1768 link_enter_failed(link);
1769 return 1;
1770 } else
1771 log_link_debug(link, "Joined netdev");
1772
1773 if (link->enslaving <= 0)
1774 link_joined(link);
1775
1776 return 1;
1777 }
1778
1779 static int link_enter_join_netdev(Link *link) {
1780 NetDev *netdev;
1781 Iterator i;
1782 int r;
1783
1784 assert(link);
1785 assert(link->network);
1786 assert(link->state == LINK_STATE_PENDING);
1787
1788 link_set_state(link, LINK_STATE_ENSLAVING);
1789
1790 link_dirty(link);
1791
1792 if (!link->network->bridge &&
1793 !link->network->bond &&
1794 hashmap_isempty(link->network->stacked_netdevs))
1795 return link_joined(link);
1796
1797 if (link->network->bond) {
1798 log_struct(LOG_DEBUG,
1799 LOG_LINK_INTERFACE(link),
1800 LOG_NETDEV_INTERFACE(link->network->bond),
1801 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
1802 NULL);
1803
1804 r = netdev_join(link->network->bond, link, netdev_join_handler);
1805 if (r < 0) {
1806 log_struct_errno(LOG_WARNING, r,
1807 LOG_LINK_INTERFACE(link),
1808 LOG_NETDEV_INTERFACE(link->network->bond),
1809 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
1810 NULL);
1811
1812 link_enter_failed(link);
1813 return r;
1814 }
1815
1816 link->enslaving ++;
1817 }
1818
1819 if (link->network->bridge) {
1820 log_struct(LOG_DEBUG,
1821 LOG_LINK_INTERFACE(link),
1822 LOG_NETDEV_INTERFACE(link->network->bridge),
1823 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
1824 NULL);
1825
1826 r = netdev_join(link->network->bridge, link, netdev_join_handler);
1827 if (r < 0) {
1828 log_struct_errno(LOG_WARNING, r,
1829 LOG_LINK_INTERFACE(link),
1830 LOG_NETDEV_INTERFACE(link->network->bridge),
1831 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
1832 NULL),
1833 link_enter_failed(link);
1834 return r;
1835 }
1836
1837 link->enslaving ++;
1838 }
1839
1840 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1841
1842 log_struct(LOG_DEBUG,
1843 LOG_LINK_INTERFACE(link),
1844 LOG_NETDEV_INTERFACE(netdev),
1845 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
1846 NULL);
1847
1848 r = netdev_join(netdev, link, netdev_join_handler);
1849 if (r < 0) {
1850 log_struct_errno(LOG_WARNING, r,
1851 LOG_LINK_INTERFACE(link),
1852 LOG_NETDEV_INTERFACE(netdev),
1853 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
1854 NULL);
1855 link_enter_failed(link);
1856 return r;
1857 }
1858
1859 link->enslaving ++;
1860 }
1861
1862 return 0;
1863 }
1864
1865 static int link_set_ipv4_forward(Link *link) {
1866 int r;
1867
1868 if (!link_ipv4_forward_enabled(link))
1869 return 0;
1870
1871 /* We propagate the forwarding flag from one interface to the
1872 * global setting one way. This means: as long as at least one
1873 * interface was configured at any time that had IP forwarding
1874 * enabled the setting will stay on for good. We do this
1875 * primarily to keep IPv4 and IPv6 packet forwarding behaviour
1876 * somewhat in sync (see below). */
1877
1878 r = write_string_file("/proc/sys/net/ipv4/ip_forward", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1879 if (r < 0)
1880 log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
1881
1882 return 0;
1883 }
1884
1885 static int link_set_ipv6_forward(Link *link) {
1886 int r;
1887
1888 if (!link_ipv6_forward_enabled(link))
1889 return 0;
1890
1891 /* On Linux, the IPv6 stack does not not know a per-interface
1892 * packet forwarding setting: either packet forwarding is on
1893 * for all, or off for all. We hence don't bother with a
1894 * per-interface setting, but simply propagate the interface
1895 * flag, if it is set, to the global flag, one-way. Note that
1896 * while IPv4 would allow a per-interface flag, we expose the
1897 * same behaviour there and also propagate the setting from
1898 * one to all, to keep things simple (see above). */
1899
1900 r = write_string_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1901 if (r < 0)
1902 log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
1903
1904 return 0;
1905 }
1906
1907 static int link_set_ipv6_privacy_extensions(Link *link) {
1908 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1909 IPv6PrivacyExtensions s;
1910 const char *p = NULL;
1911 int r;
1912
1913 s = link_ipv6_privacy_extensions(link);
1914 if (s < 0)
1915 return 0;
1916
1917 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
1918 xsprintf(buf, "%u", (unsigned) link->network->ipv6_privacy_extensions);
1919
1920 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1921 if (r < 0)
1922 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
1923
1924 return 0;
1925 }
1926
1927 static int link_set_ipv6_accept_ra(Link *link) {
1928 const char *p = NULL;
1929 int r;
1930
1931 /* Make this a NOP if IPv6 is not available */
1932 if (!socket_ipv6_is_supported())
1933 return 0;
1934
1935 if (link->flags & IFF_LOOPBACK)
1936 return 0;
1937
1938 if (!link->network)
1939 return 0;
1940
1941 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
1942
1943 /* We handle router advertisments ourselves, tell the kernel to GTFO */
1944 r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1945 if (r < 0)
1946 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
1947
1948 return 0;
1949 }
1950
1951 static int link_set_ipv6_dad_transmits(Link *link) {
1952 char buf[DECIMAL_STR_MAX(int) + 1];
1953 const char *p = NULL;
1954 int r;
1955
1956 /* Make this a NOP if IPv6 is not available */
1957 if (!socket_ipv6_is_supported())
1958 return 0;
1959
1960 if (link->flags & IFF_LOOPBACK)
1961 return 0;
1962
1963 if (!link->network)
1964 return 0;
1965
1966 if (link->network->ipv6_dad_transmits < 0)
1967 return 0;
1968
1969 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
1970 xsprintf(buf, "%i", link->network->ipv6_dad_transmits);
1971
1972 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1973 if (r < 0)
1974 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
1975
1976 return 0;
1977 }
1978
1979 static int link_set_ipv6_hop_limit(Link *link) {
1980 char buf[DECIMAL_STR_MAX(int) + 1];
1981 const char *p = NULL;
1982 int r;
1983
1984 /* Make this a NOP if IPv6 is not available */
1985 if (!socket_ipv6_is_supported())
1986 return 0;
1987
1988 if (link->flags & IFF_LOOPBACK)
1989 return 0;
1990
1991 if (!link->network)
1992 return 0;
1993
1994 if (link->network->ipv6_hop_limit < 0)
1995 return 0;
1996
1997 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
1998 xsprintf(buf, "%i", link->network->ipv6_hop_limit);
1999
2000 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
2001 if (r < 0)
2002 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
2003
2004 return 0;
2005 }
2006
2007 static int link_drop_foreign_config(Link *link) {
2008 Address *address;
2009 Route *route;
2010 Iterator i;
2011 int r;
2012
2013 SET_FOREACH(address, link->addresses_foreign, i) {
2014 /* we consider IPv6LL addresses to be managed by the kernel */
2015 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2016 continue;
2017
2018 r = address_remove(address, link, link_address_remove_handler);
2019 if (r < 0)
2020 return r;
2021 }
2022
2023 SET_FOREACH(route, link->routes_foreign, i) {
2024 /* do not touch routes managed by the kernel */
2025 if (route->protocol == RTPROT_KERNEL)
2026 continue;
2027
2028 r = route_remove(route, link, link_address_remove_handler);
2029 if (r < 0)
2030 return r;
2031 }
2032
2033 return 0;
2034 }
2035
2036 static int link_configure(Link *link) {
2037 int r;
2038
2039 assert(link);
2040 assert(link->network);
2041 assert(link->state == LINK_STATE_PENDING);
2042
2043 r = link_drop_foreign_config(link);
2044 if (r < 0)
2045 return r;
2046
2047 r = link_set_bridge_fdb(link);
2048 if (r < 0)
2049 return r;
2050
2051 r = link_set_ipv4_forward(link);
2052 if (r < 0)
2053 return r;
2054
2055 r = link_set_ipv6_forward(link);
2056 if (r < 0)
2057 return r;
2058
2059 r = link_set_ipv6_privacy_extensions(link);
2060 if (r < 0)
2061 return r;
2062
2063 r = link_set_ipv6_accept_ra(link);
2064 if (r < 0)
2065 return r;
2066
2067 r = link_set_ipv6_dad_transmits(link);
2068 if (r < 0)
2069 return r;
2070
2071 r = link_set_ipv6_hop_limit(link);
2072 if (r < 0)
2073 return r;
2074
2075 if (link_ipv4ll_enabled(link)) {
2076 r = ipv4ll_configure(link);
2077 if (r < 0)
2078 return r;
2079 }
2080
2081 if (link_dhcp4_enabled(link)) {
2082 r = dhcp4_configure(link);
2083 if (r < 0)
2084 return r;
2085 }
2086
2087 if (link_dhcp4_server_enabled(link)) {
2088 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2089 if (r < 0)
2090 return r;
2091
2092 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2093 if (r < 0)
2094 return r;
2095 }
2096
2097 if (link_dhcp6_enabled(link) ||
2098 link_ipv6_accept_ra_enabled(link)) {
2099 r = dhcp6_configure(link);
2100 if (r < 0)
2101 return r;
2102 }
2103
2104 if (link_ipv6_accept_ra_enabled(link)) {
2105 r = ndisc_configure(link);
2106 if (r < 0)
2107 return r;
2108 }
2109
2110 if (link_lldp_enabled(link)) {
2111 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
2112 if (r < 0)
2113 return r;
2114
2115 r = sd_lldp_attach_event(link->lldp, NULL, 0);
2116 if (r < 0)
2117 return r;
2118
2119 r = sd_lldp_set_callback(link->lldp,
2120 lldp_handler, link);
2121 if (r < 0)
2122 return r;
2123 }
2124
2125 if (link_has_carrier(link)) {
2126 r = link_acquire_conf(link);
2127 if (r < 0)
2128 return r;
2129
2130 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
2131 r = link_acquire_ipv6_conf(link);
2132 if (r < 0)
2133 return r;
2134 }
2135 }
2136
2137 return link_enter_join_netdev(link);
2138 }
2139
2140 static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
2141 void *userdata) {
2142 _cleanup_link_unref_ Link *link = userdata;
2143 Network *network;
2144 int r;
2145
2146 assert(link);
2147 assert(link->ifname);
2148 assert(link->manager);
2149
2150 if (link->state != LINK_STATE_PENDING)
2151 return 1;
2152
2153 log_link_debug(link, "Link state is up-to-date");
2154
2155 r = link_new_bound_by_list(link);
2156 if (r < 0)
2157 return r;
2158
2159 r = link_handle_bound_by_list(link);
2160 if (r < 0)
2161 return r;
2162
2163 if (!link->network) {
2164 r = network_get(link->manager, link->udev_device, link->ifname,
2165 &link->mac, &network);
2166 if (r == -ENOENT) {
2167 link_enter_unmanaged(link);
2168 return 1;
2169 } else if (r < 0)
2170 return r;
2171
2172 if (link->flags & IFF_LOOPBACK) {
2173 if (network->link_local != ADDRESS_FAMILY_NO)
2174 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
2175
2176 if (network->dhcp != ADDRESS_FAMILY_NO)
2177 log_link_debug(link, "Ignoring DHCP clients for loopback link");
2178
2179 if (network->dhcp_server)
2180 log_link_debug(link, "Ignoring DHCP server for loopback link");
2181 }
2182
2183 r = network_apply(link->manager, network, link);
2184 if (r < 0)
2185 return r;
2186 }
2187
2188 r = link_new_bound_to_list(link);
2189 if (r < 0)
2190 return r;
2191
2192 r = link_configure(link);
2193 if (r < 0)
2194 return r;
2195
2196 return 1;
2197 }
2198
2199 int link_initialized(Link *link, struct udev_device *device) {
2200 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
2201 int r;
2202
2203 assert(link);
2204 assert(link->manager);
2205 assert(link->manager->rtnl);
2206 assert(device);
2207
2208 if (link->state != LINK_STATE_PENDING)
2209 return 0;
2210
2211 if (link->udev_device)
2212 return 0;
2213
2214 log_link_debug(link, "udev initialized link");
2215
2216 link->udev_device = udev_device_ref(device);
2217
2218 /* udev has initialized the link, but we don't know if we have yet
2219 * processed the NEWLINK messages with the latest state. Do a GETLINK,
2220 * when it returns we know that the pending NEWLINKs have already been
2221 * processed and that we are up-to-date */
2222
2223 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2224 link->ifindex);
2225 if (r < 0)
2226 return r;
2227
2228 r = sd_netlink_call_async(link->manager->rtnl, req,
2229 link_initialized_and_synced, link, 0, NULL);
2230 if (r < 0)
2231 return r;
2232
2233 link_ref(link);
2234
2235 return 0;
2236 }
2237
2238 static int link_load(Link *link) {
2239 _cleanup_free_ char *network_file = NULL,
2240 *addresses = NULL,
2241 *routes = NULL,
2242 *dhcp4_address = NULL,
2243 *ipv4ll_address = NULL;
2244 union in_addr_union address;
2245 union in_addr_union route_dst;
2246 const char *p;
2247 int r;
2248
2249 assert(link);
2250
2251 r = parse_env_file(link->state_file, NEWLINE,
2252 "NETWORK_FILE", &network_file,
2253 "ADDRESSES", &addresses,
2254 "ROUTES", &routes,
2255 "DHCP4_ADDRESS", &dhcp4_address,
2256 "IPV4LL_ADDRESS", &ipv4ll_address,
2257 NULL);
2258 if (r < 0 && r != -ENOENT)
2259 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2260
2261 if (network_file) {
2262 Network *network;
2263 char *suffix;
2264
2265 /* drop suffix */
2266 suffix = strrchr(network_file, '.');
2267 if (!suffix) {
2268 log_link_debug(link, "Failed to get network name from %s", network_file);
2269 goto network_file_fail;
2270 }
2271 *suffix = '\0';
2272
2273 r = network_get_by_name(link->manager, basename(network_file), &network);
2274 if (r < 0) {
2275 log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2276 goto network_file_fail;
2277 }
2278
2279 r = network_apply(link->manager, network, link);
2280 if (r < 0)
2281 return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2282 }
2283
2284 network_file_fail:
2285
2286 if (addresses) {
2287 p = addresses;
2288
2289 for (;;) {
2290 _cleanup_free_ char *address_str = NULL;
2291 char *prefixlen_str;
2292 int family;
2293 unsigned char prefixlen;
2294
2295 r = extract_first_word(&p, &address_str, NULL, 0);
2296 if (r < 0) {
2297 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2298 continue;
2299 }
2300 if (r == 0)
2301 break;
2302
2303 prefixlen_str = strchr(address_str, '/');
2304 if (!prefixlen_str) {
2305 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
2306 continue;
2307 }
2308
2309 *prefixlen_str ++ = '\0';
2310
2311 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
2312 if (r != 1) {
2313 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
2314 continue;
2315 }
2316
2317 r = in_addr_from_string_auto(address_str, &family, &address);
2318 if (r < 0) {
2319 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
2320 continue;
2321 }
2322
2323 r = address_add(link, family, &address, prefixlen, NULL);
2324 if (r < 0)
2325 return log_link_error_errno(link, r, "Failed to add address: %m");
2326 }
2327 }
2328
2329 if (routes) {
2330 for (;;) {
2331 Route *route;
2332 _cleanup_free_ char *route_str = NULL;
2333 _cleanup_event_source_unref_ sd_event_source *expire = NULL;
2334 usec_t lifetime;
2335 char *prefixlen_str;
2336 int family;
2337 unsigned char prefixlen, tos, table;
2338 uint32_t priority;
2339
2340 r = extract_first_word(&p, &route_str, NULL, 0);
2341 if (r < 0) {
2342 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
2343 continue;
2344 }
2345 if (r == 0)
2346 break;
2347
2348 prefixlen_str = strchr(route_str, '/');
2349 if (!prefixlen_str) {
2350 log_link_debug(link, "Failed to parse route %s", route_str);
2351 continue;
2352 }
2353
2354 *prefixlen_str ++ = '\0';
2355
2356 r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
2357 if (r != 5) {
2358 log_link_debug(link,
2359 "Failed to parse destination prefix length, tos, priority, table or expiration %s",
2360 prefixlen_str);
2361 continue;
2362 }
2363
2364 r = in_addr_from_string_auto(route_str, &family, &route_dst);
2365 if (r < 0) {
2366 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
2367 continue;
2368 }
2369
2370 r = route_add(link, family, &route_dst, prefixlen, tos, priority, table, &route);
2371 if (r < 0)
2372 return log_link_error_errno(link, r, "Failed to add route: %m");
2373
2374 if (lifetime != USEC_INFINITY) {
2375 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
2376 0, route_expire_handler, route);
2377 if (r < 0)
2378 log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
2379 }
2380
2381 route->lifetime = lifetime;
2382 sd_event_source_unref(route->expire);
2383 route->expire = expire;
2384 expire = NULL;
2385 }
2386 }
2387
2388 if (dhcp4_address) {
2389 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
2390 if (r < 0) {
2391 log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address);
2392 goto dhcp4_address_fail;
2393 }
2394
2395 r = sd_dhcp_client_new(&link->dhcp_client);
2396 if (r < 0)
2397 return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m");
2398
2399 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
2400 if (r < 0)
2401 return log_link_error_errno(link, r, "Falied to set inital DHCPv4 address %s: %m", dhcp4_address);
2402 }
2403
2404 dhcp4_address_fail:
2405
2406 if (ipv4ll_address) {
2407 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
2408 if (r < 0) {
2409 log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address);
2410 goto ipv4ll_address_fail;
2411 }
2412
2413 r = sd_ipv4ll_new(&link->ipv4ll);
2414 if (r < 0)
2415 return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m");
2416
2417 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
2418 if (r < 0)
2419 return log_link_error_errno(link, r, "Falied to set inital IPv4LL address %s: %m", ipv4ll_address);
2420 }
2421
2422 ipv4ll_address_fail:
2423
2424 return 0;
2425 }
2426
2427 int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
2428 Link *link;
2429 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2430 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2431 int r;
2432
2433 assert(m);
2434 assert(m->rtnl);
2435 assert(message);
2436 assert(ret);
2437
2438 r = link_new(m, message, ret);
2439 if (r < 0)
2440 return r;
2441
2442 link = *ret;
2443
2444 log_link_debug(link, "Link %d added", link->ifindex);
2445
2446 r = link_load(link);
2447 if (r < 0)
2448 return r;
2449
2450 if (detect_container() <= 0) {
2451 /* not in a container, udev will be around */
2452 sprintf(ifindex_str, "n%d", link->ifindex);
2453 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2454 if (!device) {
2455 r = log_link_warning_errno(link, errno, "Could not find udev device: %m");
2456 goto failed;
2457 }
2458
2459 if (udev_device_get_is_initialized(device) <= 0) {
2460 /* not yet ready */
2461 log_link_debug(link, "link pending udev initialization...");
2462 return 0;
2463 }
2464
2465 r = link_initialized(link, device);
2466 if (r < 0)
2467 goto failed;
2468 } else {
2469 /* we are calling a callback directly, so must take a ref */
2470 link_ref(link);
2471
2472 r = link_initialized_and_synced(m->rtnl, NULL, link);
2473 if (r < 0)
2474 goto failed;
2475 }
2476
2477 return 0;
2478 failed:
2479 link_enter_failed(link);
2480 return r;
2481 }
2482
2483 int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
2484 int r;
2485
2486 assert(link);
2487
2488 log_link_info(link, "Gained IPv6LL");
2489
2490 link->ipv6ll_address = *address;
2491 link_check_ready(link);
2492
2493 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
2494 r = link_acquire_ipv6_conf(link);
2495 if (r < 0) {
2496 link_enter_failed(link);
2497 return r;
2498 }
2499 }
2500
2501 return 0;
2502 }
2503
2504 static int link_carrier_gained(Link *link) {
2505 int r;
2506
2507 assert(link);
2508
2509 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
2510 r = link_acquire_conf(link);
2511 if (r < 0) {
2512 link_enter_failed(link);
2513 return r;
2514 }
2515 }
2516
2517 r = link_handle_bound_by_list(link);
2518 if (r < 0)
2519 return r;
2520
2521 return 0;
2522 }
2523
2524 static int link_carrier_lost(Link *link) {
2525 int r;
2526
2527 assert(link);
2528
2529 r = link_stop_clients(link);
2530 if (r < 0) {
2531 link_enter_failed(link);
2532 return r;
2533 }
2534
2535 r = link_handle_bound_by_list(link);
2536 if (r < 0)
2537 return r;
2538
2539 return 0;
2540 }
2541
2542 int link_carrier_reset(Link *link) {
2543 int r;
2544
2545 assert(link);
2546
2547 if (link_has_carrier(link)) {
2548 r = link_carrier_lost(link);
2549 if (r < 0)
2550 return r;
2551
2552 r = link_carrier_gained(link);
2553 if (r < 0)
2554 return r;
2555
2556 log_link_info(link, "Reset carrier");
2557 }
2558
2559 return 0;
2560 }
2561
2562
2563 int link_update(Link *link, sd_netlink_message *m) {
2564 struct ether_addr mac;
2565 const char *ifname;
2566 uint32_t mtu;
2567 bool had_carrier, carrier_gained, carrier_lost;
2568 int r;
2569
2570 assert(link);
2571 assert(link->ifname);
2572 assert(m);
2573
2574 if (link->state == LINK_STATE_LINGER) {
2575 link_ref(link);
2576 log_link_info(link, "Link readded");
2577 link_set_state(link, LINK_STATE_ENSLAVING);
2578
2579 r = link_new_carrier_maps(link);
2580 if (r < 0)
2581 return r;
2582 }
2583
2584 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
2585 if (r >= 0 && !streq(ifname, link->ifname)) {
2586 log_link_info(link, "Renamed to %s", ifname);
2587
2588 link_free_carrier_maps(link);
2589
2590 r = free_and_strdup(&link->ifname, ifname);
2591 if (r < 0)
2592 return r;
2593
2594 r = link_new_carrier_maps(link);
2595 if (r < 0)
2596 return r;
2597 }
2598
2599 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
2600 if (r >= 0 && mtu > 0) {
2601 link->mtu = mtu;
2602 if (!link->original_mtu) {
2603 link->original_mtu = mtu;
2604 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
2605 }
2606
2607 if (link->dhcp_client) {
2608 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2609 link->mtu);
2610 if (r < 0) {
2611 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
2612 return r;
2613 }
2614 }
2615 }
2616
2617 /* The kernel may broadcast NEWLINK messages without the MAC address
2618 set, simply ignore them. */
2619 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2620 if (r >= 0) {
2621 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2622 ETH_ALEN)) {
2623
2624 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2625 ETH_ALEN);
2626
2627 log_link_debug(link, "MAC address: "
2628 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2629 mac.ether_addr_octet[0],
2630 mac.ether_addr_octet[1],
2631 mac.ether_addr_octet[2],
2632 mac.ether_addr_octet[3],
2633 mac.ether_addr_octet[4],
2634 mac.ether_addr_octet[5]);
2635
2636 if (link->ipv4ll) {
2637 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2638 if (r < 0)
2639 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
2640 }
2641
2642 if (link->dhcp_client) {
2643 r = sd_dhcp_client_set_mac(link->dhcp_client,
2644 (const uint8_t *) &link->mac,
2645 sizeof (link->mac),
2646 ARPHRD_ETHER);
2647 if (r < 0)
2648 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
2649 }
2650
2651 if (link->dhcp6_client) {
2652 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2653 (const uint8_t *) &link->mac,
2654 sizeof (link->mac),
2655 ARPHRD_ETHER);
2656 if (r < 0)
2657 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
2658 }
2659 }
2660 }
2661
2662 had_carrier = link_has_carrier(link);
2663
2664 r = link_update_flags(link, m);
2665 if (r < 0)
2666 return r;
2667
2668 carrier_gained = !had_carrier && link_has_carrier(link);
2669 carrier_lost = had_carrier && !link_has_carrier(link);
2670
2671 if (carrier_gained) {
2672 log_link_info(link, "Gained carrier");
2673
2674 r = link_carrier_gained(link);
2675 if (r < 0)
2676 return r;
2677 } else if (carrier_lost) {
2678 log_link_info(link, "Lost carrier");
2679
2680 r = link_carrier_lost(link);
2681 if (r < 0)
2682 return r;
2683
2684 }
2685
2686 return 0;
2687 }
2688
2689 int link_save(Link *link) {
2690 _cleanup_free_ char *temp_path = NULL;
2691 _cleanup_fclose_ FILE *f = NULL;
2692 const char *admin_state, *oper_state;
2693 Address *a;
2694 Route *route;
2695 Iterator i;
2696 int r;
2697
2698 assert(link);
2699 assert(link->state_file);
2700 assert(link->lease_file);
2701 assert(link->manager);
2702
2703 if (link->state == LINK_STATE_LINGER) {
2704 unlink(link->state_file);
2705 return 0;
2706 }
2707
2708 admin_state = link_state_to_string(link->state);
2709 assert(admin_state);
2710
2711 oper_state = link_operstate_to_string(link->operstate);
2712 assert(oper_state);
2713
2714 r = fopen_temporary(link->state_file, &f, &temp_path);
2715 if (r < 0)
2716 goto fail;
2717
2718 fchmod(fileno(f), 0644);
2719
2720 fprintf(f,
2721 "# This is private data. Do not parse.\n"
2722 "ADMIN_STATE=%s\n"
2723 "OPER_STATE=%s\n",
2724 admin_state, oper_state);
2725
2726 if (link->network) {
2727 char **address, **domain;
2728 bool space;
2729 sd_dhcp6_lease *dhcp6_lease = NULL;
2730
2731 if (link->dhcp6_client) {
2732 r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
2733 if (r < 0 && r != -ENOMSG)
2734 log_link_debug(link, "No DHCPv6 lease");
2735 }
2736
2737 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2738
2739 fputs("DNS=", f);
2740 space = false;
2741 STRV_FOREACH(address, link->network->dns) {
2742 if (space)
2743 fputc(' ', f);
2744 fputs(*address, f);
2745 space = true;
2746 }
2747
2748 if (link->network->dhcp_dns &&
2749 link->dhcp_lease) {
2750 const struct in_addr *addresses;
2751
2752 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2753 if (r > 0) {
2754 if (space)
2755 fputc(' ', f);
2756 serialize_in_addrs(f, addresses, r);
2757 space = true;
2758 }
2759 }
2760
2761 if (link->network->dhcp_dns && dhcp6_lease) {
2762 struct in6_addr *in6_addrs;
2763
2764 r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
2765 if (r > 0) {
2766 if (space)
2767 fputc(' ', f);
2768 serialize_in6_addrs(f, in6_addrs, r);
2769 }
2770 }
2771
2772 fputc('\n', f);
2773
2774 fputs("NTP=", f);
2775 space = false;
2776 STRV_FOREACH(address, link->network->ntp) {
2777 if (space)
2778 fputc(' ', f);
2779 fputs(*address, f);
2780 space = true;
2781 }
2782
2783 if (link->network->dhcp_ntp &&
2784 link->dhcp_lease) {
2785 const struct in_addr *addresses;
2786
2787 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2788 if (r > 0) {
2789 if (space)
2790 fputc(' ', f);
2791 serialize_in_addrs(f, addresses, r);
2792 space = true;
2793 }
2794 }
2795
2796 if (link->network->dhcp_ntp && dhcp6_lease) {
2797 struct in6_addr *in6_addrs;
2798 char **hosts;
2799 char **hostname;
2800
2801 r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
2802 &in6_addrs);
2803 if (r > 0) {
2804 if (space)
2805 fputc(' ', f);
2806 serialize_in6_addrs(f, in6_addrs, r);
2807 space = true;
2808 }
2809
2810 r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
2811 if (r > 0) {
2812 STRV_FOREACH(hostname, hosts) {
2813 if (space)
2814 fputc(' ', f);
2815 fputs(*hostname, f);
2816 space = true;
2817 }
2818 }
2819 }
2820
2821 fputc('\n', f);
2822
2823 fputs("DOMAINS=", f);
2824 space = false;
2825 STRV_FOREACH(domain, link->network->domains) {
2826 if (space)
2827 fputc(' ', f);
2828 fputs(*domain, f);
2829 space = true;
2830 }
2831
2832 if (link->network->dhcp_domains &&
2833 link->dhcp_lease) {
2834 const char *domainname;
2835
2836 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
2837 if (r >= 0) {
2838 if (space)
2839 fputc(' ', f);
2840 fputs(domainname, f);
2841 space = true;
2842 }
2843 }
2844
2845 if (link->network->dhcp_domains && dhcp6_lease) {
2846 char **domains;
2847
2848 r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
2849 if (r >= 0) {
2850 STRV_FOREACH(domain, domains) {
2851 if (space)
2852 fputc(' ', f);
2853 fputs(*domain, f);
2854 space = true;
2855 }
2856 }
2857 }
2858
2859 fputc('\n', f);
2860
2861 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2862 yes_no(link->network->wildcard_domain));
2863
2864 fprintf(f, "LLMNR=%s\n",
2865 resolve_support_to_string(link->network->llmnr));
2866
2867 fputs("ADDRESSES=", f);
2868 space = false;
2869 SET_FOREACH(a, link->addresses, i) {
2870 _cleanup_free_ char *address_str = NULL;
2871
2872 r = in_addr_to_string(a->family, &a->in_addr, &address_str);
2873 if (r < 0)
2874 goto fail;
2875
2876 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
2877 space = true;
2878 }
2879
2880 fputc('\n', f);
2881
2882 fputs("ROUTES=", f);
2883 space = false;
2884 SET_FOREACH(route, link->routes, i) {
2885 _cleanup_free_ char *route_str = NULL;
2886
2887 r = in_addr_to_string(route->family, &route->dst, &route_str);
2888 if (r < 0)
2889 goto fail;
2890
2891 fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
2892 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
2893 space = true;
2894 }
2895
2896 fputc('\n', f);
2897 }
2898
2899 if (!hashmap_isempty(link->bound_to_links)) {
2900 Link *carrier;
2901 bool space = false;
2902
2903 fputs("CARRIER_BOUND_TO=", f);
2904 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2905 if (space)
2906 fputc(' ', f);
2907 fputs(carrier->ifname, f);
2908 space = true;
2909 }
2910
2911 fputc('\n', f);
2912 }
2913
2914 if (!hashmap_isempty(link->bound_by_links)) {
2915 Link *carrier;
2916 bool space = false;
2917
2918 fputs("CARRIER_BOUND_BY=", f);
2919 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2920 if (space)
2921 fputc(' ', f);
2922 fputs(carrier->ifname, f);
2923 space = true;
2924 }
2925
2926 fputc('\n', f);
2927 }
2928
2929 if (link->dhcp_lease) {
2930 struct in_addr address;
2931 const char *tz = NULL;
2932
2933 assert(link->network);
2934
2935 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
2936 if (r >= 0)
2937 fprintf(f, "TIMEZONE=%s\n", tz);
2938
2939 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
2940 if (r >= 0) {
2941 fputs("DHCP4_ADDRESS=", f);
2942 serialize_in_addrs(f, &address, 1);
2943 fputc('\n', f);
2944 }
2945
2946 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2947 if (r < 0)
2948 goto fail;
2949
2950 fprintf(f,
2951 "DHCP_LEASE=%s\n",
2952 link->lease_file);
2953 } else
2954 unlink(link->lease_file);
2955
2956 if (link->ipv4ll) {
2957 struct in_addr address;
2958
2959 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
2960 if (r >= 0) {
2961 fputs("IPV4LL_ADDRESS=", f);
2962 serialize_in_addrs(f, &address, 1);
2963 fputc('\n', f);
2964 }
2965 }
2966
2967 if (link->lldp) {
2968 assert(link->network);
2969
2970 r = sd_lldp_save(link->lldp, link->lldp_file);
2971 if (r < 0)
2972 goto fail;
2973
2974 fprintf(f,
2975 "LLDP_FILE=%s\n",
2976 link->lldp_file);
2977 } else
2978 unlink(link->lldp_file);
2979
2980 r = fflush_and_check(f);
2981 if (r < 0)
2982 goto fail;
2983
2984 if (rename(temp_path, link->state_file) < 0) {
2985 r = -errno;
2986 goto fail;
2987 }
2988
2989 return 0;
2990
2991 fail:
2992 (void) unlink(link->state_file);
2993 if (temp_path)
2994 (void) unlink(temp_path);
2995
2996 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
2997 }
2998
2999 /* The serialized state in /run is no longer up-to-date. */
3000 void link_dirty(Link *link) {
3001 int r;
3002
3003 assert(link);
3004
3005 r = set_ensure_allocated(&link->manager->dirty_links, NULL);
3006 if (r < 0)
3007 /* allocation errors are ignored */
3008 return;
3009
3010 r = set_put(link->manager->dirty_links, link);
3011 if (r < 0)
3012 /* allocation errors are ignored */
3013 return;
3014
3015 link_ref(link);
3016 }
3017
3018 /* The serialized state in /run is up-to-date */
3019 void link_clean(Link *link) {
3020 assert(link);
3021 assert(link->manager);
3022
3023 set_remove(link->manager->dirty_links, link);
3024 link_unref(link);
3025 }
3026
3027 static const char* const link_state_table[_LINK_STATE_MAX] = {
3028 [LINK_STATE_PENDING] = "pending",
3029 [LINK_STATE_ENSLAVING] = "configuring",
3030 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
3031 [LINK_STATE_SETTING_ROUTES] = "configuring",
3032 [LINK_STATE_CONFIGURED] = "configured",
3033 [LINK_STATE_UNMANAGED] = "unmanaged",
3034 [LINK_STATE_FAILED] = "failed",
3035 [LINK_STATE_LINGER] = "linger",
3036 };
3037
3038 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
3039
3040 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
3041 [LINK_OPERSTATE_OFF] = "off",
3042 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
3043 [LINK_OPERSTATE_DORMANT] = "dormant",
3044 [LINK_OPERSTATE_CARRIER] = "carrier",
3045 [LINK_OPERSTATE_DEGRADED] = "degraded",
3046 [LINK_OPERSTATE_ROUTABLE] = "routable",
3047 };
3048
3049 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);