]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-link.c
networkd: restore logic for enslaving to a master bonding interface
[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
25 #include "networkd.h"
26 #include "libudev-private.h"
27 #include "util.h"
28 #include "bus-util.h"
29 #include "net-util.h"
30
31 #include "dhcp-lease-internal.h"
32
33 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
34 _cleanup_link_free_ Link *link = NULL;
35 const char *mac;
36 struct ether_addr *mac_addr;
37 const char *ifname;
38 int r;
39
40 assert(manager);
41 assert(manager->links);
42 assert(device);
43 assert(ret);
44
45 link = new0(Link, 1);
46 if (!link)
47 return -ENOMEM;
48
49 link->manager = manager;
50 link->state = _LINK_STATE_INVALID;
51
52 link->ifindex = udev_device_get_ifindex(device);
53 if (link->ifindex <= 0)
54 return -EINVAL;
55
56 r = asprintf(&link->state_file, "/run/systemd/network/links/%u",
57 (unsigned) link->ifindex);
58 if (r < 0)
59 return r;
60
61 mac = udev_device_get_sysattr_value(device, "address");
62 if (mac) {
63 mac_addr = ether_aton(mac);
64 if (mac_addr)
65 memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
66 }
67
68 ifname = udev_device_get_sysname(device);
69 link->ifname = strdup(ifname);
70
71 r = hashmap_put(manager->links, &link->ifindex, link);
72 if (r < 0)
73 return r;
74
75 *ret = link;
76 link = NULL;
77
78 return 0;
79 }
80
81 void link_free(Link *link) {
82 if (!link)
83 return;
84
85 assert(link->manager);
86
87 sd_dhcp_client_free(link->dhcp_client);
88 sd_dhcp_lease_unref(link->dhcp_lease);
89
90 sd_ipv4ll_free(link->ipv4ll);
91
92 hashmap_remove(link->manager->links, &link->ifindex);
93
94 free(link->ifname);
95 free(link->state_file);
96
97 free(link);
98 }
99
100 int link_get(Manager *m, int ifindex, Link **ret) {
101 Link *link;
102 uint64_t ifindex_64;
103
104 assert(m);
105 assert(m->links);
106 assert(ifindex);
107 assert(ret);
108
109 ifindex_64 = ifindex;
110 link = hashmap_get(m->links, &ifindex_64);
111 if (!link)
112 return -ENODEV;
113
114 *ret = link;
115
116 return 0;
117 }
118
119 int link_add(Manager *m, struct udev_device *device, Link **ret) {
120 Link *link = NULL;
121 Network *network;
122 int r;
123
124 assert(m);
125 assert(device);
126
127 r = link_new(m, device, &link);
128 if (r < 0)
129 return r;
130
131 *ret = link;
132
133 r = network_get(m, device, &network);
134 if (r < 0)
135 return r == -ENOENT ? 0 : r;
136
137 r = network_apply(m, network, link);
138 if (r < 0)
139 return r;
140
141 return 0;
142 }
143
144 static int link_enter_configured(Link *link) {
145 assert(link);
146 assert(link->state == LINK_STATE_SETTING_ROUTES);
147
148 log_info_link(link, "link configured");
149
150 link->state = LINK_STATE_CONFIGURED;
151
152 link_save(link);
153
154 return 0;
155 }
156
157 static void link_enter_failed(Link *link) {
158 assert(link);
159
160 log_warning_link(link, "failed");
161
162 link->state = LINK_STATE_FAILED;
163
164 link_save(link);
165 }
166
167 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
168 Link *link = userdata;
169 int r;
170
171 assert(link->route_messages > 0);
172 assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
173 link->state == LINK_STATE_SETTING_ROUTES ||
174 link->state == LINK_STATE_FAILED);
175
176 link->route_messages --;
177
178 if (link->state == LINK_STATE_FAILED)
179 return 1;
180
181 r = sd_rtnl_message_get_errno(m);
182 if (r < 0 && r != -EEXIST)
183 log_struct_link(LOG_WARNING, link,
184 "MESSAGE=%s: could not set route: %s",
185 link->ifname, strerror(-r),
186 "ERRNO=%d", -r,
187 NULL);
188
189 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
190 * ignore it */
191 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
192 log_debug_link(link, "routes set");
193 link_enter_configured(link);
194 }
195
196 return 1;
197 }
198
199 static int link_enter_set_routes(Link *link) {
200 Route *rt;
201 struct in_addr a;
202 int r;
203
204 assert(link);
205 assert(link->network);
206 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
207
208 link->state = LINK_STATE_SETTING_ROUTES;
209
210 if (!link->network->static_routes && !link->dhcp_lease &&
211 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
212 return link_enter_configured(link);
213
214 log_debug_link(link, "setting routes");
215
216 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
217 r = route_configure(rt, link, &route_handler);
218 if (r < 0) {
219 log_warning_link(link,
220 "could not set routes: %s", strerror(-r));
221 link_enter_failed(link);
222 return r;
223 }
224
225 link->route_messages ++;
226 }
227
228 if (link->ipv4ll && !link->dhcp_lease) {
229 _cleanup_route_free_ Route *route = NULL;
230 struct in_addr addr;
231
232 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
233 if (r < 0 && r != -ENOENT) {
234 log_warning_link(link, "IPV4LL error: no address: %s",
235 strerror(-r));
236 return r;
237 }
238
239 if (r != -ENOENT) {
240 r = route_new_dynamic(&route);
241 if (r < 0) {
242 log_error_link(link, "Could not allocate route: %s",
243 strerror(-r));
244 return r;
245 }
246
247 route->family = AF_INET;
248 route->scope = RT_SCOPE_LINK;
249 route->metrics = 99;
250
251 r = route_configure(route, link, &route_handler);
252 if (r < 0) {
253 log_warning_link(link,
254 "could not set routes: %s", strerror(-r));
255 link_enter_failed(link);
256 return r;
257 }
258
259 link->route_messages ++;
260 }
261 }
262
263 if (link->dhcp_lease) {
264 _cleanup_route_free_ Route *route = NULL;
265 struct in_addr gateway;
266
267 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
268 if (r < 0) {
269 log_warning_link(link, "DHCP error: no router: %s",
270 strerror(-r));
271 return r;
272 }
273
274 r = route_new_dynamic(&route);
275 if (r < 0) {
276 log_error_link(link, "Could not allocate route: %s",
277 strerror(-r));
278 return r;
279 }
280
281 route->family = AF_INET;
282 route->in_addr.in = gateway;
283
284 r = route_configure(route, link, &route_handler);
285 if (r < 0) {
286 log_warning_link(link,
287 "could not set routes: %s", strerror(-r));
288 link_enter_failed(link);
289 return r;
290 }
291
292 link->route_messages ++;
293 }
294
295 return 0;
296 }
297
298 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
299 Link *link = userdata;
300 int r;
301
302 assert(m);
303 assert(link);
304 assert(link->ifname);
305
306 if (link->state == LINK_STATE_FAILED)
307 return 1;
308
309 r = sd_rtnl_message_get_errno(m);
310 if (r < 0 && r != -ENOENT)
311 log_struct_link(LOG_WARNING, link,
312 "MESSAGE=%s: could not drop route: %s",
313 link->ifname, strerror(-r),
314 "ERRNO=%d", -r,
315 NULL);
316
317 return 0;
318 }
319
320 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
321 Link *link = userdata;
322 int r;
323
324 assert(m);
325 assert(link);
326 assert(link->ifname);
327 assert(link->addr_messages > 0);
328 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
329
330 link->addr_messages --;
331
332 if (link->state == LINK_STATE_FAILED)
333 return 1;
334
335 r = sd_rtnl_message_get_errno(m);
336 if (r < 0 && r != -EEXIST)
337 log_struct_link(LOG_WARNING, link,
338 "MESSAGE=%s: could not set address: %s",
339 link->ifname, strerror(-r),
340 "ERRNO=%d", -r,
341 NULL);
342
343 if (link->addr_messages == 0) {
344 log_debug_link(link, "addresses set");
345 link_enter_set_routes(link);
346 }
347
348 return 1;
349 }
350
351 static int link_enter_set_addresses(Link *link) {
352 Address *ad;
353 struct in_addr a;
354 int r;
355
356 assert(link);
357 assert(link->network);
358 assert(link->state != _LINK_STATE_INVALID);
359
360 link->state = LINK_STATE_SETTING_ADDRESSES;
361
362 if (!link->network->static_addresses && !link->dhcp_lease &&
363 (!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
364 return link_enter_set_routes(link);
365
366 log_debug_link(link, "setting addresses");
367
368 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
369 r = address_configure(ad, link, &address_handler);
370 if (r < 0) {
371 log_warning_link(link,
372 "could not set addresses: %s", strerror(-r));
373 link_enter_failed(link);
374 return r;
375 }
376
377 link->addr_messages ++;
378 }
379
380 if (link->ipv4ll && !link->dhcp_lease) {
381 _cleanup_address_free_ Address *ll_addr = NULL;
382 struct in_addr addr;
383
384 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
385 if (r < 0 && r != -ENOENT) {
386 log_warning_link(link, "IPV4LL error: no address: %s",
387 strerror(-r));
388 return r;
389 }
390
391 if (r != -ENOENT) {
392 r = address_new_dynamic(&ll_addr);
393 if (r < 0) {
394 log_error_link(link, "Could not allocate address: %s", strerror(-r));
395 return r;
396 }
397
398 ll_addr->family = AF_INET;
399 ll_addr->in_addr.in = addr;
400 ll_addr->prefixlen = 16;
401 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
402 ll_addr->scope = RT_SCOPE_LINK;
403
404 r = address_configure(ll_addr, link, &address_handler);
405 if (r < 0) {
406 log_warning_link(link,
407 "could not set addresses: %s", strerror(-r));
408 link_enter_failed(link);
409 return r;
410 }
411
412 link->addr_messages ++;
413 }
414 }
415
416 if (link->dhcp_lease) {
417 _cleanup_address_free_ Address *address = NULL;
418 struct in_addr addr;
419 struct in_addr netmask;
420 unsigned prefixlen;
421
422 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
423 if (r < 0) {
424 log_warning_link(link, "DHCP error: no address: %s",
425 strerror(-r));
426 return r;
427 }
428
429 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
430 if (r < 0) {
431 log_warning_link(link, "DHCP error: no netmask: %s",
432 strerror(-r));
433 return r;
434 }
435
436 prefixlen = net_netmask_to_prefixlen(&netmask);
437
438 r = address_new_dynamic(&address);
439 if (r < 0) {
440 log_error_link(link, "Could not allocate address: %s",
441 strerror(-r));
442 return r;
443 }
444
445 address->family = AF_INET;
446 address->in_addr.in = addr;
447 address->prefixlen = prefixlen;
448 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
449
450 r = address_configure(address, link, &address_handler);
451 if (r < 0) {
452 log_warning_link(link,
453 "could not set addresses: %s", strerror(-r));
454 link_enter_failed(link);
455 return r;
456 }
457
458 link->addr_messages ++;
459 }
460
461 return 0;
462 }
463
464 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
465 Link *link = userdata;
466 int r;
467
468 assert(m);
469 assert(link);
470 assert(link->ifname);
471
472 if (link->state == LINK_STATE_FAILED)
473 return 1;
474
475 r = sd_rtnl_message_get_errno(m);
476 if (r < 0 && r != -ENOENT)
477 log_struct_link(LOG_WARNING, link,
478 "MESSAGE=%s: could not drop address: %s",
479 link->ifname, strerror(-r),
480 "ERRNO=%d", -r,
481 NULL);
482
483 return 0;
484 }
485
486 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
487 int r;
488
489 r = sd_bus_message_get_errno(m);
490 if (r < 0)
491 log_warning("Could not set hostname: %s", strerror(-r));
492
493 return 1;
494 }
495
496 static int set_hostname(sd_bus *bus, const char *hostname) {
497 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
498 int r = 0;
499
500 assert(hostname);
501
502 log_debug("Setting transient hostname: '%s'", hostname);
503
504 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
505 log_info("Not connected to system bus, ignoring transient hostname.");
506 return 0;
507 }
508
509 r = sd_bus_message_new_method_call(
510 bus,
511 &m,
512 "org.freedesktop.hostname1",
513 "/org/freedesktop/hostname1",
514 "org.freedesktop.hostname1",
515 "SetHostname");
516 if (r < 0)
517 return r;
518
519 r = sd_bus_message_append(m, "sb", hostname, false);
520 if (r < 0)
521 return r;
522
523 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
524 if (r < 0)
525 log_error("Could not set transient hostname: %s", strerror(-r));
526
527 return r;
528 }
529
530 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
531 Link *link = userdata;
532 int r;
533
534 assert(m);
535 assert(link);
536 assert(link->ifname);
537
538 if (link->state == LINK_STATE_FAILED)
539 return 1;
540
541 r = sd_rtnl_message_get_errno(m);
542 if (r < 0)
543 log_struct_link(LOG_WARNING, link,
544 "MESSAGE=%s: could not set MTU: %s",
545 link->ifname, strerror(-r),
546 "ERRNO=%d", -r,
547 NULL);
548
549 return 1;
550 }
551
552 static int link_set_mtu(Link *link, uint32_t mtu) {
553 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
554 int r;
555
556 assert(link);
557 assert(link->manager);
558 assert(link->manager->rtnl);
559
560 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
561
562 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
563 RTM_SETLINK, link->ifindex);
564 if (r < 0) {
565 log_error_link(link, "Could not allocate RTM_SETLINK message");
566 return r;
567 }
568
569 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
570 if (r < 0) {
571 log_error_link(link, "Could not append MTU: %s", strerror(-r));
572 return r;
573 }
574
575 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
576 if (r < 0) {
577 log_error_link(link,
578 "Could not send rtnetlink message: %s", strerror(-r));
579 return r;
580 }
581
582 return 0;
583 }
584
585 static int dhcp_lease_lost(Link *link) {
586 _cleanup_address_free_ Address *address = NULL;
587 struct in_addr addr;
588 struct in_addr netmask;
589 unsigned prefixlen;
590 int r;
591
592 assert(link);
593 assert(link->dhcp_lease);
594
595 log_warning_link(link, "DHCP lease lost");
596
597 r = address_new_dynamic(&address);
598 if (r >= 0) {
599 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
600 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
601 prefixlen = net_netmask_to_prefixlen(&netmask);
602
603 address->family = AF_INET;
604 address->in_addr.in = addr;
605 address->prefixlen = prefixlen;
606
607 address_drop(address, link, &address_drop_handler);
608 }
609
610 if (link->network->dhcp_mtu) {
611 uint16_t mtu;
612
613 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
614 if (r >= 0 && link->original_mtu != mtu) {
615 r = link_set_mtu(link, link->original_mtu);
616 if (r < 0) {
617 log_warning_link(link, "DHCP error: could not reset MTU");
618 link_enter_failed(link);
619 return r;
620 }
621 }
622 }
623
624 if (link->network->dhcp_hostname) {
625 const char *hostname = NULL;
626
627 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
628 if (r >= 0 && hostname) {
629 r = set_hostname(link->manager->bus, "");
630 if (r < 0)
631 log_error("Failed to reset transient hostname");
632 }
633 }
634
635 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
636
637 return 0;
638 }
639
640 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
641 sd_dhcp_lease *lease;
642 struct in_addr address;
643 struct in_addr netmask;
644 struct in_addr gateway;
645 unsigned prefixlen;
646 struct in_addr *nameservers;
647 size_t nameservers_size;
648 int r;
649
650 assert(client);
651 assert(link);
652
653 r = sd_dhcp_client_get_lease(client, &lease);
654 if (r < 0) {
655 log_warning_link(link, "DHCP error: no lease: %s",
656 strerror(-r));
657 return r;
658 }
659
660 r = sd_dhcp_lease_get_address(lease, &address);
661 if (r < 0) {
662 log_warning_link(link, "DHCP error: no address: %s",
663 strerror(-r));
664 return r;
665 }
666
667 r = sd_dhcp_lease_get_netmask(lease, &netmask);
668 if (r < 0) {
669 log_warning_link(link, "DHCP error: no netmask: %s",
670 strerror(-r));
671 return r;
672 }
673
674 prefixlen = net_netmask_to_prefixlen(&netmask);
675
676 r = sd_dhcp_lease_get_router(lease, &gateway);
677 if (r < 0) {
678 log_warning_link(link, "DHCP error: no router: %s",
679 strerror(-r));
680 return r;
681 }
682
683 log_struct_link(LOG_INFO, link,
684 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
685 link->ifname,
686 ADDRESS_FMT_VAL(address),
687 prefixlen,
688 ADDRESS_FMT_VAL(gateway),
689 "ADDRESS=%u.%u.%u.%u",
690 ADDRESS_FMT_VAL(address),
691 "PREFIXLEN=%u",
692 prefixlen,
693 "GATEWAY=%u.%u.%u.%u",
694 ADDRESS_FMT_VAL(gateway),
695 NULL);
696
697 link->dhcp_lease = lease;
698
699 if (link->network->dhcp_dns) {
700 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
701 if (r >= 0) {
702 r = manager_update_resolv_conf(link->manager);
703 if (r < 0)
704 log_error("Failed to update resolv.conf");
705 }
706 }
707
708 if (link->network->dhcp_mtu) {
709 uint16_t mtu;
710
711 r = sd_dhcp_lease_get_mtu(lease, &mtu);
712 if (r >= 0) {
713 r = link_set_mtu(link, mtu);
714 if (r < 0)
715 log_error_link(link, "Failed to set MTU "
716 "to %" PRIu16, mtu);
717 }
718 }
719
720 if (link->network->dhcp_hostname) {
721 const char *hostname;
722
723 r = sd_dhcp_lease_get_hostname(lease, &hostname);
724 if (r >= 0) {
725 r = set_hostname(link->manager->bus, hostname);
726 if (r < 0)
727 log_error("Failed to set transient hostname "
728 "to '%s'", hostname);
729 }
730 }
731
732 link_enter_set_addresses(link);
733
734 return 0;
735 }
736
737 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
738 Link *link = userdata;
739 int r;
740
741 assert(link);
742 assert(link->network);
743 assert(link->manager);
744
745 if (link->state == LINK_STATE_FAILED)
746 return;
747
748 switch (event) {
749 case DHCP_EVENT_NO_LEASE:
750 log_debug_link(link, "IP address in use.");
751 break;
752 case DHCP_EVENT_EXPIRED:
753 case DHCP_EVENT_STOP:
754 case DHCP_EVENT_IP_CHANGE:
755 if (link->network->dhcp_critical) {
756 log_error_link(link, "DHCPv4 connection considered system critical, "
757 "ignoring request to reconfigure it.");
758 return;
759 }
760
761 if (link->dhcp_lease) {
762 r = dhcp_lease_lost(link);
763 if (r < 0) {
764 link_enter_failed(link);
765 return;
766 }
767 }
768
769 if (event == DHCP_EVENT_IP_CHANGE) {
770 r = dhcp_lease_acquired(client, link);
771 if (r < 0) {
772 link_enter_failed(link);
773 return;
774 }
775 }
776
777 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
778 r = sd_ipv4ll_start (link->ipv4ll);
779 if (r < 0) {
780 link_enter_failed(link);
781 return;
782 }
783 }
784
785 break;
786 case DHCP_EVENT_IP_ACQUIRE:
787 r = dhcp_lease_acquired(client, link);
788 if (r < 0) {
789 link_enter_failed(link);
790 return;
791 }
792 if (link->ipv4ll) {
793 r = sd_ipv4ll_stop(link->ipv4ll);
794 if (r < 0) {
795 link_enter_failed(link);
796 return;
797 }
798 }
799 break;
800 default:
801 if (event < 0)
802 log_warning_link(link, "DHCP error: %s", strerror(-event));
803 else
804 log_warning_link(link, "DHCP unknown event: %d", event);
805 break;
806 }
807
808 return;
809 }
810
811 static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
812 int r;
813 struct in_addr addr;
814
815 assert(ll);
816 assert(link);
817
818 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
819 if (r >= 0) {
820 _cleanup_address_free_ Address *address = NULL;
821 _cleanup_route_free_ Route *route = NULL;
822
823 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
824 ADDRESS_FMT_VAL(addr));
825
826 r = address_new_dynamic(&address);
827 if (r < 0) {
828 log_error_link(link, "Could not allocate address: %s", strerror(-r));
829 return r;
830 }
831
832 address->family = AF_INET;
833 address->in_addr.in = addr;
834 address->prefixlen = 16;
835 address->scope = RT_SCOPE_LINK;
836
837 address_drop(address, link, &address_drop_handler);
838
839 r = route_new_dynamic(&route);
840 if (r < 0) {
841 log_error_link(link, "Could not allocate route: %s",
842 strerror(-r));
843 return r;
844 }
845
846 route->family = AF_INET;
847 route->scope = RT_SCOPE_LINK;
848 route->metrics = 99;
849
850 route_drop(route, link, &route_drop_handler);
851 }
852
853 return 0;
854 }
855
856 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
857 struct in_addr address;
858 int r;
859
860 assert(ll);
861 assert(link);
862
863 r = sd_ipv4ll_get_address(ll, &address);
864 if (r < 0)
865 return r;
866
867 log_struct_link(LOG_INFO, link,
868 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
869 link->ifname,
870 ADDRESS_FMT_VAL(address),
871 NULL);
872
873 link_enter_set_addresses(link);
874
875 return 0;
876 }
877
878 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
879 Link *link = userdata;
880 int r;
881
882 assert(link);
883 assert(link->network);
884 assert(link->manager);
885
886 switch(event) {
887 case IPV4LL_EVENT_STOP:
888 case IPV4LL_EVENT_CONFLICT:
889 r = ipv4ll_address_lost(ll, link);
890 if (r < 0) {
891 link_enter_failed(link);
892 return;
893 }
894 break;
895 case IPV4LL_EVENT_BIND:
896 r = ipv4ll_address_claimed(ll, link);
897 if (r < 0) {
898 link_enter_failed(link);
899 return;
900 }
901 break;
902 default:
903 if (event < 0)
904 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
905 else
906 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
907 break;
908 }
909 }
910
911 static int link_acquire_conf(Link *link) {
912 int r;
913
914 assert(link);
915 assert(link->network);
916 assert(link->manager);
917 assert(link->manager->event);
918
919 if (link->network->ipv4ll) {
920 if (!link->ipv4ll) {
921 r = sd_ipv4ll_new(&link->ipv4ll);
922 if (r < 0)
923 return r;
924
925 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
926 if (r < 0)
927 return r;
928
929 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
930 if (r < 0)
931 return r;
932
933 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
934 if (r < 0)
935 return r;
936
937 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
938 if (r < 0)
939 return r;
940 }
941
942 log_debug_link(link, "acquiring IPv4 link-local address");
943
944 r = sd_ipv4ll_start(link->ipv4ll);
945 if (r < 0)
946 return r;
947 }
948
949 if (link->network->dhcp) {
950 if (!link->dhcp_client) {
951 r = sd_dhcp_client_new(&link->dhcp_client);
952 if (r < 0)
953 return r;
954
955 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
956 if (r < 0)
957 return r;
958
959 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
960 if (r < 0)
961 return r;
962
963 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
964 if (r < 0)
965 return r;
966
967 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
968 if (r < 0)
969 return r;
970
971 if (link->network->dhcp_mtu) {
972 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
973 if (r < 0)
974 return r;
975 }
976 }
977
978 log_debug_link(link, "acquiring DHCPv4 lease");
979
980 r = sd_dhcp_client_start(link->dhcp_client);
981 if (r < 0)
982 return r;
983 }
984
985 return 0;
986 }
987
988 static int link_update_flags(Link *link, unsigned flags) {
989 int r;
990
991 assert(link);
992 assert(link->network);
993
994 if (link->state == LINK_STATE_FAILED)
995 return 0;
996
997 if (link->flags == flags) {
998 log_debug_link(link, "link status unchanged: %#.8x", flags);
999 return 0;
1000 }
1001
1002 if ((link->flags & IFF_UP) != (flags & IFF_UP))
1003 log_info_link(link,
1004 "link is %s", flags & IFF_UP ? "up": "down");
1005
1006 if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
1007 if (flags & IFF_LOWER_UP) {
1008 log_info_link(link, "carrier on");
1009
1010 if (link->network->dhcp || link->network->ipv4ll) {
1011 r = link_acquire_conf(link);
1012 if (r < 0) {
1013 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
1014 link_enter_failed(link);
1015 return r;
1016 }
1017 }
1018 } else {
1019 log_info_link(link, "carrier off");
1020
1021 if (link->network->dhcp) {
1022 r = sd_dhcp_client_stop(link->dhcp_client);
1023 if (r < 0) {
1024 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
1025 link_enter_failed(link);
1026 return r;
1027 }
1028 }
1029
1030 if (link->network->ipv4ll) {
1031 r = sd_ipv4ll_stop(link->ipv4ll);
1032 if (r < 0) {
1033 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1034 link_enter_failed(link);
1035 return r;
1036 }
1037 }
1038 }
1039 }
1040
1041 log_debug_link(link,
1042 "link status updated: %#.8x -> %#.8x", link->flags, flags);
1043
1044 link->flags = flags;
1045
1046 return 0;
1047 }
1048
1049 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1050 Link *link = userdata;
1051 int r;
1052
1053 assert(link);
1054
1055 if (link->state == LINK_STATE_FAILED)
1056 return 1;
1057
1058 r = sd_rtnl_message_get_errno(m);
1059 if (r < 0) {
1060 log_struct_link(LOG_ERR, link,
1061 "MESSAGE=%s: could not bring up interface: %s",
1062 link->ifname, strerror(-r),
1063 "ERRNO=%d", -r,
1064 NULL);
1065 link_enter_failed(link);
1066 return 1;
1067 }
1068
1069 link_update_flags(link, link->flags | IFF_UP);
1070
1071 return 1;
1072 }
1073
1074 static int link_up(Link *link) {
1075 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1076 int r;
1077
1078 assert(link);
1079 assert(link->manager);
1080 assert(link->manager->rtnl);
1081
1082 log_debug_link(link, "bringing link up");
1083
1084 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1085 RTM_SETLINK, link->ifindex);
1086 if (r < 0) {
1087 log_error_link(link, "Could not allocate RTM_SETLINK message");
1088 return r;
1089 }
1090
1091 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1092 if (r < 0) {
1093 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1094 return r;
1095 }
1096
1097 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1098 if (r < 0) {
1099 log_error_link(link,
1100 "Could not send rtnetlink message: %s", strerror(-r));
1101 return r;
1102 }
1103
1104 return 0;
1105 }
1106
1107 static int link_enslaved(Link *link) {
1108 int r;
1109
1110 assert(link);
1111 assert(link->state == LINK_STATE_ENSLAVING);
1112 assert(link->network);
1113
1114 r = link_up(link);
1115 if (r < 0) {
1116 link_enter_failed(link);
1117 return r;
1118 }
1119
1120 if (!link->network->dhcp && !link->network->ipv4ll)
1121 return link_enter_set_addresses(link);
1122
1123 return 0;
1124 }
1125
1126 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1127 Link *link = userdata;
1128 int r;
1129
1130 assert(link);
1131 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1132 assert(link->network);
1133
1134 link->enslaving --;
1135
1136 if (link->state == LINK_STATE_FAILED)
1137 return 1;
1138
1139 r = sd_rtnl_message_get_errno(m);
1140 if (r < 0) {
1141 log_struct_link(LOG_ERR, link,
1142 "MESSAGE=%s: could not enslave: %s",
1143 link->ifname, strerror(-r),
1144 "ERRNO=%d", -r,
1145 NULL);
1146 link_enter_failed(link);
1147 return 1;
1148 }
1149
1150 log_debug_link(link, "enslaved");
1151
1152 if (link->enslaving == 0)
1153 link_enslaved(link);
1154
1155 return 1;
1156 }
1157
1158 static int link_enter_enslave(Link *link) {
1159 NetDev *vlan, *macvlan;
1160 Iterator i;
1161 int r;
1162
1163 assert(link);
1164 assert(link->network);
1165 assert(link->state == _LINK_STATE_INVALID);
1166
1167 link->state = LINK_STATE_ENSLAVING;
1168
1169 link_save(link);
1170
1171 if (!link->network->bridge && !link->network->bond &&
1172 hashmap_isempty(link->network->vlans) &&
1173 hashmap_isempty(link->network->macvlans))
1174 return link_enslaved(link);
1175
1176 if (link->network->bridge) {
1177 log_struct_link(LOG_DEBUG, link,
1178 "MESSAGE=%s: enslaving by '%s'",
1179 link->ifname, link->network->bridge->name,
1180 NETDEV(link->network->bridge),
1181 NULL);
1182
1183 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1184 if (r < 0) {
1185 log_struct_link(LOG_WARNING, link,
1186 "MESSAGE=%s: could not enslave by '%s': %s",
1187 link->ifname, link->network->bridge->name, strerror(-r),
1188 NETDEV(link->network->bridge),
1189 NULL);
1190 link_enter_failed(link);
1191 return r;
1192 }
1193
1194 link->enslaving ++;
1195 }
1196
1197 if (link->network->bond) {
1198 log_struct_link(LOG_DEBUG, link,
1199 "MESSAGE=%s: enslaving by '%s'",
1200 link->ifname, link->network->bond->name,
1201 NETDEV(link->network->bond),
1202 NULL);
1203
1204 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1205 if (r < 0) {
1206 log_struct_link(LOG_WARNING, link,
1207 "MESSAGE=%s: could not enslave by '%s': %s",
1208 link->ifname, link->network->bond->name, strerror(-r),
1209 NETDEV(link->network->bond),
1210 NULL);
1211 link_enter_failed(link);
1212 return r;
1213 }
1214
1215 link->enslaving ++;
1216 }
1217
1218 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1219 log_struct_link(LOG_DEBUG, link,
1220 "MESSAGE=%s: enslaving by '%s'",
1221 link->ifname, vlan->name, NETDEV(vlan), NULL);
1222
1223 r = netdev_enslave(vlan, link, &enslave_handler);
1224 if (r < 0) {
1225 log_struct_link(LOG_WARNING, link,
1226 "MESSAGE=%s: could not enslave by '%s': %s",
1227 link->ifname, vlan->name, strerror(-r),
1228 NETDEV(vlan), NULL);
1229 link_enter_failed(link);
1230 return r;
1231 }
1232
1233 link->enslaving ++;
1234 }
1235
1236 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1237 log_struct_link(LOG_DEBUG, link,
1238 "MESSAGE=%s: enslaving by '%s'",
1239 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1240
1241 r = netdev_enslave(macvlan, link, &enslave_handler);
1242 if (r < 0) {
1243 log_struct_link(LOG_WARNING, link,
1244 "MESSAGE=%s: could not enslave by '%s': %s",
1245 link->ifname, macvlan->name, strerror(-r),
1246 NETDEV(macvlan), NULL);
1247 link_enter_failed(link);
1248 return r;
1249 }
1250
1251 link->enslaving ++;
1252 }
1253
1254 return 0;
1255 }
1256
1257 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1258 void *userdata) {
1259 Link *link = userdata;
1260 int r;
1261
1262 assert(link);
1263
1264 if (link->state == LINK_STATE_FAILED)
1265 return 1;
1266
1267 r = sd_rtnl_message_get_errno(m);
1268 if (r < 0) {
1269 log_struct_link(LOG_ERR, link,
1270 "MESSAGE=%s: could not get state: %s",
1271 link->ifname, strerror(-r),
1272 "ERRNO=%d", -r,
1273 NULL);
1274 link_enter_failed(link);
1275 return 1;
1276 }
1277
1278 log_debug_link(link, "got link state");
1279
1280 link_update(link, m);
1281
1282 return 1;
1283 }
1284
1285 static int link_getlink(Link *link) {
1286 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1287 int r;
1288
1289 assert(link);
1290 assert(link->manager);
1291 assert(link->manager->rtnl);
1292
1293 log_debug_link(link, "requesting link status");
1294
1295 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1296 RTM_GETLINK, link->ifindex);
1297 if (r < 0) {
1298 log_error_link(link, "Could not allocate RTM_GETLINK message");
1299 return r;
1300 }
1301
1302 r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1303 link, 0, NULL);
1304 if (r < 0) {
1305 log_error_link(link,
1306 "Could not send rtnetlink message: %s", strerror(-r));
1307 return r;
1308 }
1309
1310 return 0;
1311 }
1312
1313 int link_configure(Link *link) {
1314 int r;
1315
1316 assert(link);
1317 assert(link->network);
1318 assert(link->state == _LINK_STATE_INVALID);
1319
1320 r = link_getlink(link);
1321 if (r < 0) {
1322 link_enter_failed(link);
1323 return r;
1324 }
1325
1326 return link_enter_enslave(link);
1327 }
1328
1329 int link_update(Link *link, sd_rtnl_message *m) {
1330 unsigned flags;
1331 void *data;
1332 uint16_t type;
1333 int r;
1334
1335 assert(link);
1336 assert(m);
1337
1338 if (link->state == LINK_STATE_FAILED)
1339 return 0;
1340
1341 r = sd_rtnl_message_link_get_flags(m, &flags);
1342 if (r < 0) {
1343 log_warning_link(link, "Could not get link flags");
1344 return r;
1345 }
1346
1347 while (sd_rtnl_message_read(m, &type, &data) > 0) {
1348 if (type == IFLA_MTU && link->network->dhcp &&
1349 link->network->dhcp_mtu && !link->original_mtu) {
1350 link->original_mtu = *(uint16_t *) data;
1351 log_debug_link(link, "saved original MTU: %" PRIu16,
1352 link->original_mtu);
1353 }
1354 }
1355
1356 return link_update_flags(link, flags);
1357 }
1358
1359 int link_save(Link *link) {
1360 _cleanup_free_ char *temp_path = NULL;
1361 _cleanup_fclose_ FILE *f = NULL;
1362 int r;
1363
1364 assert(link);
1365 assert(link->state_file);
1366
1367 r = mkdir_safe_label("/run/systemd/network/links", 0755, 0, 0);
1368 if (r < 0)
1369 goto finish;
1370
1371 r = fopen_temporary(link->state_file, &f, &temp_path);
1372 if (r < 0)
1373 goto finish;
1374
1375 fchmod(fileno(f), 0644);
1376
1377 fprintf(f,
1378 "# This is private data. Do not parse.\n"
1379 "STATE=%s\n",
1380 link_state_to_string(link->state));
1381
1382 if (link->dhcp_lease) {
1383 const char *lease_file = "/run/systemd/network/leases/test.lease";
1384
1385 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1386 if (r < 0)
1387 goto finish;
1388
1389 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1390 }
1391
1392 fflush(f);
1393
1394 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1395 r = -errno;
1396 unlink(link->state_file);
1397 unlink(temp_path);
1398 }
1399
1400 finish:
1401 if (r < 0)
1402 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1403
1404 return r;
1405 }
1406
1407 static const char* const link_state_table[_LINK_STATE_MAX] = {
1408 [LINK_STATE_ENSLAVING] = "configuring",
1409 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1410 [LINK_STATE_SETTING_ROUTES] = "configuring",
1411 [LINK_STATE_CONFIGURED] = "configured",
1412 [LINK_STATE_FAILED] = "failed",
1413 };
1414
1415 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);