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