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