]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/network/networkd-link.c
build: colorize gcc only if on tty
[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_warning_link(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_debug_link(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_debug_link(link,
140 "unknown link flags gained: %#.5x (ignoring)",
141 unknown_flags_added);
142
143 if (unknown_flags_removed)
144 log_debug_link(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_debug_link(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, 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_debug_link(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_debug_link(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_warning_link(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_warning_link(link, "Could not stop IPv4 link-local: %s",
342 strerror(-r));
343 r = k;
344 }
345 }
346
347 if (link->dhcp_server) {
348 k = sd_dhcp_server_stop(link->dhcp_server);
349 if (k < 0) {
350 log_warning_link(link, "Could not stop DHCPv4 server: %s",
351 strerror(-r));
352 r = k;
353 }
354 }
355
356 if(link->icmp6_router_discovery) {
357
358 if (link->dhcp6_client) {
359 k = sd_dhcp6_client_stop(link->dhcp6_client);
360 if (k < 0) {
361 log_warning_link(link, "Could not stop DHCPv6 client: %s",
362 strerror(-r));
363 r = k;
364 }
365 }
366
367 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
368 if (k < 0) {
369 log_warning_link(link,
370 "Could not stop ICMPv6 router discovery: %s",
371 strerror(-r));
372 r = k;
373 }
374 }
375
376 return r;
377}
378
379void link_enter_failed(Link *link) {
380 assert(link);
381
382 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
383 return;
384
385 log_warning_link(link, "failed");
386
387 link->state = LINK_STATE_FAILED;
388
389 link_stop_clients(link);
390
391 link_save(link);
392}
393
394static Address* link_find_dhcp_server_address(Link *link) {
395 Address *address;
396
397 assert(link);
398 assert(link->network);
399
400 /* The the first statically configured address if there is any */
401 LIST_FOREACH(addresses, address, link->network->static_addresses) {
402
403 if (address->family != AF_INET)
404 continue;
405
406 if (in_addr_is_null(address->family, &address->in_addr))
407 continue;
408
409 return address;
410 }
411
412 /* If that didn't work, find a suitable address we got from the pool */
413 LIST_FOREACH(addresses, address, link->pool_addresses) {
414 if (address->family != AF_INET)
415 continue;
416
417 return address;
418 }
419
420 return NULL;
421}
422
423static int link_enter_configured(Link *link) {
424 int r;
425
426 assert(link);
427 assert(link->network);
428 assert(link->state == LINK_STATE_SETTING_ROUTES);
429
430 if (link_dhcp4_server_enabled(link) &&
431 !sd_dhcp_server_is_running(link->dhcp_server)) {
432 struct in_addr pool_start;
433 Address *address;
434
435 address = link_find_dhcp_server_address(link);
436 if (!address) {
437 log_warning_link(link,
438 "Failed to find suitable address for DHCPv4 server instance.");
439 link_enter_failed(link);
440 return 0;
441 }
442
443 log_debug_link(link, "offering DHCPv4 leases");
444
445 r = sd_dhcp_server_set_address(link->dhcp_server,
446 &address->in_addr.in,
447 address->prefixlen);
448 if (r < 0)
449 return r;
450
451 /* offer 32 addresses starting from the address following the server address */
452 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
453 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
454 &pool_start, 32);
455 if (r < 0)
456 return r;
457
458 /* TODO:
459 r = sd_dhcp_server_set_router(link->dhcp_server,
460 &main_address->in_addr.in);
461 if (r < 0)
462 return r;
463
464 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
465 main_address->prefixlen);
466 if (r < 0)
467 return r;
468 */
469
470 r = sd_dhcp_server_start(link->dhcp_server);
471 if (r < 0) {
472 log_warning_link(link, "could not start DHCPv4 server "
473 "instance: %s", strerror(-r));
474
475 link_enter_failed(link);
476
477 return 0;
478 }
479 }
480
481 log_info_link(link, "link configured");
482
483 link->state = LINK_STATE_CONFIGURED;
484
485 link_save(link);
486
487 return 0;
488}
489
490void link_client_handler(Link *link) {
491 assert(link);
492 assert(link->network);
493
494 if (!link->static_configured)
495 return;
496
497 if (link_ipv4ll_enabled(link))
498 if (!link->ipv4ll_address ||
499 !link->ipv4ll_route)
500 return;
501
502 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
503 return;
504
505 if (link->state != LINK_STATE_CONFIGURED)
506 link_enter_configured(link);
507
508 return;
509}
510
511static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
512 _cleanup_link_unref_ Link *link = userdata;
513 int r;
514
515 assert(link->link_messages > 0);
516 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
517 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
518 LINK_STATE_LINGER));
519
520 link->link_messages --;
521
522 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
523 return 1;
524
525 r = sd_rtnl_message_get_errno(m);
526 if (r < 0 && r != -EEXIST)
527 log_struct_link(LOG_WARNING, link,
528 "MESSAGE=%-*s: could not set route: %s",
529 IFNAMSIZ,
530 link->ifname, strerror(-r),
531 "ERRNO=%d", -r,
532 NULL);
533
534 if (link->link_messages == 0) {
535 log_debug_link(link, "routes set");
536 link->static_configured = true;
537 link_client_handler(link);
538 }
539
540 return 1;
541}
542
543static int link_enter_set_routes(Link *link) {
544 Route *rt;
545 int r;
546
547 assert(link);
548 assert(link->network);
549 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
550
551 link->state = LINK_STATE_SETTING_ROUTES;
552
553 LIST_FOREACH(routes, rt, link->network->static_routes) {
554 r = route_configure(rt, link, &route_handler);
555 if (r < 0) {
556 log_warning_link(link,
557 "could not set routes: %s",
558 strerror(-r));
559 link_enter_failed(link);
560 return r;
561 }
562
563 link->link_messages ++;
564 }
565
566 if (link->link_messages == 0) {
567 link->static_configured = true;
568 link_client_handler(link);
569 } else
570 log_debug_link(link, "setting routes");
571
572 return 0;
573}
574
575int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
576 _cleanup_link_unref_ Link *link = userdata;
577 int r;
578
579 assert(m);
580 assert(link);
581 assert(link->ifname);
582
583 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
584 return 1;
585
586 r = sd_rtnl_message_get_errno(m);
587 if (r < 0 && r != -ESRCH)
588 log_struct_link(LOG_WARNING, link,
589 "MESSAGE=%-*s: could not drop route: %s",
590 IFNAMSIZ,
591 link->ifname, strerror(-r),
592 "ERRNO=%d", -r,
593 NULL);
594
595 return 1;
596}
597
598int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
599 _cleanup_link_unref_ Link *link = userdata;
600 int r;
601
602 assert(rtnl);
603 assert(m);
604 assert(link);
605 assert(link->manager);
606
607 for (; m; m = sd_rtnl_message_next(m)) {
608 r = sd_rtnl_message_get_errno(m);
609 if (r < 0) {
610 log_debug_link(link, "getting address failed: %s",
611 strerror(-r));
612 continue;
613 }
614
615 r = link_rtnl_process_address(rtnl, m, link->manager);
616 if (r < 0)
617 log_warning_link(link, "could not process address: %s",
618 strerror(-r));
619 }
620
621 return 1;
622}
623
624static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
625 _cleanup_link_unref_ Link *link = userdata;
626 int r;
627
628 assert(rtnl);
629 assert(m);
630 assert(link);
631 assert(link->ifname);
632 assert(link->link_messages > 0);
633 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
634 LINK_STATE_FAILED, LINK_STATE_LINGER));
635
636 link->link_messages --;
637
638 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
639 return 1;
640
641 r = sd_rtnl_message_get_errno(m);
642 if (r < 0 && r != -EEXIST)
643 log_struct_link(LOG_WARNING, link,
644 "MESSAGE=%-*s: could not set address: %s",
645 IFNAMSIZ,
646 link->ifname, strerror(-r),
647 "ERRNO=%d", -r,
648 NULL);
649 else if (r >= 0) {
650 /* calling handler directly so take a ref */
651 link_ref(link);
652 link_get_address_handler(rtnl, m, link);
653 }
654
655 if (link->link_messages == 0) {
656 log_debug_link(link, "addresses set");
657 link_enter_set_routes(link);
658 }
659
660 return 1;
661}
662
663static int link_enter_set_addresses(Link *link) {
664 Address *ad;
665 int r;
666
667 assert(link);
668 assert(link->network);
669 assert(link->state != _LINK_STATE_INVALID);
670
671 link->state = LINK_STATE_SETTING_ADDRESSES;
672
673 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
674 r = address_configure(ad, link, &address_handler);
675 if (r < 0) {
676 log_warning_link(link,
677 "could not set addresses: %s",
678 strerror(-r));
679 link_enter_failed(link);
680 return r;
681 }
682
683 link->link_messages ++;
684 }
685
686 if (link->link_messages == 0) {
687 link_enter_set_routes(link);
688 } else
689 log_debug_link(link, "setting addresses");
690
691 return 0;
692}
693
694int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
695 _cleanup_link_unref_ Link *link = userdata;
696 int r;
697
698 assert(m);
699 assert(link);
700 assert(link->ifname);
701
702 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
703 return 1;
704
705 r = sd_rtnl_message_get_errno(m);
706 if (r < 0 && r != -EADDRNOTAVAIL)
707 log_struct_link(LOG_WARNING, link,
708 "MESSAGE=%-*s: could not drop address: %s",
709 IFNAMSIZ,
710 link->ifname, strerror(-r),
711 "ERRNO=%d", -r,
712 NULL);
713
714 return 1;
715}
716
717static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
718 sd_bus_error *ret_error) {
719 _cleanup_link_unref_ Link *link = userdata;
720 int r;
721
722 assert(link);
723
724 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
725 return 1;
726
727 r = sd_bus_message_get_errno(m);
728 if (r < 0)
729 r = -r;
730 if (r > 0)
731 log_warning_link(link, "Could not set hostname: %s",
732 strerror(r));
733
734 return 1;
735}
736
737int link_set_hostname(Link *link, const char *hostname) {
738 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
739 int r = 0;
740
741 assert(link);
742 assert(link->manager);
743 assert(hostname);
744
745 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
746
747 if (!link->manager->bus) {
748 /* TODO: replace by assert when we can rely on kdbus */
749 log_info_link(link,
750 "Not connected to system bus, ignoring transient hostname.");
751 return 0;
752 }
753
754 r = sd_bus_message_new_method_call(
755 link->manager->bus,
756 &m,
757 "org.freedesktop.hostname1",
758 "/org/freedesktop/hostname1",
759 "org.freedesktop.hostname1",
760 "SetHostname");
761 if (r < 0)
762 return r;
763
764 r = sd_bus_message_append(m, "sb", hostname, false);
765 if (r < 0)
766 return r;
767
768 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
769 link, 0);
770 if (r < 0) {
771 log_error_link(link, "Could not set transient hostname: %s",
772 strerror(-r));
773 return r;
774 }
775
776 link_ref(link);
777
778 return 0;
779}
780
781static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
782 _cleanup_link_unref_ Link *link = userdata;
783 int r;
784
785 assert(m);
786 assert(link);
787 assert(link->ifname);
788
789 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
790 return 1;
791
792 r = sd_rtnl_message_get_errno(m);
793 if (r < 0)
794 log_struct_link(LOG_WARNING, link,
795 "MESSAGE=%-*s: could not set MTU: %s",
796 IFNAMSIZ, link->ifname, strerror(-r),
797 "ERRNO=%d", -r,
798 NULL);
799
800 return 1;
801}
802
803int link_set_mtu(Link *link, uint32_t mtu) {
804 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
805 int r;
806
807 assert(link);
808 assert(link->manager);
809 assert(link->manager->rtnl);
810
811 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
812
813 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
814 RTM_SETLINK, link->ifindex);
815 if (r < 0) {
816 log_error_link(link, "Could not allocate RTM_SETLINK message");
817 return r;
818 }
819
820 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
821 if (r < 0) {
822 log_error_link(link, "Could not append MTU: %s", strerror(-r));
823 return r;
824 }
825
826 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
827 0, NULL);
828 if (r < 0) {
829 log_error_link(link,
830 "Could not send rtnetlink message: %s",
831 strerror(-r));
832 return r;
833 }
834
835 link_ref(link);
836
837 return 0;
838}
839
840static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
841 Link *link = userdata;
842
843 assert(link);
844 assert(link->network);
845 assert(link->manager);
846
847 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
848 return;
849
850 switch(event) {
851 case DHCP6_EVENT_STOP:
852 case DHCP6_EVENT_RESEND_EXPIRE:
853 case DHCP6_EVENT_RETRANS_MAX:
854 case DHCP6_EVENT_IP_ACQUIRE:
855 log_debug_link(link, "DHCPv6 event %d", event);
856
857 break;
858
859 default:
860 if (event < 0)
861 log_warning_link(link, "DHCPv6 error: %s",
862 strerror(-event));
863 else
864 log_warning_link(link, "DHCPv6 unknown event: %d",
865 event);
866 return;
867 }
868}
869
870static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
871 Link *link = userdata;
872 int r;
873
874 assert(link);
875 assert(link->network);
876 assert(link->manager);
877
878 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
879 return;
880
881 switch(event) {
882 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
883 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
884 return;
885
886 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
887 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
888 break;
889
890 default:
891 if (event < 0)
892 log_warning_link(link, "ICMPv6 error: %s",
893 strerror(-event));
894 else
895 log_warning_link(link, "ICMPv6 unknown event: %d",
896 event);
897
898 return;
899 }
900
901 if (link->dhcp6_client)
902 return;
903
904 r = sd_dhcp6_client_new(&link->dhcp6_client);
905 if (r < 0)
906 return;
907
908 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
909 if (r < 0) {
910 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
911 return;
912 }
913
914 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
915 if (r < 0) {
916 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
917 return;
918 }
919
920 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
921 if (r < 0) {
922 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
923 return;
924 }
925
926 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
927 link);
928 if (r < 0) {
929 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
930 return;
931 }
932
933 r = sd_dhcp6_client_start(link->dhcp6_client);
934 if (r < 0)
935 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
936}
937
938static int link_acquire_conf(Link *link) {
939 int r;
940
941 assert(link);
942 assert(link->network);
943 assert(link->manager);
944 assert(link->manager->event);
945
946 if (link_ipv4ll_enabled(link)) {
947 assert(link->ipv4ll);
948
949 log_debug_link(link, "acquiring IPv4 link-local address");
950
951 r = sd_ipv4ll_start(link->ipv4ll);
952 if (r < 0) {
953 log_warning_link(link, "could not acquire IPv4 "
954 "link-local address");
955 return r;
956 }
957 }
958
959 if (link_dhcp4_enabled(link)) {
960 assert(link->dhcp_client);
961
962 log_debug_link(link, "acquiring DHCPv4 lease");
963
964 r = sd_dhcp_client_start(link->dhcp_client);
965 if (r < 0) {
966 log_warning_link(link, "could not acquire DHCPv4 "
967 "lease");
968 return r;
969 }
970 }
971
972 if (link_dhcp6_enabled(link)) {
973 assert(link->icmp6_router_discovery);
974
975 log_debug_link(link, "discovering IPv6 routers");
976
977 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
978 if (r < 0) {
979 log_warning_link(link,
980 "could not start IPv6 router discovery");
981 return r;
982 }
983 }
984
985 return 0;
986}
987
988bool link_has_carrier(Link *link) {
989 /* see Documentation/networking/operstates.txt in the kernel sources */
990
991 if (link->kernel_operstate == IF_OPER_UP)
992 return true;
993
994 if (link->kernel_operstate == IF_OPER_UNKNOWN)
995 /* operstate may not be implemented, so fall back to flags */
996 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
997 return true;
998
999 return false;
1000}
1001
1002static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1003 _cleanup_link_unref_ Link *link = userdata;
1004 int r;
1005
1006 assert(link);
1007
1008 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1009 return 1;
1010
1011 r = sd_rtnl_message_get_errno(m);
1012 if (r < 0) {
1013 /* we warn but don't fail the link, as it may
1014 be brought up later */
1015 log_struct_link(LOG_WARNING, link,
1016 "MESSAGE=%-*s: could not bring up interface: %s",
1017 IFNAMSIZ,
1018 link->ifname, strerror(-r),
1019 "ERRNO=%d", -r,
1020 NULL);
1021 }
1022
1023 return 1;
1024}
1025
1026static int link_up(Link *link) {
1027 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1028 int r;
1029
1030 assert(link);
1031 assert(link->manager);
1032 assert(link->manager->rtnl);
1033
1034 log_debug_link(link, "bringing link up");
1035
1036 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1037 RTM_SETLINK, link->ifindex);
1038 if (r < 0) {
1039 log_error_link(link, "Could not allocate RTM_SETLINK message");
1040 return r;
1041 }
1042
1043 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1044 if (r < 0) {
1045 log_error_link(link, "Could not set link flags: %s",
1046 strerror(-r));
1047 return r;
1048 }
1049
1050 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1051 0, NULL);
1052 if (r < 0) {
1053 log_error_link(link,
1054 "Could not send rtnetlink message: %s",
1055 strerror(-r));
1056 return r;
1057 }
1058
1059 link_ref(link);
1060
1061 return 0;
1062}
1063
1064static int link_joined(Link *link) {
1065 int r;
1066
1067 assert(link);
1068 assert(link->network);
1069
1070 if (!(link->flags & IFF_UP)) {
1071 r = link_up(link);
1072 if (r < 0) {
1073 link_enter_failed(link);
1074 return r;
1075 }
1076 }
1077
1078 return link_enter_set_addresses(link);
1079}
1080
1081static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1082 void *userdata) {
1083 _cleanup_link_unref_ Link *link = userdata;
1084 int r;
1085
1086 assert(link);
1087 assert(link->network);
1088
1089 link->enslaving --;
1090
1091 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1092 return 1;
1093
1094 r = sd_rtnl_message_get_errno(m);
1095 if (r < 0 && r != -EEXIST) {
1096 log_struct_link(LOG_ERR, link,
1097 "MESSAGE=%-*s: could not join netdev: %s",
1098 IFNAMSIZ,
1099 link->ifname, strerror(-r),
1100 "ERRNO=%d", -r,
1101 NULL);
1102 link_enter_failed(link);
1103 return 1;
1104 } else
1105 log_debug_link(link, "joined netdev");
1106
1107 if (link->enslaving <= 0)
1108 link_joined(link);
1109
1110 return 1;
1111}
1112
1113static int link_enter_join_netdev(Link *link) {
1114 NetDev *netdev;
1115 Iterator i;
1116 int r;
1117
1118 assert(link);
1119 assert(link->network);
1120 assert(link->state == LINK_STATE_PENDING);
1121
1122 link->state = LINK_STATE_ENSLAVING;
1123
1124 link_save(link);
1125
1126 if (!link->network->bridge &&
1127 !link->network->bond &&
1128 hashmap_isempty(link->network->stacked_netdevs))
1129 return link_joined(link);
1130
1131 if (link->network->bond) {
1132 log_struct_link(LOG_DEBUG, link,
1133 "MESSAGE=%-*s: enslaving by '%s'",
1134 IFNAMSIZ,
1135 link->ifname, link->network->bond->ifname,
1136 NETDEVIF(link->network->bond),
1137 NULL);
1138
1139 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1140 if (r < 0) {
1141 log_struct_link(LOG_WARNING, link,
1142 "MESSAGE=%-*s: could not join netdev '%s': %s",
1143 IFNAMSIZ,
1144 link->ifname, link->network->bond->ifname,
1145 strerror(-r),
1146 NETDEVIF(link->network->bond),
1147 NULL);
1148 link_enter_failed(link);
1149 return r;
1150 }
1151
1152 link->enslaving ++;
1153 }
1154
1155 if (link->network->bridge) {
1156 log_struct_link(LOG_DEBUG, link,
1157 "MESSAGE=%-*s: enslaving by '%s'",
1158 IFNAMSIZ,
1159 link->ifname, link->network->bridge->ifname,
1160 NETDEVIF(link->network->bridge),
1161 NULL);
1162
1163 r = netdev_join(link->network->bridge, link,
1164 &netdev_join_handler);
1165 if (r < 0) {
1166 log_struct_link(LOG_WARNING, link,
1167 "MESSAGE=%-*s: could not join netdev '%s': %s",
1168 IFNAMSIZ,
1169 link->ifname, link->network->bridge->ifname,
1170 strerror(-r),
1171 NETDEVIF(link->network->bridge),
1172 NULL);
1173 link_enter_failed(link);
1174 return r;
1175 }
1176
1177 link->enslaving ++;
1178 }
1179
1180 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1181 log_struct_link(LOG_DEBUG, link,
1182 "MESSAGE=%-*s: enslaving by '%s'",
1183 IFNAMSIZ,
1184 link->ifname, netdev->ifname, NETDEVIF(netdev),
1185 NULL);
1186
1187 r = netdev_join(netdev, link, &netdev_join_handler);
1188 if (r < 0) {
1189 log_struct_link(LOG_WARNING, link,
1190 "MESSAGE=%-*s: could not join netdev '%s': %s",
1191 IFNAMSIZ,
1192 link->ifname, netdev->ifname,
1193 strerror(-r),
1194 NETDEVIF(netdev), NULL);
1195 link_enter_failed(link);
1196 return r;
1197 }
1198
1199 link->enslaving ++;
1200 }
1201
1202 return 0;
1203}
1204
1205static int link_configure(Link *link) {
1206 int r;
1207
1208 assert(link);
1209 assert(link->network);
1210 assert(link->state == LINK_STATE_PENDING);
1211
1212 if (link_ipv4ll_enabled(link)) {
1213 r = ipv4ll_configure(link);
1214 if (r < 0)
1215 return r;
1216 }
1217
1218 if (link_dhcp4_enabled(link)) {
1219 r = dhcp4_configure(link);
1220 if (r < 0)
1221 return r;
1222 }
1223
1224 if (link_dhcp4_server_enabled(link)) {
1225 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1226 if (r < 0)
1227 return r;
1228
1229 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1230 if (r < 0)
1231 return r;
1232 }
1233
1234 if (link_dhcp6_enabled(link)) {
1235 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1236 if (r < 0)
1237 return r;
1238
1239 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1240 NULL, 0);
1241 if (r < 0)
1242 return r;
1243
1244 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1245 &link->mac);
1246 if (r < 0)
1247 return r;
1248
1249 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1250 link->ifindex);
1251 if (r < 0)
1252 return r;
1253
1254 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1255 icmp6_router_handler, link);
1256 if (r < 0)
1257 return r;
1258 }
1259
1260 if (link_has_carrier(link)) {
1261 r = link_acquire_conf(link);
1262 if (r < 0)
1263 return r;
1264 }
1265
1266 return link_enter_join_netdev(link);
1267}
1268
1269static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1270 void *userdata) {
1271 _cleanup_link_unref_ Link *link = userdata;
1272 Network *network;
1273 int r;
1274
1275 assert(link);
1276 assert(link->ifname);
1277 assert(link->manager);
1278
1279 if (link->state != LINK_STATE_PENDING)
1280 return 1;
1281
1282 log_debug_link(link, "link state is up-to-date");
1283
1284 r = network_get(link->manager, link->udev_device, link->ifname,
1285 &link->mac, &network);
1286 if (r == -ENOENT) {
1287 link_enter_unmanaged(link);
1288 return 1;
1289 } else if (r < 0)
1290 return r;
1291
1292 if (link->flags & IFF_LOOPBACK) {
1293 if (network->ipv4ll)
1294 log_debug_link(link, "ignoring IPv4LL for loopback link");
1295
1296 if (network->dhcp != DHCP_SUPPORT_NONE)
1297 log_debug_link(link, "ignoring DHCP clients for loopback link");
1298
1299 if (network->dhcp_server)
1300 log_debug_link(link, "ignoring DHCP server for loopback link");
1301 }
1302
1303 r = network_apply(link->manager, network, link);
1304 if (r < 0)
1305 return r;
1306
1307 r = link_configure(link);
1308 if (r < 0)
1309 return r;
1310
1311 return 1;
1312}
1313
1314int link_initialized(Link *link, struct udev_device *device) {
1315 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1316 int r;
1317
1318 assert(link);
1319 assert(link->manager);
1320 assert(link->manager->rtnl);
1321 assert(device);
1322
1323 if (link->state != LINK_STATE_PENDING)
1324 return 0;
1325
1326 if (link->udev_device)
1327 return 0;
1328
1329 log_debug_link(link, "udev initialized link");
1330
1331 link->udev_device = udev_device_ref(device);
1332
1333 /* udev has initialized the link, but we don't know if we have yet
1334 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1335 * when it returns we know that the pending NEWLINKs have already been
1336 * processed and that we are up-to-date */
1337
1338 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1339 link->ifindex);
1340 if (r < 0)
1341 return r;
1342
1343 r = sd_rtnl_call_async(link->manager->rtnl, req,
1344 link_initialized_and_synced, link, 0, NULL);
1345 if (r < 0)
1346 return r;
1347
1348 link_ref(link);
1349
1350 return 0;
1351}
1352
1353int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
1354 void *userdata) {
1355 Manager *m = userdata;
1356 Link *link = NULL;
1357 uint16_t type;
1358 _cleanup_address_free_ Address *address = NULL;
1359 Address *ad;
1360 char buf[INET6_ADDRSTRLEN];
1361 char valid_buf[FORMAT_TIMESPAN_MAX];
1362 const char *valid_str = NULL;
1363 bool address_dropped = false;
1364 int r, ifindex;
1365
1366 assert(rtnl);
1367 assert(message);
1368 assert(m);
1369
1370 r = sd_rtnl_message_get_type(message, &type);
1371 if (r < 0) {
1372 log_warning("rtnl: could not get message type");
1373 return 0;
1374 }
1375
1376 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1377 if (r < 0 || ifindex <= 0) {
1378 log_warning("rtnl: received address message without valid ifindex, ignoring");
1379 return 0;
1380 } else {
1381 r = link_get(m, ifindex, &link);
1382 if (r < 0 || !link) {
1383 log_warning("rtnl: received address for a nonexistent link (%d), ignoring", ifindex);
1384 return 0;
1385 }
1386 }
1387
1388 r = address_new_dynamic(&address);
1389 if (r < 0)
1390 return r;
1391
1392 r = sd_rtnl_message_addr_get_family(message, &address->family);
1393 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1394 log_warning_link(link,
1395 "rtnl: received address with invalid family, ignoring");
1396 return 0;
1397 }
1398
1399 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1400 if (r < 0) {
1401 log_warning_link(link,
1402 "rtnl: received address with invalid prefixlen, ignoring");
1403 return 0;
1404 }
1405
1406 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1407 if (r < 0) {
1408 log_warning_link(link,
1409 "rtnl: received address with invalid scope, ignoring");
1410 return 0;
1411 }
1412
1413 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1414 if (r < 0) {
1415 log_warning_link(link,
1416 "rtnl: received address with invalid flags, ignoring");
1417 return 0;
1418 }
1419
1420 switch (address->family) {
1421 case AF_INET:
1422 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1423 &address->in_addr.in);
1424 if (r < 0) {
1425 log_warning_link(link,
1426 "rtnl: received address without valid address, ignoring");
1427 return 0;
1428 }
1429
1430 break;
1431
1432 case AF_INET6:
1433 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1434 &address->in_addr.in6);
1435 if (r < 0) {
1436 log_warning_link(link,
1437 "rtnl: received address without valid address, ignoring");
1438 return 0;
1439 }
1440
1441 break;
1442
1443 default:
1444 assert_not_reached("invalid address family");
1445 }
1446
1447 if (!inet_ntop(address->family, &address->in_addr, buf,
1448 INET6_ADDRSTRLEN)) {
1449 log_warning_link(link, "could not print address");
1450 return 0;
1451 }
1452
1453 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1454 &address->cinfo);
1455 if (r >= 0) {
1456 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1457 valid_str = "ever";
1458 else
1459 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1460 address->cinfo.ifa_valid * USEC_PER_SEC,
1461 USEC_PER_SEC);
1462 }
1463
1464 LIST_FOREACH(addresses, ad, link->addresses) {
1465 if (address_equal(ad, address)) {
1466 LIST_REMOVE(addresses, link->addresses, ad);
1467
1468 address_free(ad);
1469
1470 address_dropped = true;
1471
1472 break;
1473 }
1474 }
1475
1476 switch (type) {
1477 case RTM_NEWADDR:
1478 if (!address_dropped)
1479 log_debug_link(link, "added address: %s/%u (valid for %s)",
1480 buf, address->prefixlen,
1481 strna(valid_str));
1482 else
1483 log_debug_link(link, "updated address: %s/%u (valid for %s)",
1484 buf, address->prefixlen,
1485 strna(valid_str));
1486
1487 LIST_PREPEND(addresses, link->addresses, address);
1488 address = NULL;
1489
1490 link_save(link);
1491
1492 break;
1493 case RTM_DELADDR:
1494 if (address_dropped) {
1495 log_debug_link(link, "removed address: %s/%u (valid for %s)",
1496 buf, address->prefixlen,
1497 strna(valid_str));
1498
1499 link_save(link);
1500 } else
1501 log_warning_link(link,
1502 "removing non-existent address: %s/%u (valid for %s)",
1503 buf, address->prefixlen,
1504 strna(valid_str));
1505
1506 break;
1507 default:
1508 assert_not_reached("Received invalid RTNL message type");
1509 }
1510
1511 return 1;
1512}
1513
1514int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1515 Link *link;
1516 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1517 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1518 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1519 int r;
1520
1521 assert(m);
1522 assert(m->rtnl);
1523 assert(message);
1524 assert(ret);
1525
1526 r = link_new(m, message, ret);
1527 if (r < 0)
1528 return r;
1529
1530 link = *ret;
1531
1532 log_debug_link(link, "link %d added", link->ifindex);
1533
1534 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
1535 0);
1536 if (r < 0)
1537 return r;
1538
1539 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
1540 NULL);
1541 if (r < 0)
1542 return r;
1543
1544 link_ref(link);
1545
1546 if (detect_container(NULL) <= 0) {
1547 /* not in a container, udev will be around */
1548 sprintf(ifindex_str, "n%d", link->ifindex);
1549 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1550 if (!device) {
1551 log_warning_link(link,
1552 "could not find udev device: %m");
1553 return -errno;
1554 }
1555
1556 if (udev_device_get_is_initialized(device) <= 0) {
1557 /* not yet ready */
1558 log_debug_link(link, "link pending udev initialization...");
1559 return 0;
1560 }
1561
1562 r = link_initialized(link, device);
1563 if (r < 0)
1564 return r;
1565 } else {
1566 /* we are calling a callback directly, so must take a ref */
1567 link_ref(link);
1568
1569 r = link_initialized_and_synced(m->rtnl, NULL, link);
1570 if (r < 0)
1571 return r;
1572 }
1573
1574 return 0;
1575}
1576
1577int link_update(Link *link, sd_rtnl_message *m) {
1578 struct ether_addr mac;
1579 const char *ifname;
1580 uint32_t mtu;
1581 bool had_carrier, carrier_gained, carrier_lost;
1582 int r;
1583
1584 assert(link);
1585 assert(link->ifname);
1586 assert(m);
1587
1588 if (link->state == LINK_STATE_LINGER) {
1589 link_ref(link);
1590 log_info_link(link, "link readded");
1591 link->state = LINK_STATE_ENSLAVING;
1592 }
1593
1594 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1595 if (r >= 0 && !streq(ifname, link->ifname)) {
1596 log_info_link(link, "renamed to %s", ifname);
1597
1598 free(link->ifname);
1599 link->ifname = strdup(ifname);
1600 if (!link->ifname)
1601 return -ENOMEM;
1602 }
1603
1604 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1605 if (r >= 0 && mtu > 0) {
1606 link->mtu = mtu;
1607 if (!link->original_mtu) {
1608 link->original_mtu = mtu;
1609 log_debug_link(link, "saved original MTU: %"
1610 PRIu32, link->original_mtu);
1611 }
1612
1613 if (link->dhcp_client) {
1614 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1615 link->mtu);
1616 if (r < 0) {
1617 log_warning_link(link,
1618 "Could not update MTU in DHCP client: %s",
1619 strerror(-r));
1620 return r;
1621 }
1622 }
1623 }
1624
1625 /* The kernel may broadcast NEWLINK messages without the MAC address
1626 set, simply ignore them. */
1627 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1628 if (r >= 0) {
1629 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1630 ETH_ALEN)) {
1631
1632 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1633 ETH_ALEN);
1634
1635 log_debug_link(link, "MAC address: "
1636 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1637 mac.ether_addr_octet[0],
1638 mac.ether_addr_octet[1],
1639 mac.ether_addr_octet[2],
1640 mac.ether_addr_octet[3],
1641 mac.ether_addr_octet[4],
1642 mac.ether_addr_octet[5]);
1643
1644 if (link->ipv4ll) {
1645 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1646 if (r < 0) {
1647 log_warning_link(link,
1648 "Could not update MAC address in IPv4LL client: %s",
1649 strerror(-r));
1650 return r;
1651 }
1652 }
1653
1654 if (link->dhcp_client) {
1655 r = sd_dhcp_client_set_mac(link->dhcp_client,
1656 &link->mac);
1657 if (r < 0) {
1658 log_warning_link(link,
1659 "Could not update MAC address in DHCP client: %s",
1660 strerror(-r));
1661 return r;
1662 }
1663 }
1664
1665 if (link->dhcp6_client) {
1666 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1667 &link->mac);
1668 if (r < 0) {
1669 log_warning_link(link,
1670 "Could not update MAC address in DHCPv6 client: %s",
1671 strerror(-r));
1672 return r;
1673 }
1674 }
1675 }
1676 }
1677
1678 had_carrier = link_has_carrier(link);
1679
1680 r = link_update_flags(link, m);
1681 if (r < 0)
1682 return r;
1683
1684 carrier_gained = !had_carrier && link_has_carrier(link);
1685 carrier_lost = had_carrier && !link_has_carrier(link);
1686
1687 if (carrier_gained) {
1688 log_info_link(link, "gained carrier");
1689
1690 if (link->network) {
1691 r = link_acquire_conf(link);
1692 if (r < 0) {
1693 link_enter_failed(link);
1694 return r;
1695 }
1696 }
1697 } else if (carrier_lost) {
1698 log_info_link(link, "lost carrier");
1699
1700 r = link_stop_clients(link);
1701 if (r < 0) {
1702 link_enter_failed(link);
1703 return r;
1704 }
1705 }
1706
1707 return 0;
1708}
1709
1710static void link_update_operstate(Link *link) {
1711
1712 assert(link);
1713
1714 if (link->kernel_operstate == IF_OPER_DORMANT)
1715 link->operstate = LINK_OPERSTATE_DORMANT;
1716 else if (link_has_carrier(link)) {
1717 Address *address;
1718 uint8_t scope = RT_SCOPE_NOWHERE;
1719
1720 /* if we have carrier, check what addresses we have */
1721 LIST_FOREACH(addresses, address, link->addresses) {
1722 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1723 continue;
1724
1725 if (address->scope < scope)
1726 scope = address->scope;
1727 }
1728
1729 if (scope < RT_SCOPE_SITE)
1730 /* universally accessible addresses found */
1731 link->operstate = LINK_OPERSTATE_ROUTABLE;
1732 else if (scope < RT_SCOPE_HOST)
1733 /* only link or site local addresses found */
1734 link->operstate = LINK_OPERSTATE_DEGRADED;
1735 else
1736 /* no useful addresses found */
1737 link->operstate = LINK_OPERSTATE_CARRIER;
1738 } else if (link->flags & IFF_UP)
1739 link->operstate = LINK_OPERSTATE_NO_CARRIER;
1740 else
1741 link->operstate = LINK_OPERSTATE_OFF;
1742}
1743
1744int link_save(Link *link) {
1745 _cleanup_free_ char *temp_path = NULL;
1746 _cleanup_fclose_ FILE *f = NULL;
1747 const char *admin_state, *oper_state;
1748 int r;
1749
1750 assert(link);
1751 assert(link->state_file);
1752 assert(link->lease_file);
1753 assert(link->manager);
1754
1755 link_update_operstate(link);
1756
1757 r = manager_save(link->manager);
1758 if (r < 0)
1759 return r;
1760
1761 if (link->state == LINK_STATE_LINGER) {
1762 unlink(link->state_file);
1763 return 0;
1764 }
1765
1766 admin_state = link_state_to_string(link->state);
1767 assert(admin_state);
1768
1769 oper_state = link_operstate_to_string(link->operstate);
1770 assert(oper_state);
1771
1772 r = fopen_temporary(link->state_file, &f, &temp_path);
1773 if (r < 0)
1774 return r;
1775
1776 fchmod(fileno(f), 0644);
1777
1778 fprintf(f,
1779 "# This is private data. Do not parse.\n"
1780 "ADMIN_STATE=%s\n"
1781 "OPER_STATE=%s\n",
1782 admin_state, oper_state);
1783
1784 if (link->network) {
1785 char **address, **domain;
1786 bool space;
1787
1788 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
1789
1790 fputs("DNS=", f);
1791 space = false;
1792 STRV_FOREACH(address, link->network->dns) {
1793 if (space)
1794 fputc(' ', f);
1795 fputs(*address, f);
1796 space = true;
1797 }
1798
1799 if (link->network->dhcp_dns &&
1800 link->dhcp_lease) {
1801 const struct in_addr *addresses;
1802
1803 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1804 if (r > 0) {
1805 if (space)
1806 fputc(' ', f);
1807 serialize_in_addrs(f, addresses, r);
1808 }
1809 }
1810
1811 fputs("\n", f);
1812
1813 fprintf(f, "NTP=");
1814 space = false;
1815 STRV_FOREACH(address, link->network->ntp) {
1816 if (space)
1817 fputc(' ', f);
1818 fputs(*address, f);
1819 space = true;
1820 }
1821
1822 if (link->network->dhcp_ntp &&
1823 link->dhcp_lease) {
1824 const struct in_addr *addresses;
1825
1826 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1827 if (r > 0) {
1828 if (space)
1829 fputc(' ', f);
1830 serialize_in_addrs(f, addresses, r);
1831 }
1832 }
1833
1834 fputs("\n", f);
1835
1836 fprintf(f, "DOMAINS=");
1837 space = false;
1838 STRV_FOREACH(domain, link->network->domains) {
1839 if (space)
1840 fputc(' ', f);
1841 fputs(*domain, f);
1842 space = true;
1843 }
1844
1845 if (link->network->dhcp_domains &&
1846 link->dhcp_lease) {
1847 const char *domainname;
1848
1849 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1850 if (r >= 0) {
1851 if (space)
1852 fputc(' ', f);
1853 fputs(domainname, f);
1854 }
1855 }
1856
1857 fputs("\n", f);
1858
1859 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1860 yes_no(link->network->wildcard_domain));
1861
1862 fprintf(f, "LLMNR=%s\n",
1863 llmnr_support_to_string(link->network->llmnr));
1864 }
1865
1866 if (link->dhcp_lease) {
1867 assert(link->network);
1868
1869 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1870 if (r < 0)
1871 goto fail;
1872
1873 fprintf(f,
1874 "DHCP_LEASE=%s\n",
1875 link->lease_file);
1876 } else
1877 unlink(link->lease_file);
1878
1879 r = fflush_and_check(f);
1880 if (r < 0)
1881 goto fail;
1882
1883 if (rename(temp_path, link->state_file) < 0) {
1884 r = -errno;
1885 goto fail;
1886 }
1887
1888 return 0;
1889fail:
1890 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1891 unlink(link->state_file);
1892 unlink(temp_path);
1893 return r;
1894}
1895
1896static const char* const link_state_table[_LINK_STATE_MAX] = {
1897 [LINK_STATE_PENDING] = "pending",
1898 [LINK_STATE_ENSLAVING] = "configuring",
1899 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1900 [LINK_STATE_SETTING_ROUTES] = "configuring",
1901 [LINK_STATE_CONFIGURED] = "configured",
1902 [LINK_STATE_UNMANAGED] = "unmanaged",
1903 [LINK_STATE_FAILED] = "failed",
1904 [LINK_STATE_LINGER] = "linger",
1905};
1906
1907DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1908
1909static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1910 [LINK_OPERSTATE_OFF] = "off",
1911 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
1912 [LINK_OPERSTATE_DORMANT] = "dormant",
1913 [LINK_OPERSTATE_CARRIER] = "carrier",
1914 [LINK_OPERSTATE_DEGRADED] = "degraded",
1915 [LINK_OPERSTATE_ROUTABLE] = "routable",
1916};
1917
1918DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);