]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
networkd: link - don't react to successfull link up
[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
2139694e
TG
190 if (link->state == LINK_STATE_FAILED)
191 return;
192
39032b87 193 log_warning_link(link, "failed");
449f7554 194
ef1ba606 195 link->state = LINK_STATE_FAILED;
fe8db0c5 196
111bb8f9
TG
197 link_stop_clients(link);
198
fe8db0c5 199 link_save(link);
f882c247
TG
200}
201
f882c247
TG
202static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
203 Link *link = userdata;
204 int r;
205
f5be5601
TG
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);
f882c247 210
f5be5601 211 link->route_messages --;
f882c247
TG
212
213 if (link->state == LINK_STATE_FAILED)
214 return 1;
215
216 r = sd_rtnl_message_get_errno(m);
c166a070 217 if (r < 0 && r != -EEXIST)
c9ccc19f
TG
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);
f882c247 223
f5be5601
TG
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) {
39032b87 227 log_debug_link(link, "routes set");
dd3efc09
TG
228 link_enter_configured(link);
229 }
f882c247
TG
230
231 return 1;
232}
233
234static int link_enter_set_routes(Link *link) {
a6cc569e 235 Route *rt;
f882c247
TG
236 int r;
237
238 assert(link);
239 assert(link->network);
ef1ba606 240 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 241
ef1ba606 242 link->state = LINK_STATE_SETTING_ROUTES;
f882c247 243
5c1d3fc9 244 if (!link->network->static_routes && !link->dhcp_lease &&
aba496a5 245 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
dd3efc09 246 return link_enter_configured(link);
f882c247 247
39032b87 248 log_debug_link(link, "setting routes");
449f7554 249
a6cc569e
TG
250 LIST_FOREACH(static_routes, rt, link->network->static_routes) {
251 r = route_configure(rt, link, &route_handler);
dd3efc09 252 if (r < 0) {
3333d748
ZJS
253 log_warning_link(link,
254 "could not set routes: %s", strerror(-r));
ef1ba606
TG
255 link_enter_failed(link);
256 return r;
dd3efc09 257 }
c166a070 258
f5be5601
TG
259 link->route_messages ++;
260 }
261
5c1d3fc9
UTL
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
a6cc569e
TG
297 if (link->dhcp_lease) {
298 _cleanup_route_free_ Route *route = NULL;
9765ce69 299 _cleanup_route_free_ Route *route_gw = NULL;
a6cc569e
TG
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
9765ce69
BP
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
a6cc569e
TG
340 route->family = AF_INET;
341 route->in_addr.in = gateway;
342
343 r = route_configure(route, link, &route_handler);
f5be5601 344 if (r < 0) {
3333d748
ZJS
345 log_warning_link(link,
346 "could not set routes: %s", strerror(-r));
f5be5601
TG
347 link_enter_failed(link);
348 return r;
349 }
350
351 link->route_messages ++;
f882c247
TG
352 }
353
354 return 0;
355}
356
5c1d3fc9
UTL
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
f882c247
TG
379static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
380 Link *link = userdata;
381 int r;
382
f5be5601
TG
383 assert(m);
384 assert(link);
385 assert(link->ifname);
386 assert(link->addr_messages > 0);
ef1ba606 387 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
f882c247 388
f5be5601 389 link->addr_messages --;
f882c247
TG
390
391 if (link->state == LINK_STATE_FAILED)
392 return 1;
393
394 r = sd_rtnl_message_get_errno(m);
c166a070 395 if (r < 0 && r != -EEXIST)
c9ccc19f 396 log_struct_link(LOG_WARNING, link,
3333d748
ZJS
397 "MESSAGE=%s: could not set address: %s",
398 link->ifname, strerror(-r),
399 "ERRNO=%d", -r,
400 NULL);
f882c247 401
f5be5601 402 if (link->addr_messages == 0) {
39032b87 403 log_debug_link(link, "addresses set");
ef1ba606 404 link_enter_set_routes(link);
dd3efc09 405 }
f882c247
TG
406
407 return 1;
408}
409
410static int link_enter_set_addresses(Link *link) {
a6cc569e 411 Address *ad;
f882c247
TG
412 int r;
413
414 assert(link);
415 assert(link->network);
f5be5601 416 assert(link->state != _LINK_STATE_INVALID);
f882c247 417
ef1ba606 418 link->state = LINK_STATE_SETTING_ADDRESSES;
f882c247 419
5c1d3fc9 420 if (!link->network->static_addresses && !link->dhcp_lease &&
aba496a5 421 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
ef1ba606 422 return link_enter_set_routes(link);
f882c247 423
39032b87 424 log_debug_link(link, "setting addresses");
449f7554 425
a6cc569e
TG
426 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
427 r = address_configure(ad, link, &address_handler);
dd3efc09 428 if (r < 0) {
3333d748
ZJS
429 log_warning_link(link,
430 "could not set addresses: %s", strerror(-r));
ef1ba606
TG
431 link_enter_failed(link);
432 return r;
dd3efc09 433 }
c166a070 434
f5be5601
TG
435 link->addr_messages ++;
436 }
437
5c1d3fc9
UTL
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
a6cc569e
TG
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);
f5be5601 509 if (r < 0) {
3333d748
ZJS
510 log_warning_link(link,
511 "could not set addresses: %s", strerror(-r));
f5be5601
TG
512 link_enter_failed(link);
513 return r;
514 }
515
516 link->addr_messages ++;
f882c247
TG
517 }
518
519 return 0;
520}
521
aba496a5
UTL
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
ff254138
TG
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);
c9ccc19f
TG
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);
ff254138 562
5c1d3fc9 563 return 0;
ff254138
TG
564}
565
1346b1f0
TG
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
1346b1f0
TG
580 assert(hostname);
581
582 log_debug("Setting transient hostname: '%s'", hostname);
583
bcbca829
TG
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
1346b1f0
TG
589 r = sd_bus_message_new_method_call(
590 bus,
151b9b96 591 &m,
1346b1f0
TG
592 "org.freedesktop.hostname1",
593 "/org/freedesktop/hostname1",
594 "org.freedesktop.hostname1",
151b9b96 595 "SetHostname");
1346b1f0
TG
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
4f882b2a
TG
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);
c9ccc19f
TG
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);
4f882b2a
TG
628
629 return 1;
630}
631
632static int link_set_mtu(Link *link, uint32_t mtu) {
cf6a8911 633 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
4f882b2a
TG
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
151b9b96
LP
642 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
643 RTM_SETLINK, link->ifindex);
4f882b2a
TG
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
a6cc569e
TG
665static int dhcp_lease_lost(Link *link) {
666 _cleanup_address_free_ Address *address = NULL;
3e790eae
UTL
667 _cleanup_route_free_ Route *route_gw = NULL;
668 _cleanup_route_free_ Route *route = NULL;
a6cc569e
TG
669 struct in_addr addr;
670 struct in_addr netmask;
3e790eae 671 struct in_addr gateway;
a6cc569e 672 unsigned prefixlen;
ff254138
TG
673 int r;
674
675 assert(link);
a6cc569e 676 assert(link->dhcp_lease);
ff254138 677
14efd761
TG
678 log_warning_link(link, "DHCP lease lost");
679
a6cc569e
TG
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);
3e790eae 684 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
a6cc569e 685 prefixlen = net_netmask_to_prefixlen(&netmask);
ff254138 686
3e790eae
UTL
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
a6cc569e
TG
705 address->family = AF_INET;
706 address->in_addr.in = addr;
707 address->prefixlen = prefixlen;
ff254138 708
5c1d3fc9 709 address_drop(address, link, &address_drop_handler);
c07aeadf 710 }
eb27aeca 711
c07aeadf
TG
712 if (link->network->dhcp_mtu) {
713 uint16_t mtu;
ff254138 714
a6cc569e 715 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
c07aeadf
TG
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 }
ff254138 723 }
c07aeadf 724 }
ff254138 725
c07aeadf 726 if (link->network->dhcp_hostname) {
216816c6
TG
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 }
c07aeadf 735 }
4f882b2a 736
a6cc569e
TG
737 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
738
c07aeadf
TG
739 return 0;
740}
4f882b2a 741
c07aeadf 742static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
a6cc569e 743 sd_dhcp_lease *lease;
c07aeadf
TG
744 struct in_addr address;
745 struct in_addr netmask;
746 struct in_addr gateway;
747 unsigned prefixlen;
c07aeadf
TG
748 struct in_addr *nameservers;
749 size_t nameservers_size;
750 int r;
1346b1f0 751
c07aeadf
TG
752 assert(client);
753 assert(link);
ff254138 754
a6cc569e
TG
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);
ff254138 763 if (r < 0) {
c07aeadf
TG
764 log_warning_link(link, "DHCP error: no address: %s",
765 strerror(-r));
766 return r;
ff254138
TG
767 }
768
a6cc569e 769 r = sd_dhcp_lease_get_netmask(lease, &netmask);
ff254138 770 if (r < 0) {
c07aeadf
TG
771 log_warning_link(link, "DHCP error: no netmask: %s",
772 strerror(-r));
773 return r;
ff254138
TG
774 }
775
377a218f 776 prefixlen = net_netmask_to_prefixlen(&netmask);
ff254138 777
a6cc569e 778 r = sd_dhcp_lease_get_router(lease, &gateway);
ff254138 779 if (r < 0) {
c07aeadf
TG
780 log_warning_link(link, "DHCP error: no router: %s",
781 strerror(-r));
782 return r;
ff254138
TG
783 }
784
c07aeadf
TG
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
d50cf59b
TG
799 link->dhcp_lease = lease;
800
c07aeadf 801 if (link->network->dhcp_dns) {
a6cc569e 802 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
c07aeadf
TG
803 if (r >= 0) {
804 r = manager_update_resolv_conf(link->manager);
805 if (r < 0)
806 log_error("Failed to update resolv.conf");
ff254138 807 }
c07aeadf 808 }
ff254138 809
c07aeadf
TG
810 if (link->network->dhcp_mtu) {
811 uint16_t mtu;
812
a6cc569e 813 r = sd_dhcp_lease_get_mtu(lease, &mtu);
c07aeadf
TG
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 }
ff254138 821
c07aeadf
TG
822 if (link->network->dhcp_hostname) {
823 const char *hostname;
ff254138 824
a6cc569e 825 r = sd_dhcp_lease_get_hostname(lease, &hostname);
c07aeadf
TG
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);
3bef724f 831 }
c07aeadf 832 }
3bef724f 833
c07aeadf
TG
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;
aba496a5 841 int r = 0;
c07aeadf
TG
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;
4f882b2a 861 }
4f882b2a 862
17256461
UTL
863 if (link->dhcp_lease) {
864 r = dhcp_lease_lost(link);
865 if (r < 0) {
866 link_enter_failed(link);
867 return;
868 }
c07aeadf 869 }
1346b1f0 870
c07aeadf
TG
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 }
1346b1f0 877 }
1346b1f0 878
5c1d3fc9 879 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
aba496a5
UTL
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);
5c1d3fc9
UTL
884 if (r < 0) {
885 link_enter_failed(link);
886 return;
887 }
888 }
889
c07aeadf
TG
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 }
5c1d3fc9 897 if (link->ipv4ll) {
aba496a5
UTL
898 if (ipv4ll_is_bound(link->ipv4ll))
899 r = ipv4ll_address_update(link, true);
900 else
901 r = sd_ipv4ll_stop(link->ipv4ll);
5c1d3fc9
UTL
902 if (r < 0) {
903 link_enter_failed(link);
904 return;
905 }
906 }
c07aeadf
TG
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);
c07aeadf 913 break;
ff254138
TG
914 }
915
916 return;
917}
918
aba496a5
UTL
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) {
5c1d3fc9
UTL
954 int r;
955 struct in_addr addr;
956
5c1d3fc9
UTL
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
aba496a5
UTL
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
5c1d3fc9
UTL
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:
aba496a5 1042 r = ipv4ll_address_lost(link);
5c1d3fc9
UTL
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
ff254138
TG
1064static int link_acquire_conf(Link *link) {
1065 int r;
1066
1067 assert(link);
1068 assert(link->network);
ff254138
TG
1069 assert(link->manager);
1070 assert(link->manager->event);
1071
5c1d3fc9 1072 if (link->network->ipv4ll) {
eb34d4af 1073 assert(link->ipv4ll);
ff254138 1074
5c1d3fc9
UTL
1075 log_debug_link(link, "acquiring IPv4 link-local address");
1076
1077 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6
TG
1078 if (r < 0) {
1079 log_warning_link(link, "could not acquire IPv4 "
1080 "link-local address");
ff254138 1081 return r;
124fa2c6 1082 }
5c1d3fc9
UTL
1083 }
1084
1085 if (link->network->dhcp) {
eb34d4af 1086 assert(link->dhcp_client);
ff254138 1087
5c1d3fc9 1088 log_debug_link(link, "acquiring DHCPv4 lease");
ab47d620 1089
5c1d3fc9 1090 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6
TG
1091 if (r < 0) {
1092 log_warning_link(link, "could not acquire DHCPv4 "
1093 "lease");
5c1d3fc9 1094 return r;
124fa2c6 1095 }
5c1d3fc9 1096 }
ff254138
TG
1097
1098 return 0;
1099}
1100
1101static int link_update_flags(Link *link, unsigned flags) {
ffba6166 1102 unsigned flags_added, flags_removed, generic_flags;
7cc832b9 1103 bool carrier_gained, carrier_lost;
ff254138
TG
1104 int r;
1105
1106 assert(link);
ff254138
TG
1107
1108 if (link->state == LINK_STATE_FAILED)
1109 return 0;
1110
a748b692 1111 if (link->flags == flags)
efbc88b8 1112 return 0;
efbc88b8 1113
ffba6166
TG
1114 flags_added = (link->flags ^ flags) & flags;
1115 flags_removed = (link->flags ^ flags) & link->flags;
c6a1eb79
TG
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);
c49b33ac 1119
75ee87c8
TG
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
7cc832b9 1125 */
75ee87c8
TG
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));
7cc832b9
TG
1130
1131 link->flags = flags;
1132
505f8da7
TG
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;
efbc88b8 1139
ffba6166
TG
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)
3379e257 1146 log_debug_link(link, "link is lower up");
ffba6166 1147 else if (flags_removed & IFF_LOWER_UP)
3379e257 1148 log_debug_link(link, "link is lower down");
ffba6166 1149
75ee87c8
TG
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");
ffba6166 1154
c6a1eb79
TG
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
069e10a0 1190 /* link flags are currently at most 18 bits, let's default to printing 20 */
505f8da7 1191 if (flags_added & generic_flags)
069e10a0 1192 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
505f8da7
TG
1193 flags_added & generic_flags);
1194
1195 if (flags_removed & generic_flags)
069e10a0 1196 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
75ee87c8 1197 flags_removed & generic_flags);
505f8da7 1198
7cc832b9
TG
1199 if (carrier_gained) {
1200 log_info_link(link, "gained carrier");
ffba6166
TG
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;
ff254138 1208 }
ffba6166 1209 }
7cc832b9
TG
1210 } else if (carrier_lost) {
1211 log_info_link(link, "lost carrier");
efbc88b8 1212
ffba6166
TG
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;
ff254138 1219 }
ffba6166 1220 }
5c1d3fc9 1221
ffba6166
TG
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;
5c1d3fc9 1228 }
ff254138
TG
1229 }
1230 }
1231
ff254138
TG
1232 return 0;
1233}
1234
dd3efc09
TG
1235static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1236 Link *link = userdata;
1237 int r;
1238
1746cf2a
TG
1239 assert(link);
1240
1241 if (link->state == LINK_STATE_FAILED)
1242 return 1;
1243
dd3efc09 1244 r = sd_rtnl_message_get_errno(m);
45ad2c13 1245 if (r < 0) {
76800848 1246 log_struct_link(LOG_WARNING, link,
c9ccc19f
TG
1247 "MESSAGE=%s: could not bring up interface: %s",
1248 link->ifname, strerror(-r),
1249 "ERRNO=%d", -r,
1250 NULL);
45ad2c13
TG
1251 link_enter_failed(link);
1252 }
1253
f882c247
TG
1254 return 1;
1255}
1256
1257static int link_up(Link *link) {
cf6a8911 1258 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
1259 int r;
1260
f882c247
TG
1261 assert(link);
1262 assert(link->manager);
1263 assert(link->manager->rtnl);
1264
39032b87 1265 log_debug_link(link, "bringing link up");
449f7554 1266
151b9b96
LP
1267 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1268 RTM_SETLINK, link->ifindex);
f579559b 1269 if (r < 0) {
39032b87 1270 log_error_link(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1271 return r;
1272 }
1273
5d4795f3 1274 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1275 if (r < 0) {
3333d748 1276 log_error_link(link, "Could not set link flags: %s", strerror(-r));
fc25d7f8
TG
1277 return r;
1278 }
1279
dd3efc09 1280 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
f579559b 1281 if (r < 0) {
3333d748
ZJS
1282 log_error_link(link,
1283 "Could not send rtnetlink message: %s", strerror(-r));
f579559b
TG
1284 return r;
1285 }
1286
f882c247
TG
1287 return 0;
1288}
1289
52433f6b 1290static int link_enslaved(Link *link) {
f882c247
TG
1291 int r;
1292
ef1ba606 1293 assert(link);
52433f6b 1294 assert(link->state == LINK_STATE_ENSLAVING);
f5be5601 1295 assert(link->network);
dd3efc09 1296
505f8da7
TG
1297 if (!(link->flags & IFF_UP)) {
1298 r = link_up(link);
1299 if (r < 0) {
1300 link_enter_failed(link);
1301 return r;
1302 }
ef1ba606 1303 }
f882c247 1304
5c1d3fc9 1305 if (!link->network->dhcp && !link->network->ipv4ll)
1746cf2a 1306 return link_enter_set_addresses(link);
ef1ba606
TG
1307
1308 return 0;
02b59d57
TG
1309}
1310
52433f6b 1311static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
02b59d57
TG
1312 Link *link = userdata;
1313 int r;
1314
1746cf2a 1315 assert(link);
52433f6b 1316 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
ef1ba606 1317 assert(link->network);
02b59d57 1318
52433f6b
TG
1319 link->enslaving --;
1320
02b59d57
TG
1321 if (link->state == LINK_STATE_FAILED)
1322 return 1;
1323
1324 r = sd_rtnl_message_get_errno(m);
ef1ba606 1325 if (r < 0) {
c9ccc19f
TG
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);
ef1ba606
TG
1331 link_enter_failed(link);
1332 return 1;
3333d748 1333 }
02b59d57 1334
52433f6b 1335 log_debug_link(link, "enslaved");
ab47d620 1336
52433f6b
TG
1337 if (link->enslaving == 0)
1338 link_enslaved(link);
02b59d57
TG
1339
1340 return 1;
1341}
1342
52433f6b 1343static int link_enter_enslave(Link *link) {
fe6b2d55 1344 NetDev *vlan, *macvlan;
672682a6 1345 Iterator i;
02b59d57
TG
1346 int r;
1347
1348 assert(link);
1349 assert(link->network);
505f8da7 1350 assert(link->state == LINK_STATE_INITIALIZING);
02b59d57 1351
52433f6b 1352 link->state = LINK_STATE_ENSLAVING;
02b59d57 1353
fe8db0c5
TG
1354 link_save(link);
1355
63ffa720 1356 if (!link->network->bridge && !link->network->bond &&
fe6b2d55
TG
1357 hashmap_isempty(link->network->vlans) &&
1358 hashmap_isempty(link->network->macvlans))
52433f6b 1359 return link_enslaved(link);
02b59d57 1360
52433f6b
TG
1361 if (link->network->bridge) {
1362 log_struct_link(LOG_DEBUG, link,
1363 "MESSAGE=%s: enslaving by '%s'",
c9ccc19f 1364 link->ifname, link->network->bridge->name,
52433f6b
TG
1365 NETDEV(link->network->bridge),
1366 NULL);
449f7554 1367
52433f6b
TG
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",
c9ccc19f 1372 link->ifname, link->network->bridge->name, strerror(-r),
52433f6b
TG
1373 NETDEV(link->network->bridge),
1374 NULL);
1375 link_enter_failed(link);
1376 return r;
1377 }
1378
0ad6148e
MO
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
52433f6b
TG
1400 link->enslaving ++;
1401 }
1402
672682a6 1403 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
52433f6b
TG
1404 log_struct_link(LOG_DEBUG, link,
1405 "MESSAGE=%s: enslaving by '%s'",
672682a6 1406 link->ifname, vlan->name, NETDEV(vlan), NULL);
52433f6b 1407
672682a6 1408 r = netdev_enslave(vlan, link, &enslave_handler);
52433f6b
TG
1409 if (r < 0) {
1410 log_struct_link(LOG_WARNING, link,
1411 "MESSAGE=%s: could not enslave by '%s': %s",
672682a6
TG
1412 link->ifname, vlan->name, strerror(-r),
1413 NETDEV(vlan), NULL);
52433f6b
TG
1414 link_enter_failed(link);
1415 return r;
1416 }
1417
1418 link->enslaving ++;
ef1ba606
TG
1419 }
1420
fe6b2d55
TG
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
ef1ba606
TG
1439 return 0;
1440}
1441
a748b692 1442static int link_configure(Link *link) {
02b59d57
TG
1443 int r;
1444
ef1ba606 1445 assert(link);
505f8da7 1446 assert(link->state == LINK_STATE_INITIALIZING);
a748b692 1447
eb34d4af 1448 if (link->network->ipv4ll) {
b5db00e5 1449 uint8_t seed[8];
45ad2c13 1450
eb34d4af
TG
1451 r = sd_ipv4ll_new(&link->ipv4ll);
1452 if (r < 0)
1453 return r;
1454
505f8da7
TG
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 }
b5db00e5
UTL
1462 }
1463
eb34d4af
TG
1464 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1465 if (r < 0)
1466 return r;
1467
4bb40e81
TG
1468 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1469 if (r < 0)
1470 return r;
1471
eb34d4af
TG
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
4bb40e81
TG
1490 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1491 if (r < 0)
1492 return r;
1493
eb34d4af
TG
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
505f8da7
TG
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);
57bd6899
TG
1530 if (r == -ENOENT) {
1531 link_enter_unmanaged(link);
1532 return 0;
1533 } else if (r < 0)
1534 return r;
505f8da7
TG
1535
1536 r = network_apply(link->manager, network, link);
1537 if (r < 0)
1538 return r;
1539
a748b692
TG
1540 r = link_configure(link);
1541 if (r < 0)
1542 return r;
1543
505f8da7
TG
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
a748b692
TG
1590 return 0;
1591}
1592
22936833
TG
1593int link_update(Link *link, sd_rtnl_message *m) {
1594 unsigned flags;
c49b33ac 1595 struct ether_addr mac;
b8941f74 1596 char *ifname;
22936833
TG
1597 int r;
1598
dd3efc09 1599 assert(link);
b8941f74 1600 assert(link->ifname);
22936833
TG
1601 assert(m);
1602
57bd6899 1603 if (link->state == LINK_STATE_FAILED || link->state == LINK_STATE_UNMANAGED)
1746cf2a
TG
1604 return 0;
1605
b8941f74
TG
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
505f8da7 1616 if (!link->original_mtu) {
9842de0d
TG
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 }
69629de9 1622
e9189a1f
TG
1623 /* The kernel may broadcast NEWLINK messages without the MAC address
1624 set, simply ignore them. */
c49b33ac 1625 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 1626 if (r >= 0) {
20861203 1627 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
c49b33ac 1628
20861203 1629 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
c49b33ac 1630
20861203
TG
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]);
c49b33ac 1639
20861203
TG
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 }
c49b33ac 1648 }
c49b33ac 1649
20861203
TG
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 }
c49b33ac
TG
1658 }
1659 }
4f882b2a
TG
1660 }
1661
a748b692
TG
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
ff254138 1668 return link_update_flags(link, flags);
dd3efc09 1669}
fe8db0c5
TG
1670
1671int link_save(Link *link) {
1672 _cleanup_free_ char *temp_path = NULL;
1673 _cleanup_fclose_ FILE *f = NULL;
7ff8f4b5 1674 const char *state;
fe8db0c5
TG
1675 int r;
1676
1677 assert(link);
1678 assert(link->state_file);
1679
7ff8f4b5 1680 state = link_state_to_string(link->state);
70280736 1681 assert(state);
7ff8f4b5 1682
fe8db0c5
TG
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"
7ff8f4b5 1691 "STATE=%s\n", state);
fe8db0c5
TG
1692
1693 if (link->dhcp_lease) {
fd88eb8a 1694 _cleanup_free_ char *lease_file = NULL;
2a1763ed 1695
315db1a8
ZJS
1696 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1697 link->ifindex);
2a1763ed 1698 if (r < 0)
315db1a8 1699 return -ENOMEM;
fe8db0c5
TG
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] = {
505f8da7 1724 [LINK_STATE_INITIALIZING] = "configuring",
fe8db0c5
TG
1725 [LINK_STATE_ENSLAVING] = "configuring",
1726 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1727 [LINK_STATE_SETTING_ROUTES] = "configuring",
1728 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 1729 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5
TG
1730 [LINK_STATE_FAILED] = "failed",
1731};
1732
1733DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);