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