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