]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/network/networkd-link.c
networkd: Introduce Link Layer Discovery Protocol (LLDP)
[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 "networkd-link.h"
27#include "networkd-netdev.h"
28#include "libudev-private.h"
29#include "udev-util.h"
30#include "util.h"
31#include "virt.h"
32#include "bus-util.h"
33#include "network-internal.h"
34#include "conf-parser.h"
35
36#include "dhcp-lease-internal.h"
37
38static bool link_dhcp6_enabled(Link *link) {
39 if (link->flags & IFF_LOOPBACK)
40 return false;
41
42 if (!link->network)
43 return false;
44
45 return IN_SET(link->network->dhcp, DHCP_SUPPORT_V6, DHCP_SUPPORT_BOTH);
46}
47
48static bool link_dhcp4_enabled(Link *link) {
49 if (link->flags & IFF_LOOPBACK)
50 return false;
51
52 if (!link->network)
53 return false;
54
55 return IN_SET(link->network->dhcp, DHCP_SUPPORT_V4, DHCP_SUPPORT_BOTH);
56}
57
58static bool link_dhcp4_server_enabled(Link *link) {
59 if (link->flags & IFF_LOOPBACK)
60 return false;
61
62 if (!link->network)
63 return false;
64
65 return link->network->dhcp_server;
66}
67
68static bool link_ipv4ll_enabled(Link *link) {
69 if (link->flags & IFF_LOOPBACK)
70 return false;
71
72 if (!link->network)
73 return false;
74
75 return link->network->ipv4ll;
76}
77
78#define FLAG_STRING(string, flag, old, new) \
79 (((old ^ new) & flag) \
80 ? ((old & flag) ? (" -" string) : (" +" string)) \
81 : "")
82
83static int link_update_flags(Link *link, sd_rtnl_message *m) {
84 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
85 uint8_t operstate;
86 int r;
87
88 assert(link);
89
90 r = sd_rtnl_message_link_get_flags(m, &flags);
91 if (r < 0) {
92 log_link_warning(link, "Could not get link flags");
93 return r;
94 }
95
96 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
97 if (r < 0)
98 /* if we got a message without operstate, take it to mean
99 the state was unchanged */
100 operstate = link->kernel_operstate;
101
102 if ((link->flags == flags) && (link->kernel_operstate == operstate))
103 return 0;
104
105 if (link->flags != flags) {
106 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",
107 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
108 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
109 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
110 FLAG_STRING("UP", IFF_UP, link->flags, flags),
111 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
112 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
113 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
114 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
115 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
116 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
117 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
118 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
119 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
120 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
121 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
122 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
123 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
124 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
125 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
126
127 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
128 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
129 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
130 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
131 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
132 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
133 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
134 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
135
136 /* link flags are currently at most 18 bits, let's align to
137 * printing 20 */
138 if (unknown_flags_added)
139 log_link_debug(link,
140 "unknown link flags gained: %#.5x (ignoring)",
141 unknown_flags_added);
142
143 if (unknown_flags_removed)
144 log_link_debug(link,
145 "unknown link flags lost: %#.5x (ignoring)",
146 unknown_flags_removed);
147 }
148
149 link->flags = flags;
150 link->kernel_operstate = operstate;
151
152 link_save(link);
153
154 return 0;
155}
156
157static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
158 _cleanup_link_unref_ Link *link = NULL;
159 uint16_t type;
160 const char *ifname;
161 int r, ifindex;
162
163 assert(manager);
164 assert(message);
165 assert(ret);
166
167 r = sd_rtnl_message_get_type(message, &type);
168 if (r < 0)
169 return r;
170 else if (type != RTM_NEWLINK)
171 return -EINVAL;
172
173 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
174 if (r < 0)
175 return r;
176 else if (ifindex <= 0)
177 return -EINVAL;
178
179 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
180 if (r < 0)
181 return r;
182
183 link = new0(Link, 1);
184 if (!link)
185 return -ENOMEM;
186
187 link->n_ref = 1;
188 link->manager = manager;
189 link->state = LINK_STATE_PENDING;
190 link->ifindex = ifindex;
191 link->ifname = strdup(ifname);
192 if (!link->ifname)
193 return -ENOMEM;
194
195 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
196 if (r < 0)
197 log_link_debug(link, "MAC address not found for new device, continuing without");
198
199 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
200 link->ifindex);
201 if (r < 0)
202 return -ENOMEM;
203
204 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
205 link->ifindex);
206 if (r < 0)
207 return -ENOMEM;
208
209 r = hashmap_ensure_allocated(&manager->links, NULL);
210 if (r < 0)
211 return r;
212
213 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
214 if (r < 0)
215 return r;
216
217 r = link_update_flags(link, message);
218 if (r < 0)
219 return r;
220
221 *ret = link;
222 link = NULL;
223
224 return 0;
225}
226
227static void link_free(Link *link) {
228 Address *address;
229
230 if (!link)
231 return;
232
233 while ((address = link->addresses)) {
234 LIST_REMOVE(addresses, link->addresses, address);
235 address_free(address);
236 }
237
238 while ((address = link->pool_addresses)) {
239 LIST_REMOVE(addresses, link->pool_addresses, address);
240 address_free(address);
241 }
242
243 sd_dhcp_client_unref(link->dhcp_client);
244 sd_dhcp_lease_unref(link->dhcp_lease);
245
246 unlink(link->lease_file);
247 free(link->lease_file);
248
249 sd_ipv4ll_unref(link->ipv4ll);
250 sd_dhcp6_client_unref(link->dhcp6_client);
251 sd_icmp6_nd_unref(link->icmp6_router_discovery);
252
253 if (link->manager)
254 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
255
256 free(link->ifname);
257
258 unlink(link->state_file);
259 free(link->state_file);
260
261 udev_device_unref(link->udev_device);
262
263 free(link);
264}
265
266Link *link_unref(Link *link) {
267 if (link && (-- link->n_ref <= 0))
268 link_free(link);
269
270 return NULL;
271}
272
273Link *link_ref(Link *link) {
274 if (link)
275 assert_se(++ link->n_ref >= 2);
276
277 return link;
278}
279
280int link_get(Manager *m, int ifindex, Link **ret) {
281 Link *link;
282
283 assert(m);
284 assert(ifindex);
285 assert(ret);
286
287 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
288 if (!link)
289 return -ENODEV;
290
291 *ret = link;
292
293 return 0;
294}
295
296void link_drop(Link *link) {
297 if (!link || link->state == LINK_STATE_LINGER)
298 return;
299
300 link->state = LINK_STATE_LINGER;
301
302 log_link_debug(link, "link removed");
303
304 link_unref(link);
305
306 return;
307}
308
309static void link_enter_unmanaged(Link *link) {
310 assert(link);
311
312 log_link_debug(link, "unmanaged");
313
314 link->state = LINK_STATE_UNMANAGED;
315
316 link_save(link);
317}
318
319static int link_stop_clients(Link *link) {
320 int r = 0, k;
321
322 assert(link);
323 assert(link->manager);
324 assert(link->manager->event);
325
326 if (!link->network)
327 return 0;
328
329 if (link->dhcp_client) {
330 k = sd_dhcp_client_stop(link->dhcp_client);
331 if (k < 0) {
332 log_link_warning(link, "Could not stop DHCPv4 client: %s",
333 strerror(-r));
334 r = k;
335 }
336 }
337
338 if (link->ipv4ll) {
339 k = sd_ipv4ll_stop(link->ipv4ll);
340 if (k < 0) {
341 log_link_warning(link, "Could not stop IPv4 link-local: %s",
342 strerror(-r));
343 r = k;
344 }
345 }
346
347 if(link->icmp6_router_discovery) {
348
349 if (link->dhcp6_client) {
350 k = sd_dhcp6_client_stop(link->dhcp6_client);
351 if (k < 0) {
352 log_link_warning(link, "Could not stop DHCPv6 client: %s",
353 strerror(-r));
354 r = k;
355 }
356 }
357
358 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
359 if (k < 0) {
360 log_link_warning(link,
361 "Could not stop ICMPv6 router discovery: %s",
362 strerror(-r));
363 r = k;
364 }
365 }
366
367 return r;
368}
369
370void link_enter_failed(Link *link) {
371 assert(link);
372
373 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
374 return;
375
376 log_link_warning(link, "failed");
377
378 link->state = LINK_STATE_FAILED;
379
380 link_stop_clients(link);
381
382 link_save(link);
383}
384
385static Address* link_find_dhcp_server_address(Link *link) {
386 Address *address;
387
388 assert(link);
389 assert(link->network);
390
391 /* The the first statically configured address if there is any */
392 LIST_FOREACH(addresses, address, link->network->static_addresses) {
393
394 if (address->family != AF_INET)
395 continue;
396
397 if (in_addr_is_null(address->family, &address->in_addr))
398 continue;
399
400 return address;
401 }
402
403 /* If that didn't work, find a suitable address we got from the pool */
404 LIST_FOREACH(addresses, address, link->pool_addresses) {
405 if (address->family != AF_INET)
406 continue;
407
408 return address;
409 }
410
411 return NULL;
412}
413
414static int link_enter_configured(Link *link) {
415 int r;
416
417 assert(link);
418 assert(link->network);
419 assert(link->state == LINK_STATE_SETTING_ROUTES);
420
421 if (link_dhcp4_server_enabled(link) &&
422 !sd_dhcp_server_is_running(link->dhcp_server)) {
423 struct in_addr pool_start;
424 Address *address;
425
426 address = link_find_dhcp_server_address(link);
427 if (!address) {
428 log_link_warning(link,
429 "Failed to find suitable address for DHCPv4 server instance.");
430 link_enter_failed(link);
431 return 0;
432 }
433
434 log_link_debug(link, "offering DHCPv4 leases");
435
436 r = sd_dhcp_server_set_address(link->dhcp_server,
437 &address->in_addr.in,
438 address->prefixlen);
439 if (r < 0)
440 return r;
441
442 /* offer 32 addresses starting from the address following the server address */
443 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
444 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
445 &pool_start, 32);
446 if (r < 0)
447 return r;
448
449 /* TODO:
450 r = sd_dhcp_server_set_router(link->dhcp_server,
451 &main_address->in_addr.in);
452 if (r < 0)
453 return r;
454
455 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
456 main_address->prefixlen);
457 if (r < 0)
458 return r;
459 */
460
461 r = sd_dhcp_server_start(link->dhcp_server);
462 if (r < 0) {
463 log_link_warning(link, "could not start DHCPv4 server "
464 "instance: %s", strerror(-r));
465
466 link_enter_failed(link);
467
468 return 0;
469 }
470 }
471
472 log_link_info(link, "link configured");
473
474 link->state = LINK_STATE_CONFIGURED;
475
476 link_save(link);
477
478 return 0;
479}
480
481void link_client_handler(Link *link) {
482 assert(link);
483 assert(link->network);
484
485 if (!link->static_configured)
486 return;
487
488 if (link_ipv4ll_enabled(link))
489 if (!link->ipv4ll_address ||
490 !link->ipv4ll_route)
491 return;
492
493 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
494 return;
495
496 if (link->state != LINK_STATE_CONFIGURED)
497 link_enter_configured(link);
498
499 return;
500}
501
502static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
503 _cleanup_link_unref_ Link *link = userdata;
504 int r;
505
506 assert(link->link_messages > 0);
507 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
508 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
509 LINK_STATE_LINGER));
510
511 link->link_messages --;
512
513 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
514 return 1;
515
516 r = sd_rtnl_message_get_errno(m);
517 if (r < 0 && r != -EEXIST)
518 log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
519
520 if (link->link_messages == 0) {
521 log_link_debug(link, "routes set");
522 link->static_configured = true;
523 link_client_handler(link);
524 }
525
526 return 1;
527}
528
529static int link_enter_set_routes(Link *link) {
530 Route *rt;
531 int r;
532
533 assert(link);
534 assert(link->network);
535 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
536
537 link->state = LINK_STATE_SETTING_ROUTES;
538
539 LIST_FOREACH(routes, rt, link->network->static_routes) {
540 r = route_configure(rt, link, &route_handler);
541 if (r < 0) {
542 log_link_warning(link,
543 "could not set routes: %s",
544 strerror(-r));
545 link_enter_failed(link);
546 return r;
547 }
548
549 link->link_messages ++;
550 }
551
552 if (link->link_messages == 0) {
553 link->static_configured = true;
554 link_client_handler(link);
555 } else
556 log_link_debug(link, "setting routes");
557
558 return 0;
559}
560
561int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
562 _cleanup_link_unref_ Link *link = userdata;
563 int r;
564
565 assert(m);
566 assert(link);
567 assert(link->ifname);
568
569 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
570 return 1;
571
572 r = sd_rtnl_message_get_errno(m);
573 if (r < 0 && r != -ESRCH)
574 log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
575
576 return 1;
577}
578
579static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
580 _cleanup_link_unref_ Link *link = userdata;
581 int r;
582
583 assert(rtnl);
584 assert(m);
585 assert(link);
586 assert(link->ifname);
587 assert(link->link_messages > 0);
588 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
589 LINK_STATE_FAILED, LINK_STATE_LINGER));
590
591 link->link_messages --;
592
593 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
594 return 1;
595
596 r = sd_rtnl_message_get_errno(m);
597 if (r < 0 && r != -EEXIST)
598 log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
599 else if (r >= 0)
600 link_rtnl_process_address(rtnl, m, link->manager);
601
602 if (link->link_messages == 0) {
603 log_link_debug(link, "addresses set");
604 link_enter_set_routes(link);
605 }
606
607 return 1;
608}
609
610static int link_enter_set_addresses(Link *link) {
611 Address *ad;
612 int r;
613
614 assert(link);
615 assert(link->network);
616 assert(link->state != _LINK_STATE_INVALID);
617
618 link->state = LINK_STATE_SETTING_ADDRESSES;
619
620 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
621 r = address_configure(ad, link, &address_handler);
622 if (r < 0) {
623 log_link_warning(link,
624 "could not set addresses: %s",
625 strerror(-r));
626 link_enter_failed(link);
627 return r;
628 }
629
630 link->link_messages ++;
631 }
632
633 if (link->link_messages == 0) {
634 link_enter_set_routes(link);
635 } else
636 log_link_debug(link, "setting addresses");
637
638 return 0;
639}
640
641int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
642 _cleanup_link_unref_ Link *link = userdata;
643 int r;
644
645 assert(m);
646 assert(link);
647 assert(link->ifname);
648
649 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
650 return 1;
651
652 r = sd_rtnl_message_get_errno(m);
653 if (r < 0 && r != -EADDRNOTAVAIL)
654 log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
655
656 return 1;
657}
658
659static int link_set_bridge_fdb(const Link *const link) {
660 FdbEntry *fdb_entry;
661 int r = 0;
662
663 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
664 r = fdb_entry_configure(link->manager->rtnl, fdb_entry, link->ifindex);
665 if(r < 0) {
666 log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r));
667 break;
668 }
669 }
670
671 return r;
672}
673
674static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
675 _cleanup_link_unref_ Link *link = userdata;
676 int r;
677
678 log_link_debug(link, "set link");
679
680 r = sd_rtnl_message_get_errno(m);
681 if (r < 0 && r != -EEXIST) {
682 log_link_struct(link, LOG_ERR,
683 "MESSAGE=%-*s: could not join netdev: %s",
684 IFNAMSIZ,
685 link->ifname, strerror(-r),
686 "ERRNO=%d", -r,
687 NULL);
688 link_enter_failed(link);
689 return 1;
690 }
691
692 return 0;
693}
694
695static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
696 sd_bus_error *ret_error) {
697 _cleanup_link_unref_ Link *link = userdata;
698 int r;
699
700 assert(link);
701
702 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
703 return 1;
704
705 r = sd_bus_message_get_errno(m);
706 if (r > 0)
707 log_link_warning(link, "Could not set hostname: %s",
708 strerror(r));
709
710 return 1;
711}
712
713int link_set_hostname(Link *link, const char *hostname) {
714 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
715 int r = 0;
716
717 assert(link);
718 assert(link->manager);
719 assert(hostname);
720
721 log_link_debug(link, "Setting transient hostname: '%s'", hostname);
722
723 if (!link->manager->bus) {
724 /* TODO: replace by assert when we can rely on kdbus */
725 log_link_info(link,
726 "Not connected to system bus, ignoring transient hostname.");
727 return 0;
728 }
729
730 r = sd_bus_message_new_method_call(
731 link->manager->bus,
732 &m,
733 "org.freedesktop.hostname1",
734 "/org/freedesktop/hostname1",
735 "org.freedesktop.hostname1",
736 "SetHostname");
737 if (r < 0)
738 return r;
739
740 r = sd_bus_message_append(m, "sb", hostname, false);
741 if (r < 0)
742 return r;
743
744 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
745 link, 0);
746 if (r < 0) {
747 log_link_error(link, "Could not set transient hostname: %s",
748 strerror(-r));
749 return r;
750 }
751
752 link_ref(link);
753
754 return 0;
755}
756
757static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
758 _cleanup_link_unref_ Link *link = userdata;
759 int r;
760
761 assert(m);
762 assert(link);
763 assert(link->ifname);
764
765 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
766 return 1;
767
768 r = sd_rtnl_message_get_errno(m);
769 if (r < 0)
770 log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
771
772 return 1;
773}
774
775int link_set_mtu(Link *link, uint32_t mtu) {
776 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
777 int r;
778
779 assert(link);
780 assert(link->manager);
781 assert(link->manager->rtnl);
782
783 log_link_debug(link, "setting MTU: %" PRIu32, mtu);
784
785 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
786 RTM_SETLINK, link->ifindex);
787 if (r < 0) {
788 log_link_error(link, "Could not allocate RTM_SETLINK message");
789 return r;
790 }
791
792 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
793 if (r < 0) {
794 log_link_error(link, "Could not append MTU: %s", strerror(-r));
795 return r;
796 }
797
798 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
799 0, NULL);
800 if (r < 0) {
801 log_link_error(link,
802 "Could not send rtnetlink message: %s",
803 strerror(-r));
804 return r;
805 }
806
807 link_ref(link);
808
809 return 0;
810}
811
812static int link_set_bridge(Link *link) {
813 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
814 int r;
815
816 assert(link);
817 assert(link->network);
818
819 if(link->network->cost == 0)
820 return 0;
821
822 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
823 RTM_SETLINK, link->ifindex);
824 if (r < 0) {
825 log_link_error(link, "Could not allocate RTM_SETLINK message");
826 return r;
827 }
828
829 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
830 if (r < 0) {
831 log_link_error(link,
832 "Could not set message family %s", strerror(-r));
833 return r;
834 }
835
836 r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
837 if (r < 0) {
838 log_link_error(link,
839 "Could not append IFLA_PROTINFO attribute: %s",
840 strerror(-r));
841 return r;
842 }
843
844 if(link->network->cost != 0) {
845 r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
846 if (r < 0) {
847 log_link_error(link,
848 "Could not append IFLA_BRPORT_COST attribute: %s",
849 strerror(-r));
850 return r;
851 }
852 }
853
854 r = sd_rtnl_message_close_container(req);
855 if (r < 0) {
856 log_link_error(link,
857 "Could not append IFLA_LINKINFO attribute: %s",
858 strerror(-r));
859 return r;
860 }
861
862 r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
863 if (r < 0) {
864 log_link_error(link,
865 "Could not send rtnetlink message: %s",
866 strerror(-r));
867 return r;
868 }
869
870 link_ref(link);
871
872 return r;
873}
874
875static int link_acquire_conf(Link *link) {
876 int r;
877
878 assert(link);
879 assert(link->network);
880 assert(link->manager);
881 assert(link->manager->event);
882
883 if (link_ipv4ll_enabled(link)) {
884 assert(link->ipv4ll);
885
886 log_link_debug(link, "acquiring IPv4 link-local address");
887
888 r = sd_ipv4ll_start(link->ipv4ll);
889 if (r < 0) {
890 log_link_warning(link, "could not acquire IPv4 "
891 "link-local address");
892 return r;
893 }
894 }
895
896 if (link_dhcp4_enabled(link)) {
897 assert(link->dhcp_client);
898
899 log_link_debug(link, "acquiring DHCPv4 lease");
900
901 r = sd_dhcp_client_start(link->dhcp_client);
902 if (r < 0) {
903 log_link_warning(link, "could not acquire DHCPv4 "
904 "lease");
905 return r;
906 }
907 }
908
909 if (link_dhcp6_enabled(link)) {
910 assert(link->icmp6_router_discovery);
911
912 log_link_debug(link, "discovering IPv6 routers");
913
914 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
915 if (r < 0) {
916 log_link_warning(link,
917 "could not start IPv6 router discovery");
918 return r;
919 }
920 }
921
922 return 0;
923}
924
925bool link_has_carrier(Link *link) {
926 /* see Documentation/networking/operstates.txt in the kernel sources */
927
928 if (link->kernel_operstate == IF_OPER_UP)
929 return true;
930
931 if (link->kernel_operstate == IF_OPER_UNKNOWN)
932 /* operstate may not be implemented, so fall back to flags */
933 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
934 return true;
935
936 return false;
937}
938
939static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
940 _cleanup_link_unref_ Link *link = userdata;
941 int r;
942
943 assert(link);
944
945 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
946 return 1;
947
948 r = sd_rtnl_message_get_errno(m);
949 if (r < 0) {
950 /* we warn but don't fail the link, as it may
951 be brought up later */
952 log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
953 }
954
955 return 1;
956}
957
958static int link_up(Link *link) {
959 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
960 int r;
961
962 assert(link);
963 assert(link->network);
964 assert(link->manager);
965 assert(link->manager->rtnl);
966
967 log_link_debug(link, "bringing link up");
968
969 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
970 RTM_SETLINK, link->ifindex);
971 if (r < 0) {
972 log_link_error(link, "Could not allocate RTM_SETLINK message");
973 return r;
974 }
975
976 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
977 if (r < 0) {
978 log_link_error(link, "Could not set link flags: %s",
979 strerror(-r));
980 return r;
981 }
982
983 if (link->network->mac) {
984 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
985 if (r < 0) {
986 log_link_error(link, "Could not set MAC address: %s", strerror(-r));
987 return r;
988 }
989 }
990
991 if (link->network->mtu) {
992 r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
993 if (r < 0) {
994 log_link_error(link, "Could not set MTU: %s", strerror(-r));
995 return r;
996 }
997 }
998
999 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1000 0, NULL);
1001 if (r < 0) {
1002 log_link_error(link,
1003 "Could not send rtnetlink message: %s",
1004 strerror(-r));
1005 return r;
1006 }
1007
1008 link_ref(link);
1009
1010 return 0;
1011}
1012
1013static int link_joined(Link *link) {
1014 int r;
1015
1016 assert(link);
1017 assert(link->network);
1018
1019 if (!(link->flags & IFF_UP)) {
1020 r = link_up(link);
1021 if (r < 0) {
1022 link_enter_failed(link);
1023 return r;
1024 }
1025 }
1026
1027 if(link->network->bridge) {
1028 r = link_set_bridge(link);
1029 if (r < 0) {
1030 log_link_error(link,
1031 "Could not set bridge message: %s",
1032 strerror(-r));
1033 }
1034 }
1035
1036 return link_enter_set_addresses(link);
1037}
1038
1039static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1040 void *userdata) {
1041 _cleanup_link_unref_ Link *link = userdata;
1042 int r;
1043
1044 assert(link);
1045 assert(link->network);
1046
1047 link->enslaving --;
1048
1049 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1050 return 1;
1051
1052 r = sd_rtnl_message_get_errno(m);
1053 if (r < 0 && r != -EEXIST) {
1054 log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
1055 link_enter_failed(link);
1056 return 1;
1057 } else
1058 log_link_debug(link, "joined netdev");
1059
1060 if (link->enslaving <= 0)
1061 link_joined(link);
1062
1063 return 1;
1064}
1065
1066static int link_enter_join_netdev(Link *link) {
1067 NetDev *netdev;
1068 Iterator i;
1069 int r;
1070
1071 assert(link);
1072 assert(link->network);
1073 assert(link->state == LINK_STATE_PENDING);
1074
1075 link->state = LINK_STATE_ENSLAVING;
1076
1077 link_save(link);
1078
1079 if (!link->network->bridge &&
1080 !link->network->bond &&
1081 hashmap_isempty(link->network->stacked_netdevs))
1082 return link_joined(link);
1083
1084 if (link->network->bond) {
1085 log_link_struct(link, LOG_DEBUG,
1086 "MESSAGE=%-*s: enslaving by '%s'",
1087 IFNAMSIZ,
1088 link->ifname, link->network->bond->ifname,
1089 NETDEVIF(link->network->bond),
1090 NULL);
1091
1092 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1093 if (r < 0) {
1094 log_link_struct(link, LOG_WARNING,
1095 "MESSAGE=%-*s: could not join netdev '%s': %s",
1096 IFNAMSIZ,
1097 link->ifname, link->network->bond->ifname,
1098 strerror(-r),
1099 NETDEVIF(link->network->bond),
1100 NULL);
1101 link_enter_failed(link);
1102 return r;
1103 }
1104
1105 link->enslaving ++;
1106 }
1107
1108 if (link->network->bridge) {
1109 log_link_struct(link, LOG_DEBUG,
1110 "MESSAGE=%-*s: enslaving by '%s'",
1111 IFNAMSIZ,
1112 link->ifname, link->network->bridge->ifname,
1113 NETDEVIF(link->network->bridge),
1114 NULL);
1115
1116 r = netdev_join(link->network->bridge, link,
1117 &netdev_join_handler);
1118 if (r < 0) {
1119 log_link_struct(link, LOG_WARNING,
1120 "MESSAGE=%-*s: could not join netdev '%s': %s",
1121 IFNAMSIZ,
1122 link->ifname, link->network->bridge->ifname,
1123 strerror(-r),
1124 NETDEVIF(link->network->bridge),
1125 NULL);
1126 link_enter_failed(link);
1127 return r;
1128 }
1129
1130 link->enslaving ++;
1131 }
1132
1133 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1134 log_link_struct(link, LOG_DEBUG,
1135 "MESSAGE=%-*s: enslaving by '%s'",
1136 IFNAMSIZ,
1137 link->ifname, netdev->ifname, NETDEVIF(netdev),
1138 NULL);
1139
1140 r = netdev_join(netdev, link, &netdev_join_handler);
1141 if (r < 0) {
1142 log_link_struct(link, LOG_WARNING,
1143 "MESSAGE=%-*s: could not join netdev '%s': %s",
1144 IFNAMSIZ,
1145 link->ifname, netdev->ifname,
1146 strerror(-r),
1147 NETDEVIF(netdev), NULL);
1148 link_enter_failed(link);
1149 return r;
1150 }
1151
1152 link->enslaving ++;
1153 }
1154
1155 return 0;
1156}
1157
1158static int link_configure(Link *link) {
1159 int r;
1160
1161 assert(link);
1162 assert(link->network);
1163 assert(link->state == LINK_STATE_PENDING);
1164
1165 r = link_set_bridge_fdb(link);
1166 if (r < 0)
1167 return r;
1168
1169 if (link_ipv4ll_enabled(link)) {
1170 r = ipv4ll_configure(link);
1171 if (r < 0)
1172 return r;
1173 }
1174
1175 if (link_dhcp4_enabled(link)) {
1176 r = dhcp4_configure(link);
1177 if (r < 0)
1178 return r;
1179 }
1180
1181 if (link_dhcp4_server_enabled(link)) {
1182 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1183 if (r < 0)
1184 return r;
1185
1186 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1187 if (r < 0)
1188 return r;
1189 }
1190
1191 if (link_dhcp6_enabled(link)) {
1192 r = icmp6_configure(link);
1193 if (r < 0)
1194 return r;
1195 }
1196
1197 if (link_has_carrier(link)) {
1198 r = link_acquire_conf(link);
1199 if (r < 0)
1200 return r;
1201 }
1202
1203 return link_enter_join_netdev(link);
1204}
1205
1206static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1207 void *userdata) {
1208 _cleanup_link_unref_ Link *link = userdata;
1209 Network *network;
1210 int r;
1211
1212 assert(link);
1213 assert(link->ifname);
1214 assert(link->manager);
1215
1216 if (link->state != LINK_STATE_PENDING)
1217 return 1;
1218
1219 log_link_debug(link, "link state is up-to-date");
1220
1221 r = network_get(link->manager, link->udev_device, link->ifname,
1222 &link->mac, &network);
1223 if (r == -ENOENT) {
1224 link_enter_unmanaged(link);
1225 return 1;
1226 } else if (r < 0)
1227 return r;
1228
1229 if (link->flags & IFF_LOOPBACK) {
1230 if (network->ipv4ll)
1231 log_link_debug(link, "ignoring IPv4LL for loopback link");
1232
1233 if (network->dhcp != DHCP_SUPPORT_NONE)
1234 log_link_debug(link, "ignoring DHCP clients for loopback link");
1235
1236 if (network->dhcp_server)
1237 log_link_debug(link, "ignoring DHCP server for loopback link");
1238 }
1239
1240 r = network_apply(link->manager, network, link);
1241 if (r < 0)
1242 return r;
1243
1244 r = link_configure(link);
1245 if (r < 0)
1246 return r;
1247
1248 return 1;
1249}
1250
1251int link_initialized(Link *link, struct udev_device *device) {
1252 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1253 int r;
1254
1255 assert(link);
1256 assert(link->manager);
1257 assert(link->manager->rtnl);
1258 assert(device);
1259
1260 if (link->state != LINK_STATE_PENDING)
1261 return 0;
1262
1263 if (link->udev_device)
1264 return 0;
1265
1266 log_link_debug(link, "udev initialized link");
1267
1268 link->udev_device = udev_device_ref(device);
1269
1270 /* udev has initialized the link, but we don't know if we have yet
1271 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1272 * when it returns we know that the pending NEWLINKs have already been
1273 * processed and that we are up-to-date */
1274
1275 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1276 link->ifindex);
1277 if (r < 0)
1278 return r;
1279
1280 r = sd_rtnl_call_async(link->manager->rtnl, req,
1281 link_initialized_and_synced, link, 0, NULL);
1282 if (r < 0)
1283 return r;
1284
1285 link_ref(link);
1286
1287 return 0;
1288}
1289
1290int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1291 Manager *m = userdata;
1292 Link *link = NULL;
1293 uint16_t type;
1294 _cleanup_address_free_ Address *address = NULL;
1295 Address *ad;
1296 char buf[INET6_ADDRSTRLEN];
1297 char valid_buf[FORMAT_TIMESPAN_MAX];
1298 const char *valid_str = NULL;
1299 bool address_dropped = false;
1300 int r, ifindex;
1301
1302 assert(rtnl);
1303 assert(message);
1304 assert(m);
1305
1306 if (sd_rtnl_message_is_error(message)) {
1307 r = sd_rtnl_message_get_errno(message);
1308 if (r < 0)
1309 log_warning_errno(r, "rtnl: failed to receive address: %m");
1310
1311 return 0;
1312 }
1313
1314 r = sd_rtnl_message_get_type(message, &type);
1315 if (r < 0) {
1316 log_warning("rtnl: could not get message type");
1317 return 0;
1318 }
1319
1320 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1321 if (r < 0) {
1322 log_warning_errno(r, "rtnl: could not get ifindex: %m");
1323 return 0;
1324 } else if (ifindex <= 0) {
1325 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
1326 return 0;
1327 } else {
1328 r = link_get(m, ifindex, &link);
1329 if (r < 0 || !link) {
1330 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
1331 return 0;
1332 }
1333 }
1334
1335 r = address_new_dynamic(&address);
1336 if (r < 0)
1337 return r;
1338
1339 r = sd_rtnl_message_addr_get_family(message, &address->family);
1340 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1341 log_link_warning(link,
1342 "rtnl: received address with invalid family, ignoring");
1343 return 0;
1344 }
1345
1346 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1347 if (r < 0) {
1348 log_link_warning(link,
1349 "rtnl: received address with invalid prefixlen, ignoring");
1350 return 0;
1351 }
1352
1353 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1354 if (r < 0) {
1355 log_link_warning(link,
1356 "rtnl: received address with invalid scope, ignoring");
1357 return 0;
1358 }
1359
1360 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1361 if (r < 0) {
1362 log_link_warning(link,
1363 "rtnl: received address with invalid flags, ignoring");
1364 return 0;
1365 }
1366
1367 switch (address->family) {
1368 case AF_INET:
1369 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1370 &address->in_addr.in);
1371 if (r < 0) {
1372 log_link_warning(link,
1373 "rtnl: received address without valid address, ignoring");
1374 return 0;
1375 }
1376
1377 break;
1378
1379 case AF_INET6:
1380 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1381 &address->in_addr.in6);
1382 if (r < 0) {
1383 log_link_warning(link,
1384 "rtnl: received address without valid address, ignoring");
1385 return 0;
1386 }
1387
1388 break;
1389
1390 default:
1391 assert_not_reached("invalid address family");
1392 }
1393
1394 if (!inet_ntop(address->family, &address->in_addr, buf,
1395 INET6_ADDRSTRLEN)) {
1396 log_link_warning(link, "could not print address");
1397 return 0;
1398 }
1399
1400 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1401 &address->cinfo);
1402 if (r >= 0) {
1403 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1404 valid_str = "ever";
1405 else
1406 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1407 address->cinfo.ifa_valid * USEC_PER_SEC,
1408 USEC_PER_SEC);
1409 }
1410
1411 LIST_FOREACH(addresses, ad, link->addresses) {
1412 if (address_equal(ad, address)) {
1413 LIST_REMOVE(addresses, link->addresses, ad);
1414
1415 address_free(ad);
1416
1417 address_dropped = true;
1418
1419 break;
1420 }
1421 }
1422
1423 switch (type) {
1424 case RTM_NEWADDR:
1425 if (!address_dropped)
1426 log_link_debug(link, "added address: %s/%u (valid for %s)",
1427 buf, address->prefixlen, valid_str);
1428 else
1429 log_link_debug(link, "updated address: %s/%u (valid for %s)",
1430 buf, address->prefixlen, valid_str);
1431
1432 LIST_PREPEND(addresses, link->addresses, address);
1433 address = NULL;
1434
1435 link_save(link);
1436
1437 break;
1438 case RTM_DELADDR:
1439 if (address_dropped) {
1440 log_link_debug(link, "removed address: %s/%u (valid for %s)",
1441 buf, address->prefixlen, valid_str);
1442
1443 link_save(link);
1444 } else
1445 log_link_warning(link,
1446 "removing non-existent address: %s/%u (valid for %s)",
1447 buf, address->prefixlen, valid_str);
1448
1449 break;
1450 default:
1451 assert_not_reached("Received invalid RTNL message type");
1452 }
1453
1454 return 1;
1455}
1456
1457int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1458 Link *link;
1459 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1460 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1461 int r;
1462
1463 assert(m);
1464 assert(m->rtnl);
1465 assert(message);
1466 assert(ret);
1467
1468 r = link_new(m, message, ret);
1469 if (r < 0)
1470 return r;
1471
1472 link = *ret;
1473
1474 log_link_debug(link, "link %d added", link->ifindex);
1475
1476 if (detect_container(NULL) <= 0) {
1477 /* not in a container, udev will be around */
1478 sprintf(ifindex_str, "n%d", link->ifindex);
1479 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1480 if (!device) {
1481 log_link_warning(link,
1482 "could not find udev device: %m");
1483 return -errno;
1484 }
1485
1486 if (udev_device_get_is_initialized(device) <= 0) {
1487 /* not yet ready */
1488 log_link_debug(link, "link pending udev initialization...");
1489 return 0;
1490 }
1491
1492 r = link_initialized(link, device);
1493 if (r < 0)
1494 return r;
1495 } else {
1496 /* we are calling a callback directly, so must take a ref */
1497 link_ref(link);
1498
1499 r = link_initialized_and_synced(m->rtnl, NULL, link);
1500 if (r < 0)
1501 return r;
1502 }
1503
1504 return 0;
1505}
1506
1507int link_update(Link *link, sd_rtnl_message *m) {
1508 struct ether_addr mac;
1509 const char *ifname;
1510 uint32_t mtu;
1511 bool had_carrier, carrier_gained, carrier_lost;
1512 int r;
1513
1514 assert(link);
1515 assert(link->ifname);
1516 assert(m);
1517
1518 if (link->state == LINK_STATE_LINGER) {
1519 link_ref(link);
1520 log_link_info(link, "link readded");
1521 link->state = LINK_STATE_ENSLAVING;
1522 }
1523
1524 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1525 if (r >= 0 && !streq(ifname, link->ifname)) {
1526 log_link_info(link, "renamed to %s", ifname);
1527
1528 free(link->ifname);
1529 link->ifname = strdup(ifname);
1530 if (!link->ifname)
1531 return -ENOMEM;
1532 }
1533
1534 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1535 if (r >= 0 && mtu > 0) {
1536 link->mtu = mtu;
1537 if (!link->original_mtu) {
1538 link->original_mtu = mtu;
1539 log_link_debug(link, "saved original MTU: %"
1540 PRIu32, link->original_mtu);
1541 }
1542
1543 if (link->dhcp_client) {
1544 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1545 link->mtu);
1546 if (r < 0) {
1547 log_link_warning(link,
1548 "Could not update MTU in DHCP client: %s",
1549 strerror(-r));
1550 return r;
1551 }
1552 }
1553 }
1554
1555 /* The kernel may broadcast NEWLINK messages without the MAC address
1556 set, simply ignore them. */
1557 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1558 if (r >= 0) {
1559 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1560 ETH_ALEN)) {
1561
1562 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1563 ETH_ALEN);
1564
1565 log_link_debug(link, "MAC address: "
1566 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1567 mac.ether_addr_octet[0],
1568 mac.ether_addr_octet[1],
1569 mac.ether_addr_octet[2],
1570 mac.ether_addr_octet[3],
1571 mac.ether_addr_octet[4],
1572 mac.ether_addr_octet[5]);
1573
1574 if (link->ipv4ll) {
1575 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1576 if (r < 0) {
1577 log_link_warning(link,
1578 "Could not update MAC address in IPv4LL client: %s",
1579 strerror(-r));
1580 return r;
1581 }
1582 }
1583
1584 if (link->dhcp_client) {
1585 r = sd_dhcp_client_set_mac(link->dhcp_client,
1586 (const uint8_t *) &link->mac,
1587 sizeof (link->mac),
1588 ARPHRD_ETHER);
1589 if (r < 0) {
1590 log_link_warning(link,
1591 "Could not update MAC address in DHCP client: %s",
1592 strerror(-r));
1593 return r;
1594 }
1595 }
1596
1597 if (link->dhcp6_client) {
1598 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1599 (const uint8_t *) &link->mac,
1600 sizeof (link->mac),
1601 ARPHRD_ETHER);
1602 if (r < 0) {
1603 log_link_warning(link,
1604 "Could not update MAC address in DHCPv6 client: %s",
1605 strerror(-r));
1606 return r;
1607 }
1608 }
1609 }
1610 }
1611
1612 had_carrier = link_has_carrier(link);
1613
1614 r = link_update_flags(link, m);
1615 if (r < 0)
1616 return r;
1617
1618 carrier_gained = !had_carrier && link_has_carrier(link);
1619 carrier_lost = had_carrier && !link_has_carrier(link);
1620
1621 if (carrier_gained) {
1622 log_link_info(link, "gained carrier");
1623
1624 if (link->network) {
1625 r = link_acquire_conf(link);
1626 if (r < 0) {
1627 link_enter_failed(link);
1628 return r;
1629 }
1630 }
1631 } else if (carrier_lost) {
1632 log_link_info(link, "lost carrier");
1633
1634 r = link_stop_clients(link);
1635 if (r < 0) {
1636 link_enter_failed(link);
1637 return r;
1638 }
1639 }
1640
1641 return 0;
1642}
1643
1644static void link_update_operstate(Link *link) {
1645
1646 assert(link);
1647
1648 if (link->kernel_operstate == IF_OPER_DORMANT)
1649 link->operstate = LINK_OPERSTATE_DORMANT;
1650 else if (link_has_carrier(link)) {
1651 Address *address;
1652 uint8_t scope = RT_SCOPE_NOWHERE;
1653
1654 /* if we have carrier, check what addresses we have */
1655 LIST_FOREACH(addresses, address, link->addresses) {
1656 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1657 continue;
1658
1659 if (address->scope < scope)
1660 scope = address->scope;
1661 }
1662
1663 if (scope < RT_SCOPE_SITE)
1664 /* universally accessible addresses found */
1665 link->operstate = LINK_OPERSTATE_ROUTABLE;
1666 else if (scope < RT_SCOPE_HOST)
1667 /* only link or site local addresses found */
1668 link->operstate = LINK_OPERSTATE_DEGRADED;
1669 else
1670 /* no useful addresses found */
1671 link->operstate = LINK_OPERSTATE_CARRIER;
1672 } else if (link->flags & IFF_UP)
1673 link->operstate = LINK_OPERSTATE_NO_CARRIER;
1674 else
1675 link->operstate = LINK_OPERSTATE_OFF;
1676}
1677
1678int link_save(Link *link) {
1679 _cleanup_free_ char *temp_path = NULL;
1680 _cleanup_fclose_ FILE *f = NULL;
1681 const char *admin_state, *oper_state;
1682 int r;
1683
1684 assert(link);
1685 assert(link->state_file);
1686 assert(link->lease_file);
1687 assert(link->manager);
1688
1689 link_update_operstate(link);
1690
1691 r = manager_save(link->manager);
1692 if (r < 0)
1693 return r;
1694
1695 if (link->state == LINK_STATE_LINGER) {
1696 unlink(link->state_file);
1697 return 0;
1698 }
1699
1700 admin_state = link_state_to_string(link->state);
1701 assert(admin_state);
1702
1703 oper_state = link_operstate_to_string(link->operstate);
1704 assert(oper_state);
1705
1706 r = fopen_temporary(link->state_file, &f, &temp_path);
1707 if (r < 0)
1708 return r;
1709
1710 fchmod(fileno(f), 0644);
1711
1712 fprintf(f,
1713 "# This is private data. Do not parse.\n"
1714 "ADMIN_STATE=%s\n"
1715 "OPER_STATE=%s\n",
1716 admin_state, oper_state);
1717
1718 if (link->network) {
1719 char **address, **domain;
1720 bool space;
1721
1722 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
1723
1724 fputs("DNS=", f);
1725 space = false;
1726 STRV_FOREACH(address, link->network->dns) {
1727 if (space)
1728 fputc(' ', f);
1729 fputs(*address, f);
1730 space = true;
1731 }
1732
1733 if (link->network->dhcp_dns &&
1734 link->dhcp_lease) {
1735 const struct in_addr *addresses;
1736
1737 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1738 if (r > 0) {
1739 if (space)
1740 fputc(' ', f);
1741 serialize_in_addrs(f, addresses, r);
1742 }
1743 }
1744
1745 fputs("\n", f);
1746
1747 fprintf(f, "NTP=");
1748 space = false;
1749 STRV_FOREACH(address, link->network->ntp) {
1750 if (space)
1751 fputc(' ', f);
1752 fputs(*address, f);
1753 space = true;
1754 }
1755
1756 if (link->network->dhcp_ntp &&
1757 link->dhcp_lease) {
1758 const struct in_addr *addresses;
1759
1760 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1761 if (r > 0) {
1762 if (space)
1763 fputc(' ', f);
1764 serialize_in_addrs(f, addresses, r);
1765 }
1766 }
1767
1768 fputs("\n", f);
1769
1770 fprintf(f, "DOMAINS=");
1771 space = false;
1772 STRV_FOREACH(domain, link->network->domains) {
1773 if (space)
1774 fputc(' ', f);
1775 fputs(*domain, f);
1776 space = true;
1777 }
1778
1779 if (link->network->dhcp_domains &&
1780 link->dhcp_lease) {
1781 const char *domainname;
1782
1783 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1784 if (r >= 0) {
1785 if (space)
1786 fputc(' ', f);
1787 fputs(domainname, f);
1788 }
1789 }
1790
1791 fputs("\n", f);
1792
1793 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1794 yes_no(link->network->wildcard_domain));
1795
1796 fprintf(f, "LLMNR=%s\n",
1797 llmnr_support_to_string(link->network->llmnr));
1798 }
1799
1800 if (link->dhcp_lease) {
1801 assert(link->network);
1802
1803 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
1804 if (r < 0)
1805 goto fail;
1806
1807 fprintf(f,
1808 "DHCP_LEASE=%s\n",
1809 link->lease_file);
1810 } else
1811 unlink(link->lease_file);
1812
1813 r = fflush_and_check(f);
1814 if (r < 0)
1815 goto fail;
1816
1817 if (rename(temp_path, link->state_file) < 0) {
1818 r = -errno;
1819 goto fail;
1820 }
1821
1822 return 0;
1823fail:
1824 log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1825 unlink(link->state_file);
1826 unlink(temp_path);
1827 return r;
1828}
1829
1830static const char* const link_state_table[_LINK_STATE_MAX] = {
1831 [LINK_STATE_PENDING] = "pending",
1832 [LINK_STATE_ENSLAVING] = "configuring",
1833 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1834 [LINK_STATE_SETTING_ROUTES] = "configuring",
1835 [LINK_STATE_CONFIGURED] = "configured",
1836 [LINK_STATE_UNMANAGED] = "unmanaged",
1837 [LINK_STATE_FAILED] = "failed",
1838 [LINK_STATE_LINGER] = "linger",
1839};
1840
1841DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1842
1843static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1844 [LINK_OPERSTATE_OFF] = "off",
1845 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
1846 [LINK_OPERSTATE_DORMANT] = "dormant",
1847 [LINK_OPERSTATE_CARRIER] = "carrier",
1848 [LINK_OPERSTATE_DEGRADED] = "degraded",
1849 [LINK_OPERSTATE_ROUTABLE] = "routable",
1850};
1851
1852DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);