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