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