]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/network/networkd-link.c
tree-wide: port everything over to fflush_and_check()
[thirdparty/systemd.git] / src / network / networkd-link.c
... / ...
CommitLineData
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 "util.h"
27#include "virt.h"
28#include "fileio.h"
29#include "socket-util.h"
30#include "bus-util.h"
31#include "udev-util.h"
32#include "network-internal.h"
33#include "networkd-link.h"
34#include "networkd-netdev.h"
35
36bool link_dhcp6_enabled(Link *link) {
37 if (link->flags & IFF_LOOPBACK)
38 return false;
39
40 if (!link->network)
41 return false;
42
43 return link->network->dhcp & ADDRESS_FAMILY_IPV6;
44}
45
46bool link_dhcp4_enabled(Link *link) {
47 if (link->flags & IFF_LOOPBACK)
48 return false;
49
50 if (!link->network)
51 return false;
52
53 return link->network->dhcp & ADDRESS_FAMILY_IPV4;
54}
55
56bool link_dhcp4_server_enabled(Link *link) {
57 if (link->flags & IFF_LOOPBACK)
58 return false;
59
60 if (!link->network)
61 return false;
62
63 return link->network->dhcp_server;
64}
65
66bool link_ipv4ll_enabled(Link *link) {
67 if (link->flags & IFF_LOOPBACK)
68 return false;
69
70 if (!link->network)
71 return false;
72
73 return link->network->link_local & ADDRESS_FAMILY_IPV4;
74}
75
76bool link_ipv6ll_enabled(Link *link) {
77 if (link->flags & IFF_LOOPBACK)
78 return false;
79
80 if (!link->network)
81 return false;
82
83 return link->network->link_local & ADDRESS_FAMILY_IPV6;
84}
85
86bool link_lldp_enabled(Link *link) {
87 if (link->flags & IFF_LOOPBACK)
88 return false;
89
90 if (!link->network)
91 return false;
92
93 if (link->network->bridge)
94 return false;
95
96 return link->network->lldp;
97}
98
99static bool link_ipv4_forward_enabled(Link *link) {
100 if (link->flags & IFF_LOOPBACK)
101 return false;
102
103 if (!link->network)
104 return false;
105
106 return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
107}
108
109static bool link_ipv6_forward_enabled(Link *link) {
110 if (link->flags & IFF_LOOPBACK)
111 return false;
112
113 if (!link->network)
114 return false;
115
116 return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
117}
118
119static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
120 if (link->flags & IFF_LOOPBACK)
121 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
122
123 if (!link->network)
124 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
125
126 return link->network->ipv6_privacy_extensions;
127}
128
129#define FLAG_STRING(string, flag, old, new) \
130 (((old ^ new) & flag) \
131 ? ((old & flag) ? (" -" string) : (" +" string)) \
132 : "")
133
134static int link_update_flags(Link *link, sd_netlink_message *m) {
135 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
136 uint8_t operstate;
137 int r;
138
139 assert(link);
140
141 r = sd_rtnl_message_link_get_flags(m, &flags);
142 if (r < 0)
143 return log_link_warning_errno(link, r, "Could not get link flags: %m");
144
145 r = sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &operstate);
146 if (r < 0)
147 /* if we got a message without operstate, take it to mean
148 the state was unchanged */
149 operstate = link->kernel_operstate;
150
151 if ((link->flags == flags) && (link->kernel_operstate == operstate))
152 return 0;
153
154 if (link->flags != flags) {
155 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",
156 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
157 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
158 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
159 FLAG_STRING("UP", IFF_UP, link->flags, flags),
160 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
161 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
162 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
163 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
164 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
165 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
166 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
167 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
168 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
169 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
170 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
171 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
172 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
173 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
174 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
175
176 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
177 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
178 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
179 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
180 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
181 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
182 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
183 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
184
185 /* link flags are currently at most 18 bits, let's align to
186 * printing 20 */
187 if (unknown_flags_added)
188 log_link_debug(link,
189 "Unknown link flags gained: %#.5x (ignoring)",
190 unknown_flags_added);
191
192 if (unknown_flags_removed)
193 log_link_debug(link,
194 "Unknown link flags lost: %#.5x (ignoring)",
195 unknown_flags_removed);
196 }
197
198 link->flags = flags;
199 link->kernel_operstate = operstate;
200
201 link_save(link);
202
203 return 0;
204}
205
206static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
207 _cleanup_link_unref_ Link *link = NULL;
208 uint16_t type;
209 const char *ifname;
210 int r, ifindex;
211
212 assert(manager);
213 assert(message);
214 assert(ret);
215
216 r = sd_netlink_message_get_type(message, &type);
217 if (r < 0)
218 return r;
219 else if (type != RTM_NEWLINK)
220 return -EINVAL;
221
222 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
223 if (r < 0)
224 return r;
225 else if (ifindex <= 0)
226 return -EINVAL;
227
228 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
229 if (r < 0)
230 return r;
231
232 link = new0(Link, 1);
233 if (!link)
234 return -ENOMEM;
235
236 link->n_ref = 1;
237 link->manager = manager;
238 link->state = LINK_STATE_PENDING;
239 link->rtnl_extended_attrs = true;
240 link->ifindex = ifindex;
241 link->ifname = strdup(ifname);
242 if (!link->ifname)
243 return -ENOMEM;
244
245 r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
246 if (r < 0)
247 log_link_debug(link, "MAC address not found for new device, continuing without");
248
249 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
250 link->ifindex);
251 if (r < 0)
252 return -ENOMEM;
253
254 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
255 link->ifindex);
256 if (r < 0)
257 return -ENOMEM;
258
259 r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
260 link->ifindex);
261 if (r < 0)
262 return -ENOMEM;
263
264
265 r = hashmap_ensure_allocated(&manager->links, NULL);
266 if (r < 0)
267 return r;
268
269 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
270 if (r < 0)
271 return r;
272
273 r = link_update_flags(link, message);
274 if (r < 0)
275 return r;
276
277 *ret = link;
278 link = NULL;
279
280 return 0;
281}
282
283static void link_free(Link *link) {
284 Address *address;
285 Iterator i;
286 Link *carrier;
287
288 if (!link)
289 return;
290
291 while ((address = link->addresses)) {
292 LIST_REMOVE(addresses, link->addresses, address);
293 address_free(address);
294 }
295
296 while ((address = link->pool_addresses)) {
297 LIST_REMOVE(addresses, link->pool_addresses, address);
298 address_free(address);
299 }
300
301 sd_dhcp_server_unref(link->dhcp_server);
302 sd_dhcp_client_unref(link->dhcp_client);
303 sd_dhcp_lease_unref(link->dhcp_lease);
304
305 free(link->lease_file);
306
307 sd_lldp_free(link->lldp);
308
309 free(link->lldp_file);
310
311 sd_ipv4ll_unref(link->ipv4ll);
312 sd_dhcp6_client_unref(link->dhcp6_client);
313 sd_icmp6_nd_unref(link->icmp6_router_discovery);
314
315 if (link->manager)
316 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
317
318 free(link->ifname);
319
320 free(link->state_file);
321
322 udev_device_unref(link->udev_device);
323
324 HASHMAP_FOREACH (carrier, link->bound_to_links, i)
325 hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex));
326 hashmap_free(link->bound_to_links);
327
328 HASHMAP_FOREACH (carrier, link->bound_by_links, i)
329 hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
330 hashmap_free(link->bound_by_links);
331
332 free(link);
333}
334
335Link *link_unref(Link *link) {
336 if (link && (-- link->n_ref <= 0))
337 link_free(link);
338
339 return NULL;
340}
341
342Link *link_ref(Link *link) {
343 if (link)
344 assert_se(++ link->n_ref >= 2);
345
346 return link;
347}
348
349int link_get(Manager *m, int ifindex, Link **ret) {
350 Link *link;
351
352 assert(m);
353 assert(ifindex);
354 assert(ret);
355
356 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
357 if (!link)
358 return -ENODEV;
359
360 *ret = link;
361
362 return 0;
363}
364
365static void link_set_state(Link *link, LinkState state) {
366 assert(link);
367
368 if (link->state == state)
369 return;
370
371 link->state = state;
372
373 link_send_changed(link, "AdministrativeState", NULL);
374
375 return;
376}
377
378static void link_enter_unmanaged(Link *link) {
379 assert(link);
380
381 log_link_debug(link, "Unmanaged");
382
383 link_set_state(link, LINK_STATE_UNMANAGED);
384
385 link_save(link);
386}
387
388static int link_stop_clients(Link *link) {
389 int r = 0, k;
390
391 assert(link);
392 assert(link->manager);
393 assert(link->manager->event);
394
395 if (!link->network)
396 return 0;
397
398 if (link->dhcp_client) {
399 k = sd_dhcp_client_stop(link->dhcp_client);
400 if (k < 0)
401 r = log_link_warning_errno(link, r, "Could not stop DHCPv4 client: %m");
402 }
403
404 if (link->ipv4ll) {
405 k = sd_ipv4ll_stop(link->ipv4ll);
406 if (k < 0)
407 r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m");
408 }
409
410 if(link->icmp6_router_discovery) {
411 if (link->dhcp6_client) {
412 k = sd_dhcp6_client_stop(link->dhcp6_client);
413 if (k < 0)
414 r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m");
415 }
416
417 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
418 if (k < 0)
419 r = log_link_warning_errno(link, r, "Could not stop ICMPv6 router discovery: %m");
420 }
421
422 if (link->lldp) {
423 k = sd_lldp_stop(link->lldp);
424 if (k < 0)
425 r = log_link_warning_errno(link, r, "Could not stop LLDP: %m");
426 }
427
428 return r;
429}
430
431void link_enter_failed(Link *link) {
432 assert(link);
433
434 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
435 return;
436
437 log_link_warning(link, "Failed");
438
439 link_set_state(link, LINK_STATE_FAILED);
440
441 link_stop_clients(link);
442
443 link_save(link);
444}
445
446static Address* link_find_dhcp_server_address(Link *link) {
447 Address *address;
448
449 assert(link);
450 assert(link->network);
451
452 /* The first statically configured address if there is any */
453 LIST_FOREACH(addresses, address, link->network->static_addresses) {
454
455 if (address->family != AF_INET)
456 continue;
457
458 if (in_addr_is_null(address->family, &address->in_addr))
459 continue;
460
461 return address;
462 }
463
464 /* If that didn't work, find a suitable address we got from the pool */
465 LIST_FOREACH(addresses, address, link->pool_addresses) {
466 if (address->family != AF_INET)
467 continue;
468
469 return address;
470 }
471
472 return NULL;
473}
474
475static int link_enter_configured(Link *link) {
476 assert(link);
477 assert(link->network);
478 assert(link->state == LINK_STATE_SETTING_ROUTES);
479
480 log_link_info(link, "Configured");
481
482 link_set_state(link, LINK_STATE_CONFIGURED);
483
484 link_save(link);
485
486 return 0;
487}
488
489void link_client_handler(Link *link) {
490 assert(link);
491 assert(link->network);
492
493 if (!link->static_configured)
494 return;
495
496 if (link_ipv4ll_enabled(link))
497 if (!link->ipv4ll_address ||
498 !link->ipv4ll_route)
499 return;
500
501 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
502 return;
503
504 if (link->state != LINK_STATE_CONFIGURED)
505 link_enter_configured(link);
506
507 return;
508}
509
510static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
511 _cleanup_link_unref_ Link *link = userdata;
512 int r;
513
514 assert(link->link_messages > 0);
515 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
516 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
517 LINK_STATE_LINGER));
518
519 link->link_messages --;
520
521 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
522 return 1;
523
524 r = sd_netlink_message_get_errno(m);
525 if (r < 0 && r != -EEXIST)
526 log_link_warning_errno(link, r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
527
528 if (link->link_messages == 0) {
529 log_link_debug(link, "Routes set");
530 link->static_configured = true;
531 link_client_handler(link);
532 }
533
534 return 1;
535}
536
537static int link_enter_set_routes(Link *link) {
538 Route *rt;
539 int r;
540
541 assert(link);
542 assert(link->network);
543 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
544
545 link_set_state(link, LINK_STATE_SETTING_ROUTES);
546
547 LIST_FOREACH(routes, rt, link->network->static_routes) {
548 r = route_configure(rt, link, &route_handler);
549 if (r < 0) {
550 log_link_warning_errno(link, r, "Could not set routes: %m");
551 link_enter_failed(link);
552 return r;
553 }
554
555 link->link_messages ++;
556 }
557
558 if (link->link_messages == 0) {
559 link->static_configured = true;
560 link_client_handler(link);
561 } else
562 log_link_debug(link, "Setting routes");
563
564 return 0;
565}
566
567int link_route_drop_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
568 _cleanup_link_unref_ Link *link = userdata;
569 int r;
570
571 assert(m);
572 assert(link);
573 assert(link->ifname);
574
575 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
576 return 1;
577
578 r = sd_netlink_message_get_errno(m);
579 if (r < 0 && r != -ESRCH)
580 log_link_warning_errno(link, r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
581
582 return 1;
583}
584
585static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
586 _cleanup_link_unref_ Link *link = userdata;
587 int r;
588
589 assert(rtnl);
590 assert(m);
591 assert(link);
592 assert(link->ifname);
593 assert(link->link_messages > 0);
594 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
595 LINK_STATE_FAILED, LINK_STATE_LINGER));
596
597 link->link_messages --;
598
599 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
600 return 1;
601
602 r = sd_netlink_message_get_errno(m);
603 if (r < 0 && r != -EEXIST)
604 log_link_warning_errno(link, r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
605 else if (r >= 0)
606 link_rtnl_process_address(rtnl, m, link->manager);
607
608 if (link->link_messages == 0) {
609 log_link_debug(link, "Addresses set");
610 link_enter_set_routes(link);
611 }
612
613 return 1;
614}
615
616static int link_enter_set_addresses(Link *link) {
617 Address *ad;
618 int r;
619
620 assert(link);
621 assert(link->network);
622 assert(link->state != _LINK_STATE_INVALID);
623
624 link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
625
626 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
627 r = address_configure(ad, link, &address_handler);
628 if (r < 0) {
629 log_link_warning_errno(link, r, "Could not set addresses: %m");
630 link_enter_failed(link);
631 return r;
632 }
633
634 link->link_messages ++;
635 }
636
637 /* now that we can figure out a default address for the dhcp server,
638 start it */
639 if (link_dhcp4_server_enabled(link)) {
640 struct in_addr pool_start;
641 Address *address;
642
643 address = link_find_dhcp_server_address(link);
644 if (!address) {
645 log_link_warning(link, "Failed to find suitable address for DHCPv4 server instance.");
646 link_enter_failed(link);
647 return 0;
648 }
649
650 r = sd_dhcp_server_set_address(link->dhcp_server,
651 &address->in_addr.in,
652 address->prefixlen);
653 if (r < 0)
654 return r;
655
656 /* offer 32 addresses starting from the address following the server address */
657 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
658 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
659 &pool_start, 32);
660 if (r < 0)
661 return r;
662
663 /* TODO:
664 r = sd_dhcp_server_set_router(link->dhcp_server,
665 &main_address->in_addr.in);
666 if (r < 0)
667 return r;
668
669 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
670 main_address->prefixlen);
671 if (r < 0)
672 return r;
673 */
674
675 r = sd_dhcp_server_start(link->dhcp_server);
676 if (r < 0) {
677 log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
678
679 link_enter_failed(link);
680
681 return 0;
682 }
683
684 log_link_debug(link, "Offering DHCPv4 leases");
685 }
686
687 if (link->link_messages == 0)
688 link_enter_set_routes(link);
689 else
690 log_link_debug(link, "Setting addresses");
691
692 return 0;
693}
694
695int link_address_drop_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
696 _cleanup_link_unref_ Link *link = userdata;
697 int r;
698
699 assert(m);
700 assert(link);
701 assert(link->ifname);
702
703 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
704 return 1;
705
706 r = sd_netlink_message_get_errno(m);
707 if (r < 0 && r != -EADDRNOTAVAIL)
708 log_link_warning_errno(link, r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
709
710 return 1;
711}
712
713static int link_set_bridge_fdb(Link *const link) {
714 FdbEntry *fdb_entry;
715 int r = 0;
716
717 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
718 r = fdb_entry_configure(link, fdb_entry);
719 if(r < 0) {
720 log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
721 break;
722 }
723 }
724
725 return r;
726}
727
728static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
729 _cleanup_link_unref_ Link *link = userdata;
730 int r;
731
732 log_link_debug(link, "Set link");
733
734 r = sd_netlink_message_get_errno(m);
735 if (r < 0 && r != -EEXIST) {
736 log_link_error_errno(link, r, "Could not join netdev: %m");
737 link_enter_failed(link);
738 return 1;
739 }
740
741 return 0;
742}
743
744static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
745 _cleanup_link_unref_ Link *link = userdata;
746 int r;
747
748 assert(m);
749 assert(link);
750
751 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
752 return 1;
753
754 r = sd_bus_message_get_errno(m);
755 if (r > 0)
756 log_link_warning_errno(link, r, "Could not set hostname: %m");
757
758 return 1;
759}
760
761int link_set_hostname(Link *link, const char *hostname) {
762 int r = 0;
763
764 assert(link);
765 assert(link->manager);
766 assert(hostname);
767
768 log_link_debug(link, "Setting transient hostname: '%s'", hostname);
769
770 if (!link->manager->bus) {
771 /* TODO: replace by assert when we can rely on kdbus */
772 log_link_info(link, "Not connected to system bus, ignoring transient hostname.");
773 return 0;
774 }
775
776 r = sd_bus_call_method_async(
777 link->manager->bus,
778 NULL,
779 "org.freedesktop.hostname1",
780 "/org/freedesktop/hostname1",
781 "org.freedesktop.hostname1",
782 "SetHostname",
783 set_hostname_handler,
784 link,
785 "sb",
786 hostname,
787 false);
788
789 if (r < 0)
790 return log_link_error_errno(link, r, "Could not set transient hostname: %m");
791
792 link_ref(link);
793
794 return 0;
795}
796
797static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
798 _cleanup_link_unref_ Link *link = userdata;
799 int r;
800
801 assert(m);
802 assert(link);
803 assert(link->ifname);
804
805 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
806 return 1;
807
808 r = sd_netlink_message_get_errno(m);
809 if (r < 0)
810 log_link_warning_errno(link, r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
811
812 return 1;
813}
814
815int link_set_mtu(Link *link, uint32_t mtu) {
816 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
817 int r;
818
819 assert(link);
820 assert(link->manager);
821 assert(link->manager->rtnl);
822
823 log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
824
825 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
826 if (r < 0)
827 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
828
829 r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
830 if (r < 0)
831 return log_link_error_errno(link, r, "Could not append MTU: %m");
832
833 r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
834 if (r < 0)
835 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
836
837 link_ref(link);
838
839 return 0;
840}
841
842static int link_set_bridge(Link *link) {
843 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
844 int r;
845
846 assert(link);
847 assert(link->network);
848
849 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
850 if (r < 0)
851 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
852
853 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
854 if (r < 0)
855 return log_link_error_errno(link, r, "Could not set message family: %m");
856
857 r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
858 if (r < 0)
859 return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
860
861 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, !link->network->use_bpdu);
862 if (r < 0)
863 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
864
865 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
866 if (r < 0)
867 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
868
869 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
870 if (r < 0)
871 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
872
873 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, !link->network->allow_port_to_be_root);
874 if (r < 0)
875 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
876
877 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
878 if (r < 0)
879 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
880
881 if(link->network->cost != 0) {
882 r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
883 if (r < 0)
884 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
885 }
886
887 r = sd_netlink_message_close_container(req);
888 if (r < 0)
889 return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
890
891 r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
892 if (r < 0)
893 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
894
895 link_ref(link);
896
897 return r;
898}
899
900static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
901 Link *link = userdata;
902 int r;
903
904 assert(link);
905 assert(link->network);
906 assert(link->manager);
907
908 if (event != UPDATE_INFO)
909 return;
910
911 r = sd_lldp_save(link->lldp, link->lldp_file);
912 if (r < 0)
913 log_link_warning_errno(link, r, "Could not save LLDP: %m");
914
915}
916
917static int link_acquire_conf(Link *link) {
918 int r;
919
920 assert(link);
921 assert(link->network);
922 assert(link->manager);
923 assert(link->manager->event);
924
925 if (link_ipv4ll_enabled(link)) {
926 assert(link->ipv4ll);
927
928 log_link_debug(link, "Acquiring IPv4 link-local address");
929
930 r = sd_ipv4ll_start(link->ipv4ll);
931 if (r < 0)
932 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
933 }
934
935 if (link_dhcp4_enabled(link)) {
936 assert(link->dhcp_client);
937
938 log_link_debug(link, "Acquiring DHCPv4 lease");
939
940 r = sd_dhcp_client_start(link->dhcp_client);
941 if (r < 0)
942 return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
943 }
944
945 if (link_dhcp6_enabled(link)) {
946 assert(link->icmp6_router_discovery);
947
948 log_link_debug(link, "Discovering IPv6 routers");
949
950 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
951 if (r < 0)
952 return log_link_warning_errno(link, r, "Could not start IPv6 router discovery: %m");
953 }
954
955 if (link_lldp_enabled(link)) {
956 assert(link->lldp);
957
958 log_link_debug(link, "Starting LLDP");
959
960 r = sd_lldp_start(link->lldp);
961 if (r < 0)
962 return log_link_warning_errno(link, r, "Could not start LLDP: %m");
963 }
964
965 return 0;
966}
967
968bool link_has_carrier(Link *link) {
969 /* see Documentation/networking/operstates.txt in the kernel sources */
970
971 if (link->kernel_operstate == IF_OPER_UP)
972 return true;
973
974 if (link->kernel_operstate == IF_OPER_UNKNOWN)
975 /* operstate may not be implemented, so fall back to flags */
976 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
977 return true;
978
979 return false;
980}
981
982static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
983 _cleanup_link_unref_ Link *link = userdata;
984 int r;
985
986 assert(link);
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)
993 /* we warn but don't fail the link, as it may be
994 brought up later */
995 log_link_warning_errno(link, r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
996
997 return 1;
998}
999
1000static int link_up(Link *link) {
1001 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
1002 uint8_t ipv6ll_mode;
1003 int r;
1004
1005 assert(link);
1006 assert(link->network);
1007 assert(link->manager);
1008 assert(link->manager->rtnl);
1009
1010 log_link_debug(link, "Bringing link up");
1011
1012 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1013 if (r < 0)
1014 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1015
1016 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1017 if (r < 0)
1018 return log_link_error_errno(link, r, "Could not set link flags: %m");
1019
1020 if (link->network->mac) {
1021 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1022 if (r < 0)
1023 return log_link_error_errno(link, r, "Could not set MAC address: %m");
1024 }
1025
1026 if (link->network->mtu) {
1027 r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
1028 if (r < 0)
1029 return log_link_error_errno(link, r, "Could not set MTU: %m");
1030 }
1031
1032 r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
1033 if (r < 0)
1034 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
1035
1036 if (socket_ipv6_is_supported()) {
1037 /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
1038 r = sd_netlink_message_open_container(req, AF_INET6);
1039 if (r < 0)
1040 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
1041
1042 ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
1043 r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
1044 if (r < 0)
1045 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
1046
1047 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1048 r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
1049 if (r < 0)
1050 return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
1051 }
1052
1053 r = sd_netlink_message_close_container(req);
1054 if (r < 0)
1055 return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
1056 }
1057
1058 r = sd_netlink_message_close_container(req);
1059 if (r < 0)
1060 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
1061
1062 r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1063 if (r < 0)
1064 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1065
1066 link_ref(link);
1067
1068 return 0;
1069}
1070
1071static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1072 _cleanup_link_unref_ Link *link = userdata;
1073 int r;
1074
1075 assert(link);
1076
1077 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1078 return 1;
1079
1080 r = sd_netlink_message_get_errno(m);
1081 if (r < 0)
1082 log_link_warning_errno(link, r, "%-*s: could not bring down interface: %m", IFNAMSIZ, link->ifname);
1083
1084 return 1;
1085}
1086
1087static int link_down(Link *link) {
1088 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
1089 int r;
1090
1091 assert(link);
1092 assert(link->manager);
1093 assert(link->manager->rtnl);
1094
1095 log_link_debug(link, "Bringing link down");
1096
1097 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1098 RTM_SETLINK, link->ifindex);
1099 if (r < 0)
1100 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
1101
1102 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
1103 if (r < 0)
1104 return log_link_error_errno(link, r, "Could not set link flags: %m");
1105
1106 r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
1107 if (r < 0)
1108 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
1109
1110 link_ref(link);
1111
1112 return 0;
1113}
1114
1115static int link_handle_bound_to_list(Link *link) {
1116 Link *l;
1117 Iterator i;
1118 int r;
1119 bool required_up = false;
1120 bool link_is_up = false;
1121
1122 assert(link);
1123
1124 if (hashmap_isempty(link->bound_to_links))
1125 return 0;
1126
1127 if (link->flags & IFF_UP)
1128 link_is_up = true;
1129
1130 HASHMAP_FOREACH (l, link->bound_to_links, i)
1131 if (link_has_carrier(l)) {
1132 required_up = true;
1133 break;
1134 }
1135
1136 if (!required_up && link_is_up) {
1137 r = link_down(link);
1138 if (r < 0)
1139 return r;
1140 } else if (required_up && !link_is_up) {
1141 r = link_up(link);
1142 if (r < 0)
1143 return r;
1144 }
1145
1146 return 0;
1147}
1148
1149static int link_handle_bound_by_list(Link *link) {
1150 Iterator i;
1151 Link *l;
1152 int r;
1153
1154 assert(link);
1155
1156 if (hashmap_isempty(link->bound_by_links))
1157 return 0;
1158
1159 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1160 r = link_handle_bound_to_list(l);
1161 if (r < 0)
1162 return r;
1163 }
1164
1165 return 0;
1166}
1167
1168static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1169 int r;
1170
1171 assert(link);
1172 assert(carrier);
1173
1174 if (link == carrier)
1175 return 0;
1176
1177 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1178 return 0;
1179
1180 r = hashmap_ensure_allocated(h, NULL);
1181 if (r < 0)
1182 return r;
1183
1184 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1185 if (r < 0)
1186 return r;
1187
1188 return 0;
1189}
1190
1191static int link_new_bound_by_list(Link *link) {
1192 Manager *m;
1193 Link *carrier;
1194 Iterator i;
1195 int r;
1196 bool list_updated = false;
1197
1198 assert(link);
1199 assert(link->manager);
1200
1201 m = link->manager;
1202
1203 HASHMAP_FOREACH (carrier, m->links, i) {
1204 if (!carrier->network)
1205 continue;
1206
1207 if (strv_isempty(carrier->network->bind_carrier))
1208 continue;
1209
1210 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1211 r = link_put_carrier(link, carrier, &link->bound_by_links);
1212 if (r < 0)
1213 return r;
1214
1215 list_updated = true;
1216 }
1217 }
1218
1219 if (list_updated)
1220 link_save(link);
1221
1222 HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
1223 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1224 if (r < 0)
1225 return r;
1226
1227 link_save(carrier);
1228 }
1229
1230 return 0;
1231}
1232
1233static int link_new_bound_to_list(Link *link) {
1234 Manager *m;
1235 Link *carrier;
1236 Iterator i;
1237 int r;
1238 bool list_updated = false;
1239
1240 assert(link);
1241 assert(link->manager);
1242
1243 if (!link->network)
1244 return 0;
1245
1246 if (strv_isempty(link->network->bind_carrier))
1247 return 0;
1248
1249 m = link->manager;
1250
1251 HASHMAP_FOREACH (carrier, m->links, i) {
1252 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1253 r = link_put_carrier(link, carrier, &link->bound_to_links);
1254 if (r < 0)
1255 return r;
1256
1257 list_updated = true;
1258 }
1259 }
1260
1261 if (list_updated)
1262 link_save(link);
1263
1264 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1265 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1266 if (r < 0)
1267 return r;
1268
1269 link_save(carrier);
1270 }
1271
1272 return 0;
1273}
1274
1275static int link_new_carrier_maps(Link *link) {
1276 int r;
1277
1278 r = link_new_bound_by_list(link);
1279 if (r < 0)
1280 return r;
1281
1282 r = link_handle_bound_by_list(link);
1283 if (r < 0)
1284 return r;
1285
1286 r = link_new_bound_to_list(link);
1287 if (r < 0)
1288 return r;
1289
1290 r = link_handle_bound_to_list(link);
1291 if (r < 0)
1292 return r;
1293
1294 return 0;
1295}
1296
1297static void link_free_bound_to_list(Link *link) {
1298 Link *bound_to;
1299 Iterator i;
1300
1301 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1302 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1303
1304 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
1305 link_save(bound_to);
1306 }
1307
1308 return;
1309}
1310
1311static void link_free_bound_by_list(Link *link) {
1312 Link *bound_by;
1313 Iterator i;
1314
1315 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1316 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1317
1318 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
1319 link_save(bound_by);
1320 link_handle_bound_to_list(bound_by);
1321 }
1322 }
1323
1324 return;
1325}
1326
1327static void link_free_carrier_maps(Link *link) {
1328 bool list_updated = false;
1329
1330 assert(link);
1331
1332 if (!hashmap_isempty(link->bound_to_links)) {
1333 link_free_bound_to_list(link);
1334 list_updated = true;
1335 }
1336
1337 if (!hashmap_isempty(link->bound_by_links)) {
1338 link_free_bound_by_list(link);
1339 list_updated = true;
1340 }
1341
1342 if (list_updated)
1343 link_save(link);
1344
1345 return;
1346}
1347
1348void link_drop(Link *link) {
1349 if (!link || link->state == LINK_STATE_LINGER)
1350 return;
1351
1352 link_set_state(link, LINK_STATE_LINGER);
1353
1354 link_free_carrier_maps(link);
1355
1356 log_link_debug(link, "Link removed");
1357
1358 link_unref(link);
1359
1360 return;
1361}
1362
1363static int link_joined(Link *link) {
1364 int r;
1365
1366 assert(link);
1367 assert(link->network);
1368
1369 if (!hashmap_isempty(link->bound_to_links)) {
1370 r = link_handle_bound_to_list(link);
1371 if (r < 0)
1372 return r;
1373 } else if (!(link->flags & IFF_UP)) {
1374 r = link_up(link);
1375 if (r < 0) {
1376 link_enter_failed(link);
1377 return r;
1378 }
1379 }
1380
1381 if(link->network->bridge) {
1382 r = link_set_bridge(link);
1383 if (r < 0)
1384 log_link_error_errno(link, r, "Could not set bridge message: %m");
1385 }
1386
1387 return link_enter_set_addresses(link);
1388}
1389
1390static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1391 _cleanup_link_unref_ Link *link = userdata;
1392 int r;
1393
1394 assert(link);
1395 assert(link->network);
1396
1397 link->enslaving --;
1398
1399 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1400 return 1;
1401
1402 r = sd_netlink_message_get_errno(m);
1403 if (r < 0 && r != -EEXIST) {
1404 log_link_error_errno(link, r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
1405 link_enter_failed(link);
1406 return 1;
1407 } else
1408 log_link_debug(link, "Joined netdev");
1409
1410 if (link->enslaving <= 0)
1411 link_joined(link);
1412
1413 return 1;
1414}
1415
1416static int link_enter_join_netdev(Link *link) {
1417 NetDev *netdev;
1418 Iterator i;
1419 int r;
1420
1421 assert(link);
1422 assert(link->network);
1423 assert(link->state == LINK_STATE_PENDING);
1424
1425 link_set_state(link, LINK_STATE_ENSLAVING);
1426
1427 link_save(link);
1428
1429 if (!link->network->bridge &&
1430 !link->network->bond &&
1431 hashmap_isempty(link->network->stacked_netdevs))
1432 return link_joined(link);
1433
1434 if (link->network->bond) {
1435 log_struct(LOG_DEBUG,
1436 LOG_LINK_INTERFACE(link),
1437 LOG_NETDEV_INTERFACE(link->network->bond),
1438 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
1439 NULL);
1440
1441 r = netdev_join(link->network->bond, link, netdev_join_handler);
1442 if (r < 0) {
1443 log_struct_errno(LOG_WARNING, r,
1444 LOG_LINK_INTERFACE(link),
1445 LOG_NETDEV_INTERFACE(link->network->bond),
1446 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
1447 NULL);
1448
1449 link_enter_failed(link);
1450 return r;
1451 }
1452
1453 link->enslaving ++;
1454 }
1455
1456 if (link->network->bridge) {
1457 log_struct(LOG_DEBUG,
1458 LOG_LINK_INTERFACE(link),
1459 LOG_NETDEV_INTERFACE(link->network->bridge),
1460 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
1461 NULL);
1462
1463 r = netdev_join(link->network->bridge, link, netdev_join_handler);
1464 if (r < 0) {
1465 log_struct_errno(LOG_WARNING, r,
1466 LOG_LINK_INTERFACE(link),
1467 LOG_NETDEV_INTERFACE(link->network->bridge),
1468 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
1469 NULL),
1470 link_enter_failed(link);
1471 return r;
1472 }
1473
1474 link->enslaving ++;
1475 }
1476
1477 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1478
1479 log_struct(LOG_DEBUG,
1480 LOG_LINK_INTERFACE(link),
1481 LOG_NETDEV_INTERFACE(netdev),
1482 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
1483 NULL);
1484
1485 r = netdev_join(netdev, link, netdev_join_handler);
1486 if (r < 0) {
1487 log_struct_errno(LOG_WARNING, r,
1488 LOG_LINK_INTERFACE(link),
1489 LOG_NETDEV_INTERFACE(netdev),
1490 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
1491 NULL);
1492 link_enter_failed(link);
1493 return r;
1494 }
1495
1496 link->enslaving ++;
1497 }
1498
1499 return 0;
1500}
1501
1502static int link_set_ipv4_forward(Link *link) {
1503 const char *p = NULL, *v;
1504 int r;
1505
1506 if (link->flags & IFF_LOOPBACK)
1507 return 0;
1508
1509 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
1510 return 0;
1511
1512 p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
1513 v = one_zero(link_ipv4_forward_enabled(link));
1514
1515 r = write_string_file(p, v, 0);
1516 if (r < 0) {
1517 /* If the right value is set anyway, don't complain */
1518 if (verify_one_line_file(p, v) > 0)
1519 return 0;
1520
1521 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
1522 }
1523
1524 return 0;
1525}
1526
1527static int link_set_ipv6_forward(Link *link) {
1528 const char *p = NULL, *v = NULL;
1529 int r;
1530
1531 /* Make this a NOP if IPv6 is not available */
1532 if (!socket_ipv6_is_supported())
1533 return 0;
1534
1535 if (link->flags & IFF_LOOPBACK)
1536 return 0;
1537
1538 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
1539 return 0;
1540
1541 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
1542 v = one_zero(link_ipv6_forward_enabled(link));
1543
1544 r = write_string_file(p, v, 0);
1545 if (r < 0) {
1546 /* If the right value is set anyway, don't complain */
1547 if (verify_one_line_file(p, v) > 0)
1548 return 0;
1549
1550 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
1551 }
1552
1553 return 0;
1554}
1555
1556static int link_set_ipv6_privacy_extensions(Link *link) {
1557 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1558 IPv6PrivacyExtensions s;
1559 const char *p = NULL;
1560 int r;
1561
1562 /* Make this a NOP if IPv6 is not available */
1563 if (!socket_ipv6_is_supported())
1564 return 0;
1565
1566 s = link_ipv6_privacy_extensions(link);
1567 if (s == _IPV6_PRIVACY_EXTENSIONS_INVALID)
1568 return 0;
1569
1570 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
1571 xsprintf(buf, "%u", link->network->ipv6_privacy_extensions);
1572
1573 r = write_string_file(p, buf, 0);
1574 if (r < 0) {
1575 /* If the right value is set anyway, don't complain */
1576 if (verify_one_line_file(p, buf) > 0)
1577 return 0;
1578
1579 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
1580 }
1581
1582 return 0;
1583}
1584
1585static int link_configure(Link *link) {
1586 int r;
1587
1588 assert(link);
1589 assert(link->network);
1590 assert(link->state == LINK_STATE_PENDING);
1591
1592 r = link_set_bridge_fdb(link);
1593 if (r < 0)
1594 return r;
1595
1596 r = link_set_ipv4_forward(link);
1597 if (r < 0)
1598 return r;
1599
1600 r = link_set_ipv6_forward(link);
1601 if (r < 0)
1602 return r;
1603
1604 r = link_set_ipv6_privacy_extensions(link);
1605 if (r < 0)
1606 return r;
1607
1608 if (link_ipv4ll_enabled(link)) {
1609 r = ipv4ll_configure(link);
1610 if (r < 0)
1611 return r;
1612 }
1613
1614 if (link_dhcp4_enabled(link)) {
1615 r = dhcp4_configure(link);
1616 if (r < 0)
1617 return r;
1618 }
1619
1620 if (link_dhcp4_server_enabled(link)) {
1621 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1622 if (r < 0)
1623 return r;
1624
1625 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1626 if (r < 0)
1627 return r;
1628 }
1629
1630 if (link_dhcp6_enabled(link)) {
1631 r = icmp6_configure(link);
1632 if (r < 0)
1633 return r;
1634 }
1635
1636 if (link_lldp_enabled(link)) {
1637 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
1638 if (r < 0)
1639 return r;
1640
1641 r = sd_lldp_attach_event(link->lldp, NULL, 0);
1642 if (r < 0)
1643 return r;
1644
1645 r = sd_lldp_set_callback(link->lldp,
1646 lldp_handler, link);
1647 if (r < 0)
1648 return r;
1649 }
1650
1651 if (link_has_carrier(link)) {
1652 r = link_acquire_conf(link);
1653 if (r < 0)
1654 return r;
1655 }
1656
1657 return link_enter_join_netdev(link);
1658}
1659
1660static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
1661 void *userdata) {
1662 _cleanup_link_unref_ Link *link = userdata;
1663 Network *network;
1664 int r;
1665
1666 assert(link);
1667 assert(link->ifname);
1668 assert(link->manager);
1669
1670 if (link->state != LINK_STATE_PENDING)
1671 return 1;
1672
1673 log_link_debug(link, "Link state is up-to-date");
1674
1675 r = link_new_bound_by_list(link);
1676 if (r < 0)
1677 return r;
1678
1679 r = link_handle_bound_by_list(link);
1680 if (r < 0)
1681 return r;
1682
1683 r = network_get(link->manager, link->udev_device, link->ifname,
1684 &link->mac, &network);
1685 if (r == -ENOENT) {
1686 link_enter_unmanaged(link);
1687 return 1;
1688 } else if (r < 0)
1689 return r;
1690
1691 if (link->flags & IFF_LOOPBACK) {
1692 if (network->link_local != ADDRESS_FAMILY_NO)
1693 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
1694
1695 if (network->dhcp != ADDRESS_FAMILY_NO)
1696 log_link_debug(link, "Ignoring DHCP clients for loopback link");
1697
1698 if (network->dhcp_server)
1699 log_link_debug(link, "Ignoring DHCP server for loopback link");
1700 }
1701
1702 r = network_apply(link->manager, network, link);
1703 if (r < 0)
1704 return r;
1705
1706 r = link_new_bound_to_list(link);
1707 if (r < 0)
1708 return r;
1709
1710 r = link_configure(link);
1711 if (r < 0)
1712 return r;
1713
1714 return 1;
1715}
1716
1717int link_initialized(Link *link, struct udev_device *device) {
1718 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
1719 int r;
1720
1721 assert(link);
1722 assert(link->manager);
1723 assert(link->manager->rtnl);
1724 assert(device);
1725
1726 if (link->state != LINK_STATE_PENDING)
1727 return 0;
1728
1729 if (link->udev_device)
1730 return 0;
1731
1732 log_link_debug(link, "udev initialized link");
1733
1734 link->udev_device = udev_device_ref(device);
1735
1736 /* udev has initialized the link, but we don't know if we have yet
1737 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1738 * when it returns we know that the pending NEWLINKs have already been
1739 * processed and that we are up-to-date */
1740
1741 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1742 link->ifindex);
1743 if (r < 0)
1744 return r;
1745
1746 r = sd_netlink_call_async(link->manager->rtnl, req,
1747 link_initialized_and_synced, link, 0, NULL);
1748 if (r < 0)
1749 return r;
1750
1751 link_ref(link);
1752
1753 return 0;
1754}
1755
1756static Address* link_get_equal_address(Link *link, Address *needle) {
1757 Address *i;
1758
1759 assert(link);
1760 assert(needle);
1761
1762 LIST_FOREACH(addresses, i, link->addresses)
1763 if (address_equal(i, needle))
1764 return i;
1765
1766 return NULL;
1767}
1768
1769int link_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
1770 Manager *m = userdata;
1771 Link *link = NULL;
1772 uint16_t type;
1773 _cleanup_address_free_ Address *address = NULL;
1774 unsigned char flags;
1775 Address *existing;
1776 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
1777 const char *valid_str = NULL;
1778 int r, ifindex;
1779
1780 assert(rtnl);
1781 assert(message);
1782 assert(m);
1783
1784 if (sd_netlink_message_is_error(message)) {
1785 r = sd_netlink_message_get_errno(message);
1786 if (r < 0)
1787 log_warning_errno(r, "rtnl: failed to receive address: %m");
1788
1789 return 0;
1790 }
1791
1792 r = sd_netlink_message_get_type(message, &type);
1793 if (r < 0) {
1794 log_warning_errno(r, "rtnl: could not get message type: %m");
1795 return 0;
1796 } else if (type != RTM_NEWADDR && type != RTM_DELADDR) {
1797 log_warning("rtnl: received unexpected message type when processing address");
1798 return 0;
1799 }
1800
1801 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1802 if (r < 0) {
1803 log_warning_errno(r, "rtnl: could not get ifindex from address: %m");
1804 return 0;
1805 } else if (ifindex <= 0) {
1806 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
1807 return 0;
1808 } else {
1809 r = link_get(m, ifindex, &link);
1810 if (r < 0 || !link) {
1811 /* when enumerating we might be out of sync, but we will
1812 * get the address again, so just ignore it */
1813 if (!m->enumerating)
1814 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
1815 return 0;
1816 }
1817 }
1818
1819 r = address_new_dynamic(&address);
1820 if (r < 0)
1821 return r;
1822
1823 r = sd_rtnl_message_addr_get_family(message, &address->family);
1824 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1825 log_link_warning(link, "rtnl: received address with invalid family, ignoring.");
1826 return 0;
1827 }
1828
1829 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1830 if (r < 0) {
1831 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m");
1832 return 0;
1833 }
1834
1835 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1836 if (r < 0) {
1837 log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m");
1838 return 0;
1839 }
1840
1841 r = sd_rtnl_message_addr_get_flags(message, &flags);
1842 if (r < 0) {
1843 log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m");
1844 return 0;
1845 }
1846 address->flags = flags;
1847
1848 switch (address->family) {
1849 case AF_INET:
1850 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1851 if (r < 0) {
1852 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
1853 return 0;
1854 }
1855
1856 break;
1857
1858 case AF_INET6:
1859 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1860 if (r < 0) {
1861 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m");
1862 return 0;
1863 }
1864
1865 break;
1866
1867 default:
1868 assert_not_reached("invalid address family");
1869 }
1870
1871 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1872 log_link_warning(link, "Could not print address");
1873 return 0;
1874 }
1875
1876 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo);
1877 if (r >= 0) {
1878 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1879 valid_str = "ever";
1880 else
1881 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1882 address->cinfo.ifa_valid * USEC_PER_SEC,
1883 USEC_PER_SEC);
1884 }
1885
1886 existing = link_get_equal_address(link, address);
1887
1888 switch (type) {
1889 case RTM_NEWADDR:
1890 if (existing) {
1891 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1892
1893
1894 existing->scope = address->scope;
1895 existing->flags = address->flags;
1896 existing->cinfo = address->cinfo;
1897
1898 } else {
1899 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1900
1901 LIST_PREPEND(addresses, link->addresses, address);
1902 address_establish(address, link);
1903
1904 address = NULL;
1905
1906 link_save(link);
1907 }
1908
1909 break;
1910
1911 case RTM_DELADDR:
1912
1913 if (existing) {
1914 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1915 address_release(existing, link);
1916 LIST_REMOVE(addresses, link->addresses, existing);
1917 address_free(existing);
1918 } else
1919 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1920
1921 break;
1922 default:
1923 assert_not_reached("Received invalid RTNL message type");
1924 }
1925
1926 return 1;
1927}
1928
1929int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
1930 Link *link;
1931 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1932 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1933 int r;
1934
1935 assert(m);
1936 assert(m->rtnl);
1937 assert(message);
1938 assert(ret);
1939
1940 r = link_new(m, message, ret);
1941 if (r < 0)
1942 return r;
1943
1944 link = *ret;
1945
1946 log_link_debug(link, "Link %d added", link->ifindex);
1947
1948 if (detect_container(NULL) <= 0) {
1949 /* not in a container, udev will be around */
1950 sprintf(ifindex_str, "n%d", link->ifindex);
1951 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1952 if (!device)
1953 return log_link_warning_errno(link, errno, "Could not find udev device: %m");
1954
1955 if (udev_device_get_is_initialized(device) <= 0) {
1956 /* not yet ready */
1957 log_link_debug(link, "link pending udev initialization...");
1958 return 0;
1959 }
1960
1961 r = link_initialized(link, device);
1962 if (r < 0)
1963 return r;
1964 } else {
1965 /* we are calling a callback directly, so must take a ref */
1966 link_ref(link);
1967
1968 r = link_initialized_and_synced(m->rtnl, NULL, link);
1969 if (r < 0)
1970 return r;
1971 }
1972
1973 return 0;
1974}
1975
1976static int link_carrier_gained(Link *link) {
1977 int r;
1978
1979 assert(link);
1980
1981 if (link->network) {
1982 r = link_acquire_conf(link);
1983 if (r < 0) {
1984 link_enter_failed(link);
1985 return r;
1986 }
1987 }
1988
1989 r = link_handle_bound_by_list(link);
1990 if (r < 0)
1991 return r;
1992
1993 return 0;
1994}
1995
1996static int link_carrier_lost(Link *link) {
1997 int r;
1998
1999 assert(link);
2000
2001 r = link_stop_clients(link);
2002 if (r < 0) {
2003 link_enter_failed(link);
2004 return r;
2005 }
2006
2007 r = link_handle_bound_by_list(link);
2008 if (r < 0)
2009 return r;
2010
2011 return 0;
2012}
2013
2014int link_carrier_reset(Link *link) {
2015 int r;
2016
2017 assert(link);
2018
2019 if (link_has_carrier(link)) {
2020 r = link_carrier_lost(link);
2021 if (r < 0)
2022 return r;
2023
2024 r = link_carrier_gained(link);
2025 if (r < 0)
2026 return r;
2027
2028 log_link_info(link, "Reset carrier");
2029 }
2030
2031 return 0;
2032}
2033
2034
2035int link_update(Link *link, sd_netlink_message *m) {
2036 struct ether_addr mac;
2037 const char *ifname;
2038 uint32_t mtu;
2039 bool had_carrier, carrier_gained, carrier_lost;
2040 int r;
2041
2042 assert(link);
2043 assert(link->ifname);
2044 assert(m);
2045
2046 if (link->state == LINK_STATE_LINGER) {
2047 link_ref(link);
2048 log_link_info(link, "Link readded");
2049 link_set_state(link, LINK_STATE_ENSLAVING);
2050
2051 r = link_new_carrier_maps(link);
2052 if (r < 0)
2053 return r;
2054 }
2055
2056 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
2057 if (r >= 0 && !streq(ifname, link->ifname)) {
2058 log_link_info(link, "Renamed to %s", ifname);
2059
2060 link_free_carrier_maps(link);
2061
2062 free(link->ifname);
2063 link->ifname = strdup(ifname);
2064 if (!link->ifname)
2065 return -ENOMEM;
2066
2067 r = link_new_carrier_maps(link);
2068 if (r < 0)
2069 return r;
2070 }
2071
2072 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
2073 if (r >= 0 && mtu > 0) {
2074 link->mtu = mtu;
2075 if (!link->original_mtu) {
2076 link->original_mtu = mtu;
2077 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
2078 }
2079
2080 if (link->dhcp_client) {
2081 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2082 link->mtu);
2083 if (r < 0) {
2084 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
2085 return r;
2086 }
2087 }
2088 }
2089
2090 /* The kernel may broadcast NEWLINK messages without the MAC address
2091 set, simply ignore them. */
2092 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2093 if (r >= 0) {
2094 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2095 ETH_ALEN)) {
2096
2097 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2098 ETH_ALEN);
2099
2100 log_link_debug(link, "MAC address: "
2101 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2102 mac.ether_addr_octet[0],
2103 mac.ether_addr_octet[1],
2104 mac.ether_addr_octet[2],
2105 mac.ether_addr_octet[3],
2106 mac.ether_addr_octet[4],
2107 mac.ether_addr_octet[5]);
2108
2109 if (link->ipv4ll) {
2110 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2111 if (r < 0)
2112 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
2113 }
2114
2115 if (link->dhcp_client) {
2116 r = sd_dhcp_client_set_mac(link->dhcp_client,
2117 (const uint8_t *) &link->mac,
2118 sizeof (link->mac),
2119 ARPHRD_ETHER);
2120 if (r < 0)
2121 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
2122 }
2123
2124 if (link->dhcp6_client) {
2125 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2126 (const uint8_t *) &link->mac,
2127 sizeof (link->mac),
2128 ARPHRD_ETHER);
2129 if (r < 0)
2130 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
2131 }
2132 }
2133 }
2134
2135 had_carrier = link_has_carrier(link);
2136
2137 r = link_update_flags(link, m);
2138 if (r < 0)
2139 return r;
2140
2141 carrier_gained = !had_carrier && link_has_carrier(link);
2142 carrier_lost = had_carrier && !link_has_carrier(link);
2143
2144 if (carrier_gained) {
2145 log_link_info(link, "Gained carrier");
2146
2147 r = link_carrier_gained(link);
2148 if (r < 0)
2149 return r;
2150 } else if (carrier_lost) {
2151 log_link_info(link, "Lost carrier");
2152
2153 r = link_carrier_lost(link);
2154 if (r < 0)
2155 return r;
2156
2157 }
2158
2159 return 0;
2160}
2161
2162static void link_update_operstate(Link *link) {
2163 LinkOperationalState operstate;
2164 assert(link);
2165
2166 if (link->kernel_operstate == IF_OPER_DORMANT)
2167 operstate = LINK_OPERSTATE_DORMANT;
2168 else if (link_has_carrier(link)) {
2169 Address *address;
2170 uint8_t scope = RT_SCOPE_NOWHERE;
2171
2172 /* if we have carrier, check what addresses we have */
2173 LIST_FOREACH(addresses, address, link->addresses) {
2174 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
2175 continue;
2176
2177 if (address->scope < scope)
2178 scope = address->scope;
2179 }
2180
2181 if (scope < RT_SCOPE_SITE)
2182 /* universally accessible addresses found */
2183 operstate = LINK_OPERSTATE_ROUTABLE;
2184 else if (scope < RT_SCOPE_HOST)
2185 /* only link or site local addresses found */
2186 operstate = LINK_OPERSTATE_DEGRADED;
2187 else
2188 /* no useful addresses found */
2189 operstate = LINK_OPERSTATE_CARRIER;
2190 } else if (link->flags & IFF_UP)
2191 operstate = LINK_OPERSTATE_NO_CARRIER;
2192 else
2193 operstate = LINK_OPERSTATE_OFF;
2194
2195 if (link->operstate != operstate) {
2196 link->operstate = operstate;
2197 link_send_changed(link, "OperationalState", NULL);
2198 }
2199}
2200
2201int link_save(Link *link) {
2202 _cleanup_free_ char *temp_path = NULL;
2203 _cleanup_fclose_ FILE *f = NULL;
2204 const char *admin_state, *oper_state;
2205 int r;
2206
2207 assert(link);
2208 assert(link->state_file);
2209 assert(link->lease_file);
2210 assert(link->manager);
2211
2212 link_update_operstate(link);
2213
2214 r = manager_save(link->manager);
2215 if (r < 0)
2216 return r;
2217
2218 if (link->state == LINK_STATE_LINGER) {
2219 unlink(link->state_file);
2220 return 0;
2221 }
2222
2223 admin_state = link_state_to_string(link->state);
2224 assert(admin_state);
2225
2226 oper_state = link_operstate_to_string(link->operstate);
2227 assert(oper_state);
2228
2229 r = fopen_temporary(link->state_file, &f, &temp_path);
2230 if (r < 0)
2231 goto fail;
2232
2233 fchmod(fileno(f), 0644);
2234
2235 fprintf(f,
2236 "# This is private data. Do not parse.\n"
2237 "ADMIN_STATE=%s\n"
2238 "OPER_STATE=%s\n",
2239 admin_state, oper_state);
2240
2241 if (link->network) {
2242 char **address, **domain;
2243 bool space;
2244
2245 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2246
2247 fputs("DNS=", f);
2248 space = false;
2249 STRV_FOREACH(address, link->network->dns) {
2250 if (space)
2251 fputc(' ', f);
2252 fputs(*address, f);
2253 space = true;
2254 }
2255
2256 if (link->network->dhcp_dns &&
2257 link->dhcp_lease) {
2258 const struct in_addr *addresses;
2259
2260 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2261 if (r > 0) {
2262 if (space)
2263 fputc(' ', f);
2264 serialize_in_addrs(f, addresses, r);
2265 }
2266 }
2267
2268 fputs("\n", f);
2269
2270 fprintf(f, "NTP=");
2271 space = false;
2272 STRV_FOREACH(address, link->network->ntp) {
2273 if (space)
2274 fputc(' ', f);
2275 fputs(*address, f);
2276 space = true;
2277 }
2278
2279 if (link->network->dhcp_ntp &&
2280 link->dhcp_lease) {
2281 const struct in_addr *addresses;
2282
2283 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2284 if (r > 0) {
2285 if (space)
2286 fputc(' ', f);
2287 serialize_in_addrs(f, addresses, r);
2288 }
2289 }
2290
2291 fputs("\n", f);
2292
2293 fprintf(f, "DOMAINS=");
2294 space = false;
2295 STRV_FOREACH(domain, link->network->domains) {
2296 if (space)
2297 fputc(' ', f);
2298 fputs(*domain, f);
2299 space = true;
2300 }
2301
2302 if (link->network->dhcp_domains &&
2303 link->dhcp_lease) {
2304 const char *domainname;
2305
2306 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
2307 if (r >= 0) {
2308 if (space)
2309 fputc(' ', f);
2310 fputs(domainname, f);
2311 }
2312 }
2313
2314 fputs("\n", f);
2315
2316 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2317 yes_no(link->network->wildcard_domain));
2318
2319 fprintf(f, "LLMNR=%s\n",
2320 llmnr_support_to_string(link->network->llmnr));
2321 }
2322
2323 if (!hashmap_isempty(link->bound_to_links)) {
2324 Link *carrier;
2325 Iterator i;
2326 bool space = false;
2327
2328 fputs("CARRIER_BOUND_TO=", f);
2329 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2330 if (space)
2331 fputc(' ', f);
2332 fputs(carrier->ifname, f);
2333 space = true;
2334 }
2335
2336 fputs("\n", f);
2337 }
2338
2339 if (!hashmap_isempty(link->bound_by_links)) {
2340 Link *carrier;
2341 Iterator i;
2342 bool space = false;
2343
2344 fputs("CARRIER_BOUND_BY=", f);
2345 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2346 if (space)
2347 fputc(' ', f);
2348 fputs(carrier->ifname, f);
2349 space = true;
2350 }
2351
2352 fputs("\n", f);
2353 }
2354
2355 if (link->dhcp_lease) {
2356 assert(link->network);
2357
2358 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
2359 if (r < 0)
2360 goto fail;
2361
2362 fprintf(f,
2363 "DHCP_LEASE=%s\n",
2364 link->lease_file);
2365 } else
2366 unlink(link->lease_file);
2367
2368 if (link->lldp) {
2369 assert(link->network);
2370
2371 r = sd_lldp_save(link->lldp, link->lldp_file);
2372 if (r < 0)
2373 goto fail;
2374
2375 fprintf(f,
2376 "LLDP_FILE=%s\n",
2377 link->lldp_file);
2378 } else
2379 unlink(link->lldp_file);
2380
2381 r = fflush_and_check(f);
2382 if (r < 0)
2383 goto fail;
2384
2385 if (rename(temp_path, link->state_file) < 0) {
2386 r = -errno;
2387 goto fail;
2388 }
2389
2390 return 0;
2391
2392fail:
2393 (void) unlink(link->state_file);
2394 if (temp_path)
2395 (void) unlink(temp_path);
2396
2397 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
2398}
2399
2400static const char* const link_state_table[_LINK_STATE_MAX] = {
2401 [LINK_STATE_PENDING] = "pending",
2402 [LINK_STATE_ENSLAVING] = "configuring",
2403 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2404 [LINK_STATE_SETTING_ROUTES] = "configuring",
2405 [LINK_STATE_CONFIGURED] = "configured",
2406 [LINK_STATE_UNMANAGED] = "unmanaged",
2407 [LINK_STATE_FAILED] = "failed",
2408 [LINK_STATE_LINGER] = "linger",
2409};
2410
2411DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2412
2413static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2414 [LINK_OPERSTATE_OFF] = "off",
2415 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
2416 [LINK_OPERSTATE_DORMANT] = "dormant",
2417 [LINK_OPERSTATE_CARRIER] = "carrier",
2418 [LINK_OPERSTATE_DEGRADED] = "degraded",
2419 [LINK_OPERSTATE_ROUTABLE] = "routable",
2420};
2421
2422DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);