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