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