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