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