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