]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
networkd: link - make check for whether addresses/routes are being configured implicit
[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>
4cc7a82c 24#include <unistd.h>
f579559b 25
0b1831c2 26#include "networkd-link.h"
3be1d7e0 27#include "networkd-netdev.h"
f579559b 28#include "libudev-private.h"
505f8da7 29#include "udev-util.h"
f579559b 30#include "util.h"
505f8da7 31#include "virt.h"
1346b1f0 32#include "bus-util.h"
c6f7c917 33#include "network-internal.h"
ed942a9e 34#include "conf-parser.h"
f579559b 35
fe8db0c5
TG
36#include "dhcp-lease-internal.h"
37
505f8da7 38static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
14b746f7 39 _cleanup_link_unref_ Link *link = NULL;
505f8da7 40 uint16_t type;
ca4e095a 41 const char *ifname;
505f8da7 42 int r, ifindex;
f579559b 43
0c2f9b84 44 assert(manager);
505f8da7 45 assert(message);
f579559b
TG
46 assert(ret);
47
505f8da7
TG
48 r = sd_rtnl_message_get_type(message, &type);
49 if (r < 0)
50 return r;
51 else if (type != RTM_NEWLINK)
52 return -EINVAL;
53
54 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
55 if (r < 0)
56 return r;
57 else if (ifindex <= 0)
58 return -EINVAL;
59
60 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
61 if (r < 0)
62 return r;
63
f579559b
TG
64 link = new0(Link, 1);
65 if (!link)
66 return -ENOMEM;
67
14b746f7 68 link->n_ref = 1;
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
512922f8
TG
76 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
77 if (r < 0)
1a941ac4 78 log_debug_link(link, "MAC address not found for new device, continuing without");
512922f8 79
ae06ab10 80 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex);
fe8db0c5 81 if (r < 0)
315db1a8 82 return -ENOMEM;
fe8db0c5 83
ae06ab10 84 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex);
68a8723c
TG
85 if (r < 0)
86 return -ENOMEM;
87
ae06ab10
TG
88 r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
89 if (r < 0)
90 return r;
91
92 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
f579559b
TG
93 if (r < 0)
94 return r;
95
96 *ret = link;
97 link = NULL;
98
99 return 0;
100}
101
14b746f7 102static void link_free(Link *link) {
428fd0a7
TG
103 Address *address;
104
f579559b
TG
105 if (!link)
106 return;
107
428fd0a7
TG
108 while ((address = link->addresses)) {
109 LIST_REMOVE(addresses, link->addresses, address);
110 address_free(address);
111 }
112
11bf3cce
LP
113 while ((address = link->pool_addresses)) {
114 LIST_REMOVE(addresses, link->pool_addresses, address);
115 address_free(address);
116 }
117
e5b04c8d 118 sd_dhcp_client_unref(link->dhcp_client);
a6cc569e 119 sd_dhcp_lease_unref(link->dhcp_lease);
f5be5601 120
68a8723c
TG
121 unlink(link->lease_file);
122 free(link->lease_file);
123
56cd007a 124 sd_ipv4ll_unref(link->ipv4ll);
4138fb2c 125 sd_dhcp6_client_unref(link->dhcp6_client);
6b66097b 126 sd_icmp6_nd_unref(link->icmp6_router_discovery);
4138fb2c 127
28aeb07f 128 if (link->manager)
ae06ab10 129 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
f579559b 130
c166a070 131 free(link->ifname);
68a8723c
TG
132
133 unlink(link->state_file);
fe8db0c5 134 free(link->state_file);
c166a070 135
b5db00e5
UTL
136 udev_device_unref(link->udev_device);
137
f579559b
TG
138 free(link);
139}
140
14b746f7
TG
141Link *link_unref(Link *link) {
142 if (link && (-- link->n_ref <= 0))
143 link_free(link);
144
145 return NULL;
146}
147
148Link *link_ref(Link *link) {
149 if (link)
150 assert_se(++ link->n_ref >= 2);
151
152 return link;
153}
154
11a7f229
TG
155int link_get(Manager *m, int ifindex, Link **ret) {
156 Link *link;
11a7f229
TG
157
158 assert(m);
11a7f229
TG
159 assert(ifindex);
160 assert(ret);
161
ae06ab10 162 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
11a7f229
TG
163 if (!link)
164 return -ENODEV;
165
166 *ret = link;
167
168 return 0;
169}
170
370e9930
TG
171void link_drop(Link *link) {
172 if (!link || link->state == LINK_STATE_LINGER)
173 return;
174
175 link->state = LINK_STATE_LINGER;
176
7619683b 177 log_debug_link(link, "link removed");
370e9930
TG
178
179 link_unref(link);
180
181 return;
182}
183
57bd6899
TG
184static void link_enter_unmanaged(Link *link) {
185 assert(link);
186
df9aa406 187 log_debug_link(link, "unmanaged");
57bd6899
TG
188
189 link->state = LINK_STATE_UNMANAGED;
190
191 link_save(link);
192}
193
111bb8f9
TG
194static int link_stop_clients(Link *link) {
195 int r = 0, k;
196
197 assert(link);
198 assert(link->manager);
199 assert(link->manager->event);
200
201 if (!link->network)
202 return 0;
203
ba179154 204 if (link->dhcp_client) {
111bb8f9
TG
205 k = sd_dhcp_client_stop(link->dhcp_client);
206 if (k < 0) {
207 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
208 r = k;
209 }
210 }
211
ba179154 212 if (link->ipv4ll) {
111bb8f9
TG
213 k = sd_ipv4ll_stop(link->ipv4ll);
214 if (k < 0) {
215 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
216 r = k;
217 }
218 }
219
ba179154 220 if (link->dhcp_server) {
dd43110f
TG
221 k = sd_dhcp_server_stop(link->dhcp_server);
222 if (k < 0) {
223 log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
224 r = k;
225 }
226 }
227
ba179154 228 if(link->icmp6_router_discovery) {
1873a3d3
PF
229
230 if (link->dhcp6_client) {
231 k = sd_dhcp6_client_stop(link->dhcp6_client);
232 if (k < 0) {
233 log_warning_link(link, "Could not stop DHCPv6 client: %s", strerror(-r));
234 r = k;
235 }
236 }
4138fb2c 237
1873a3d3 238 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
4138fb2c 239 if (k < 0) {
1873a3d3 240 log_warning_link(link, "Could not stop ICMPv6 router discovery: %s", strerror(-r));
4138fb2c
PF
241 r = k;
242 }
243 }
244
111bb8f9
TG
245 return r;
246}
247
ef1ba606
TG
248static void link_enter_failed(Link *link) {
249 assert(link);
f882c247 250
370e9930 251 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2139694e
TG
252 return;
253
39032b87 254 log_warning_link(link, "failed");
449f7554 255
ef1ba606 256 link->state = LINK_STATE_FAILED;
fe8db0c5 257
111bb8f9
TG
258 link_stop_clients(link);
259
fe8db0c5 260 link_save(link);
f882c247
TG
261}
262
4f434938
LP
263static Address* link_find_dhcp_server_address(Link *link) {
264 Address *address;
265
266 assert(link);
267 assert(link->network);
268
269 /* The the first statically configured address if there is any */
270 LIST_FOREACH(addresses, address, link->network->static_addresses) {
271
272 if (address->family != AF_INET)
273 continue;
274
af93291c 275 if (in_addr_is_null(address->family, &address->in_addr))
4f434938
LP
276 continue;
277
278 return address;
279 }
280
281 /* If that didn't work, find a suitable address we got from the pool */
282 LIST_FOREACH(addresses, address, link->pool_addresses) {
283 if (address->family != AF_INET)
284 continue;
285
286 return address;
287 }
288
289 return NULL;
290}
291
dd43110f
TG
292static int link_enter_configured(Link *link) {
293 int r;
294
295 assert(link);
296 assert(link->network);
297 assert(link->state == LINK_STATE_SETTING_ROUTES);
298
7c16313f
TG
299 if (link->network->dhcp_server &&
300 !sd_dhcp_server_is_running(link->dhcp_server)) {
4f434938
LP
301 struct in_addr pool_start;
302 Address *address;
303
304 address = link_find_dhcp_server_address(link);
305 if (!address) {
306 log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
307 link_enter_failed(link);
308 return 0;
309 }
310
dd43110f
TG
311 log_debug_link(link, "offering DHCPv4 leases");
312
59b8f6b6 313 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in, address->prefixlen);
4f434938
LP
314 if (r < 0)
315 return r;
316
317 /* offer 32 addresses starting from the address following the server address */
318 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
319 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
320 &pool_start, 32);
321 if (r < 0)
322 return r;
323
324 /* TODO:
325 r = sd_dhcp_server_set_router(link->dhcp_server,
326 &main_address->in_addr.in);
327 if (r < 0)
328 return r;
329
330 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
331 main_address->prefixlen);
332 if (r < 0)
333 return r;
334 */
335
dd43110f
TG
336 r = sd_dhcp_server_start(link->dhcp_server);
337 if (r < 0) {
338 log_warning_link(link, "could not start DHCPv4 server "
339 "instance: %s", strerror(-r));
340
341 link_enter_failed(link);
342
343 return 0;
344 }
345 }
346
347 log_info_link(link, "link configured");
348
349 link->state = LINK_STATE_CONFIGURED;
350
351 link_save(link);
352
353 return 0;
354}
355
f882c247 356static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 357 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
358 int r;
359
f5be5601 360 assert(link->route_messages > 0);
370e9930
TG
361 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
362 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
363 LINK_STATE_LINGER));
f882c247 364
f5be5601 365 link->route_messages --;
f882c247 366
5da8149f 367 if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
368 return 1;
369
370 r = sd_rtnl_message_get_errno(m);
c166a070 371 if (r < 0 && r != -EEXIST)
c9ccc19f 372 log_struct_link(LOG_WARNING, link,
97578344 373 "MESSAGE=%-*s: could not set route: %s",
987efa17 374 IFNAMSIZ,
c9ccc19f
TG
375 link->ifname, strerror(-r),
376 "ERRNO=%d", -r,
377 NULL);
f882c247 378
f5be5601
TG
379 /* we might have received an old reply after moving back to SETTING_ADDRESSES,
380 * ignore it */
381 if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
39032b87 382 log_debug_link(link, "routes set");
dd3efc09
TG
383 link_enter_configured(link);
384 }
f882c247
TG
385
386 return 1;
387}
388
e1ea665e
EY
389static int link_set_dhcp_routes(Link *link) {
390 struct sd_dhcp_route *static_routes;
a2ba62c7 391 int r, n, i;
e1ea665e
EY
392
393 assert(link);
394
a2ba62c7
LP
395 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
396 if (n < 0) {
397 if (n != -ENOENT)
398 log_warning_link(link, "DHCP error: could not get routes: %s", strerror(-n));
399 return n;
e1ea665e
EY
400 }
401
a2ba62c7 402 for (i = 0; i < n; i++) {
e1ea665e
EY
403 _cleanup_route_free_ Route *route = NULL;
404
28cc555d 405 r = route_new_dynamic(&route, RTPROT_DHCP);
e1ea665e
EY
406 if (r < 0) {
407 log_error_link(link, "Could not allocate route: %s",
408 strerror(-r));
409 return r;
410 }
411
412 route->family = AF_INET;
413 route->in_addr.in = static_routes[i].gw_addr;
414 route->dst_addr.in = static_routes[i].dst_addr;
415 route->dst_prefixlen = static_routes[i].dst_prefixlen;
4faefc7f 416 route->metrics = DHCP_ROUTE_METRIC;
e1ea665e
EY
417
418 r = route_configure(route, link, &route_handler);
419 if (r < 0) {
420 log_warning_link(link,
421 "could not set host route: %s", strerror(-r));
422 return r;
423 }
424
e1ea665e
EY
425 link->route_messages ++;
426 }
427
428 return 0;
429}
430
ba179154
TG
431static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
432 int r;
433 struct in_addr addr;
434
435 if (!ll)
436 return false;
437
438 r = sd_ipv4ll_get_address(ll, &addr);
439 if (r < 0)
440 return false;
441
442 return true;
443}
444
f882c247 445static int link_enter_set_routes(Link *link) {
a6cc569e 446 Route *rt;
f882c247
TG
447 int r;
448
449 assert(link);
450 assert(link->network);
ef1ba606 451 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 452
ef1ba606 453 link->state = LINK_STATE_SETTING_ROUTES;
f882c247 454
3d3d4255 455 LIST_FOREACH(routes, rt, link->network->static_routes) {
a6cc569e 456 r = route_configure(rt, link, &route_handler);
dd3efc09 457 if (r < 0) {
3333d748
ZJS
458 log_warning_link(link,
459 "could not set routes: %s", strerror(-r));
ef1ba606
TG
460 link_enter_failed(link);
461 return r;
dd3efc09 462 }
c166a070 463
f5be5601
TG
464 link->route_messages ++;
465 }
466
ba179154 467 if (ipv4ll_is_bound(link->ipv4ll)) {
5c1d3fc9 468 _cleanup_route_free_ Route *route = NULL;
5c1d3fc9 469
ba179154
TG
470 r = route_new_dynamic(&route, RTPROT_STATIC);
471 if (r < 0) {
472 log_error_link(link, "Could not allocate route: %s",
473 strerror(-r));
474 return r;
475 }
5c1d3fc9 476
ba179154
TG
477 route->family = AF_INET;
478 route->scope = RT_SCOPE_LINK;
479 route->metrics = IPV4LL_ROUTE_METRIC;
5c1d3fc9 480
ba179154
TG
481 r = route_configure(route, link, &route_handler);
482 if (r < 0) {
483 log_warning_link(link,
484 "could not set routes: %s", strerror(-r));
485 link_enter_failed(link);
486 return r;
5c1d3fc9 487 }
ba179154
TG
488
489 link->route_messages ++;
5c1d3fc9
UTL
490 }
491
a6cc569e
TG
492 if (link->dhcp_lease) {
493 _cleanup_route_free_ Route *route = NULL;
9765ce69 494 _cleanup_route_free_ Route *route_gw = NULL;
a6cc569e
TG
495 struct in_addr gateway;
496
497 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
8ddbeaa2 498 if (r < 0 && r != -ENOENT) {
b1666580
TG
499 log_warning_link(link, "DHCP error: could not get gateway: %s",
500 strerror(-r));
a6cc569e
TG
501 return r;
502 }
503
8ddbeaa2 504 if (r >= 0) {
28cc555d 505 r = route_new_dynamic(&route, RTPROT_DHCP);
8ddbeaa2
UTL
506 if (r < 0) {
507 log_error_link(link, "Could not allocate route: %s",
508 strerror(-r));
509 return r;
510 }
a6cc569e 511
28cc555d 512 r = route_new_dynamic(&route_gw, RTPROT_DHCP);
8ddbeaa2
UTL
513 if (r < 0) {
514 log_error_link(link, "Could not allocate route: %s",
515 strerror(-r));
516 return r;
517 }
9765ce69 518
8ddbeaa2
UTL
519 /* The dhcp netmask may mask out the gateway. Add an explicit
520 * route for the gw host so that we can route no matter the
521 * netmask or existing kernel route tables. */
522 route_gw->family = AF_INET;
523 route_gw->dst_addr.in = gateway;
524 route_gw->dst_prefixlen = 32;
525 route_gw->scope = RT_SCOPE_LINK;
4faefc7f 526 route_gw->metrics = DHCP_ROUTE_METRIC;
9765ce69 527
8ddbeaa2
UTL
528 r = route_configure(route_gw, link, &route_handler);
529 if (r < 0) {
530 log_warning_link(link,
531 "could not set host route: %s", strerror(-r));
532 return r;
533 }
9765ce69 534
8ddbeaa2 535 link->route_messages ++;
9765ce69 536
8ddbeaa2
UTL
537 route->family = AF_INET;
538 route->in_addr.in = gateway;
4faefc7f 539 route->metrics = DHCP_ROUTE_METRIC;
a6cc569e 540
8ddbeaa2
UTL
541 r = route_configure(route, link, &route_handler);
542 if (r < 0) {
543 log_warning_link(link,
544 "could not set routes: %s", strerror(-r));
545 link_enter_failed(link);
546 return r;
547 }
548
549 link->route_messages ++;
f5be5601 550 }
e1ea665e
EY
551
552 if (link->network->dhcp_routes)
553 link_set_dhcp_routes(link);
8ddbeaa2 554 }
f5be5601 555
8ddbeaa2
UTL
556 if (link->route_messages == 0) {
557 link_enter_configured(link);
431ca2ce
TG
558 } else
559 log_debug_link(link, "setting routes");
f882c247
TG
560
561 return 0;
562}
563
5c1d3fc9 564static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 565 _cleanup_link_unref_ Link *link = userdata;
5c1d3fc9
UTL
566 int r;
567
568 assert(m);
569 assert(link);
570 assert(link->ifname);
571
5da8149f 572 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
5c1d3fc9
UTL
573 return 1;
574
575 r = sd_rtnl_message_get_errno(m);
b90b025a 576 if (r < 0 && r != -ESRCH)
5c1d3fc9 577 log_struct_link(LOG_WARNING, link,
97578344 578 "MESSAGE=%-*s: could not drop route: %s",
987efa17 579 IFNAMSIZ,
5c1d3fc9
UTL
580 link->ifname, strerror(-r),
581 "ERRNO=%d", -r,
582 NULL);
583
5bdd314c 584 return 1;
5c1d3fc9
UTL
585}
586
4958aee4
TG
587static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
588 _cleanup_link_unref_ Link *link = userdata;
589 int r;
590
591 assert(rtnl);
592 assert(m);
593 assert(link);
594 assert(link->manager);
595
596 for (; m; m = sd_rtnl_message_next(m)) {
597 r = sd_rtnl_message_get_errno(m);
598 if (r < 0) {
599 log_debug_link(link, "getting address failed: %s", strerror(-r));
600 continue;
601 }
602
603 r = link_rtnl_process_address(rtnl, m, link->manager);
604 if (r < 0)
605 log_warning_link(link, "could not process address: %s", strerror(-r));
606 }
607
608 return 1;
609}
610
f882c247 611static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 612 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
613 int r;
614
4958aee4 615 assert(rtnl);
f5be5601
TG
616 assert(m);
617 assert(link);
618 assert(link->ifname);
619 assert(link->addr_messages > 0);
370e9930
TG
620 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
621 LINK_STATE_FAILED, LINK_STATE_LINGER));
f882c247 622
f5be5601 623 link->addr_messages --;
f882c247 624
5da8149f 625 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
626 return 1;
627
628 r = sd_rtnl_message_get_errno(m);
c166a070 629 if (r < 0 && r != -EEXIST)
c9ccc19f 630 log_struct_link(LOG_WARNING, link,
97578344 631 "MESSAGE=%-*s: could not set address: %s",
987efa17 632 IFNAMSIZ,
3333d748
ZJS
633 link->ifname, strerror(-r),
634 "ERRNO=%d", -r,
635 NULL);
5bdd314c 636 else if (r >= 0) {
4958aee4
TG
637 /* calling handler directly so take a ref */
638 link_ref(link);
639 link_get_address_handler(rtnl, m, link);
640 }
f882c247 641
f5be5601 642 if (link->addr_messages == 0) {
39032b87 643 log_debug_link(link, "addresses set");
ef1ba606 644 link_enter_set_routes(link);
dd3efc09 645 }
f882c247
TG
646
647 return 1;
648}
649
650static int link_enter_set_addresses(Link *link) {
a6cc569e 651 Address *ad;
f882c247 652 int r;
68ceb9df 653 uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
f882c247
TG
654
655 assert(link);
656 assert(link->network);
f5be5601 657 assert(link->state != _LINK_STATE_INVALID);
f882c247 658
ef1ba606 659 link->state = LINK_STATE_SETTING_ADDRESSES;
f882c247 660
3d3d4255 661 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
a6cc569e 662 r = address_configure(ad, link, &address_handler);
dd3efc09 663 if (r < 0) {
3333d748
ZJS
664 log_warning_link(link,
665 "could not set addresses: %s", strerror(-r));
ef1ba606
TG
666 link_enter_failed(link);
667 return r;
dd3efc09 668 }
c166a070 669
f5be5601
TG
670 link->addr_messages ++;
671 }
672
ba179154 673 if (link->ipv4ll) {
5c1d3fc9
UTL
674 _cleanup_address_free_ Address *ll_addr = NULL;
675 struct in_addr addr;
676
677 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
678 if (r < 0 && r != -ENOENT) {
679 log_warning_link(link, "IPV4LL error: no address: %s",
680 strerror(-r));
681 return r;
682 }
683
684 if (r != -ENOENT) {
685 r = address_new_dynamic(&ll_addr);
686 if (r < 0) {
687 log_error_link(link, "Could not allocate address: %s", strerror(-r));
688 return r;
689 }
690
691 ll_addr->family = AF_INET;
692 ll_addr->in_addr.in = addr;
693 ll_addr->prefixlen = 16;
694 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
695 ll_addr->scope = RT_SCOPE_LINK;
696
697 r = address_configure(ll_addr, link, &address_handler);
698 if (r < 0) {
699 log_warning_link(link,
700 "could not set addresses: %s", strerror(-r));
701 link_enter_failed(link);
702 return r;
703 }
704
705 link->addr_messages ++;
706 }
707 }
708
a6cc569e
TG
709 if (link->dhcp_lease) {
710 _cleanup_address_free_ Address *address = NULL;
711 struct in_addr addr;
712 struct in_addr netmask;
713 unsigned prefixlen;
714
715 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
716 if (r < 0) {
717 log_warning_link(link, "DHCP error: no address: %s",
718 strerror(-r));
719 return r;
720 }
721
68ceb9df
PF
722 if (!link->network->dhcp_critical) {
723 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease,
724 &lifetime);
725 if (r < 0) {
726 log_warning_link(link, "DHCP error: no lifetime: %s",
727 strerror(-r));
728 return r;
729 }
730 }
731
a6cc569e
TG
732 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
733 if (r < 0) {
734 log_warning_link(link, "DHCP error: no netmask: %s",
735 strerror(-r));
736 return r;
737 }
738
44e7b949 739 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
a6cc569e
TG
740
741 r = address_new_dynamic(&address);
742 if (r < 0) {
743 log_error_link(link, "Could not allocate address: %s",
744 strerror(-r));
745 return r;
746 }
747
748 address->family = AF_INET;
749 address->in_addr.in = addr;
68ceb9df
PF
750 address->cinfo.ifa_prefered = lifetime;
751 address->cinfo.ifa_valid = lifetime;
a6cc569e
TG
752 address->prefixlen = prefixlen;
753 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
754
46ba9fba
TG
755 /* use update rather than configure so that we will update the lifetime
756 of an existing address if it has already been configured */
757 r = address_update(address, link, &address_handler);
f5be5601 758 if (r < 0) {
3333d748
ZJS
759 log_warning_link(link,
760 "could not set addresses: %s", strerror(-r));
f5be5601
TG
761 link_enter_failed(link);
762 return r;
763 }
764
765 link->addr_messages ++;
f882c247
TG
766 }
767
431ca2ce
TG
768 if (link->addr_messages == 0) {
769 link_enter_set_routes(link);
770 } else
771 log_debug_link(link, "setting addresses");
772
f882c247
TG
773 return 0;
774}
775
ff254138 776static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 777 _cleanup_link_unref_ Link *link = userdata;
ff254138
TG
778 int r;
779
780 assert(m);
781 assert(link);
782 assert(link->ifname);
783
5da8149f 784 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ff254138
TG
785 return 1;
786
787 r = sd_rtnl_message_get_errno(m);
b90b025a 788 if (r < 0 && r != -EADDRNOTAVAIL)
c9ccc19f 789 log_struct_link(LOG_WARNING, link,
97578344 790 "MESSAGE=%-*s: could not drop address: %s",
987efa17 791 IFNAMSIZ,
c9ccc19f
TG
792 link->ifname, strerror(-r),
793 "ERRNO=%d", -r,
794 NULL);
ff254138 795
5bdd314c 796 return 1;
ff254138
TG
797}
798
1346b1f0 799static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
5da8149f 800 _cleanup_link_unref_ Link *link = userdata;
1346b1f0
TG
801 int r;
802
b226d99b
TG
803 assert(link);
804
5da8149f 805 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
370e9930 806 return 1;
370e9930 807
1346b1f0
TG
808 r = sd_bus_message_get_errno(m);
809 if (r < 0)
70b34f5d
MM
810 r = -r;
811 if (r > 0)
812 log_warning_link(link, "Could not set hostname: %s", strerror(r));
1346b1f0
TG
813
814 return 1;
815}
816
b226d99b 817static int link_set_hostname(Link *link, const char *hostname) {
1346b1f0
TG
818 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
819 int r = 0;
820
b226d99b
TG
821 assert(link);
822 assert(link->manager);
1346b1f0
TG
823 assert(hostname);
824
b226d99b 825 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
1346b1f0 826
b226d99b
TG
827 if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
828 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
bcbca829
TG
829 return 0;
830 }
831
1346b1f0 832 r = sd_bus_message_new_method_call(
b226d99b 833 link->manager->bus,
151b9b96 834 &m,
1346b1f0
TG
835 "org.freedesktop.hostname1",
836 "/org/freedesktop/hostname1",
837 "org.freedesktop.hostname1",
151b9b96 838 "SetHostname");
1346b1f0
TG
839 if (r < 0)
840 return r;
841
842 r = sd_bus_message_append(m, "sb", hostname, false);
843 if (r < 0)
844 return r;
845
19befb2d 846 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
5da8149f 847 if (r < 0) {
b226d99b 848 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
5da8149f
TG
849 return r;
850 }
b226d99b
TG
851
852 link_ref(link);
1346b1f0 853
5da8149f 854 return 0;
1346b1f0
TG
855}
856
4f882b2a 857static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 858 _cleanup_link_unref_ Link *link = userdata;
4f882b2a
TG
859 int r;
860
861 assert(m);
862 assert(link);
863 assert(link->ifname);
864
5da8149f 865 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
4f882b2a
TG
866 return 1;
867
868 r = sd_rtnl_message_get_errno(m);
c9ccc19f
TG
869 if (r < 0)
870 log_struct_link(LOG_WARNING, link,
97578344
TG
871 "MESSAGE=%-*s: could not set MTU: %s",
872 IFNAMSIZ, link->ifname, strerror(-r),
c9ccc19f
TG
873 "ERRNO=%d", -r,
874 NULL);
4f882b2a
TG
875
876 return 1;
877}
878
879static int link_set_mtu(Link *link, uint32_t mtu) {
cf6a8911 880 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
4f882b2a
TG
881 int r;
882
883 assert(link);
884 assert(link->manager);
885 assert(link->manager->rtnl);
886
887 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
888
151b9b96
LP
889 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
890 RTM_SETLINK, link->ifindex);
4f882b2a
TG
891 if (r < 0) {
892 log_error_link(link, "Could not allocate RTM_SETLINK message");
893 return r;
894 }
895
896 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
897 if (r < 0) {
898 log_error_link(link, "Could not append MTU: %s", strerror(-r));
899 return r;
900 }
901
902 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
903 if (r < 0) {
904 log_error_link(link,
905 "Could not send rtnetlink message: %s", strerror(-r));
906 return r;
907 }
908
ae941762 909 link_ref(link);
b226d99b 910
4f882b2a
TG
911 return 0;
912}
913
a6cc569e
TG
914static int dhcp_lease_lost(Link *link) {
915 _cleanup_address_free_ Address *address = NULL;
916 struct in_addr addr;
917 struct in_addr netmask;
3e790eae 918 struct in_addr gateway;
a6cc569e 919 unsigned prefixlen;
ff254138
TG
920 int r;
921
922 assert(link);
a6cc569e 923 assert(link->dhcp_lease);
ff254138 924
14efd761
TG
925 log_warning_link(link, "DHCP lease lost");
926
e1ea665e
EY
927 if (link->network->dhcp_routes) {
928 struct sd_dhcp_route *routes;
a2ba62c7 929 int n, i;
e1ea665e 930
a2ba62c7
LP
931 n = sd_dhcp_lease_get_routes(link->dhcp_lease, &routes);
932 if (n >= 0) {
933 for (i = 0; i < n; i++) {
e1ea665e
EY
934 _cleanup_route_free_ Route *route = NULL;
935
28cc555d 936 r = route_new_dynamic(&route, RTPROT_UNSPEC);
e1ea665e
EY
937 if (r >= 0) {
938 route->family = AF_INET;
939 route->in_addr.in = routes[i].gw_addr;
940 route->dst_addr.in = routes[i].dst_addr;
941 route->dst_prefixlen = routes[i].dst_prefixlen;
942
943 route_drop(route, link, &route_drop_handler);
e1ea665e
EY
944 }
945 }
946 }
947 }
948
a6cc569e
TG
949 r = address_new_dynamic(&address);
950 if (r >= 0) {
8ddbeaa2 951 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
3e790eae 952 if (r >= 0) {
e1ea665e
EY
953 _cleanup_route_free_ Route *route_gw = NULL;
954 _cleanup_route_free_ Route *route = NULL;
955
28cc555d 956 r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
8ddbeaa2
UTL
957 if (r >= 0) {
958 route_gw->family = AF_INET;
959 route_gw->dst_addr.in = gateway;
960 route_gw->dst_prefixlen = 32;
961 route_gw->scope = RT_SCOPE_LINK;
962
963 route_drop(route_gw, link, &route_drop_handler);
964 }
3e790eae 965
28cc555d 966 r = route_new_dynamic(&route, RTPROT_UNSPEC);
8ddbeaa2
UTL
967 if (r >= 0) {
968 route->family = AF_INET;
969 route->in_addr.in = gateway;
3e790eae 970
8ddbeaa2
UTL
971 route_drop(route, link, &route_drop_handler);
972 }
3e790eae
UTL
973 }
974
8ddbeaa2
UTL
975 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
976 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
44e7b949 977 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
8ddbeaa2 978
a6cc569e
TG
979 address->family = AF_INET;
980 address->in_addr.in = addr;
981 address->prefixlen = prefixlen;
ff254138 982
5c1d3fc9 983 address_drop(address, link, &address_drop_handler);
c07aeadf 984 }
eb27aeca 985
c07aeadf
TG
986 if (link->network->dhcp_mtu) {
987 uint16_t mtu;
ff254138 988
a6cc569e 989 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
c07aeadf
TG
990 if (r >= 0 && link->original_mtu != mtu) {
991 r = link_set_mtu(link, link->original_mtu);
992 if (r < 0) {
993 log_warning_link(link, "DHCP error: could not reset MTU");
994 link_enter_failed(link);
995 return r;
996 }
ff254138 997 }
c07aeadf 998 }
ff254138 999
c07aeadf 1000 if (link->network->dhcp_hostname) {
216816c6
TG
1001 const char *hostname = NULL;
1002
1003 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
1004 if (r >= 0 && hostname) {
b226d99b 1005 r = link_set_hostname(link, "");
216816c6 1006 if (r < 0)
987efa17 1007 log_error_link(link, "Failed to reset transient hostname");
216816c6 1008 }
c07aeadf 1009 }
4f882b2a 1010
a6cc569e
TG
1011 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
1012
c07aeadf
TG
1013 return 0;
1014}
4f882b2a 1015
68ceb9df
PF
1016static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
1017 sd_dhcp_lease *lease;
1018 int r;
1019
1020 r = sd_dhcp_client_get_lease(client, &lease);
1021 if (r < 0) {
1022 log_warning_link(link, "DHCP error: no lease %s",
1023 strerror(-r));
1024 return r;
1025 }
1026
1027 sd_dhcp_lease_unref(link->dhcp_lease);
1028 link->dhcp_lease = lease;
1029
1030 link_enter_set_addresses(link);
1031
1032 return 0;
1033}
1034
c07aeadf 1035static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
a6cc569e 1036 sd_dhcp_lease *lease;
c07aeadf
TG
1037 struct in_addr address;
1038 struct in_addr netmask;
1039 struct in_addr gateway;
1040 unsigned prefixlen;
c07aeadf 1041 int r;
1346b1f0 1042
c07aeadf
TG
1043 assert(client);
1044 assert(link);
ff254138 1045
a6cc569e
TG
1046 r = sd_dhcp_client_get_lease(client, &lease);
1047 if (r < 0) {
1048 log_warning_link(link, "DHCP error: no lease: %s",
1049 strerror(-r));
1050 return r;
1051 }
1052
1053 r = sd_dhcp_lease_get_address(lease, &address);
ff254138 1054 if (r < 0) {
c07aeadf
TG
1055 log_warning_link(link, "DHCP error: no address: %s",
1056 strerror(-r));
1057 return r;
ff254138
TG
1058 }
1059
a6cc569e 1060 r = sd_dhcp_lease_get_netmask(lease, &netmask);
ff254138 1061 if (r < 0) {
c07aeadf
TG
1062 log_warning_link(link, "DHCP error: no netmask: %s",
1063 strerror(-r));
1064 return r;
ff254138
TG
1065 }
1066
44e7b949 1067 prefixlen = in_addr_netmask_to_prefixlen(&netmask);
ff254138 1068
a6cc569e 1069 r = sd_dhcp_lease_get_router(lease, &gateway);
8ddbeaa2 1070 if (r < 0 && r != -ENOENT) {
b1666580
TG
1071 log_warning_link(link, "DHCP error: could not get gateway: %s",
1072 strerror(-r));
c07aeadf 1073 return r;
ff254138
TG
1074 }
1075
8ddbeaa2
UTL
1076 if (r >= 0)
1077 log_struct_link(LOG_INFO, link,
97578344 1078 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
987efa17 1079 IFNAMSIZ,
8ddbeaa2
UTL
1080 link->ifname,
1081 ADDRESS_FMT_VAL(address),
1082 prefixlen,
1083 ADDRESS_FMT_VAL(gateway),
1084 "ADDRESS=%u.%u.%u.%u",
1085 ADDRESS_FMT_VAL(address),
1086 "PREFIXLEN=%u",
1087 prefixlen,
1088 "GATEWAY=%u.%u.%u.%u",
1089 ADDRESS_FMT_VAL(gateway),
1090 NULL);
1091 else
1092 log_struct_link(LOG_INFO, link,
97578344 1093 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
987efa17 1094 IFNAMSIZ,
8ddbeaa2
UTL
1095 link->ifname,
1096 ADDRESS_FMT_VAL(address),
1097 prefixlen,
1098 "ADDRESS=%u.%u.%u.%u",
1099 ADDRESS_FMT_VAL(address),
1100 "PREFIXLEN=%u",
1101 prefixlen,
1102 NULL);
c07aeadf 1103
d50cf59b
TG
1104 link->dhcp_lease = lease;
1105
c07aeadf
TG
1106 if (link->network->dhcp_mtu) {
1107 uint16_t mtu;
1108
a6cc569e 1109 r = sd_dhcp_lease_get_mtu(lease, &mtu);
c07aeadf
TG
1110 if (r >= 0) {
1111 r = link_set_mtu(link, mtu);
1112 if (r < 0)
1113 log_error_link(link, "Failed to set MTU "
1114 "to %" PRIu16, mtu);
1115 }
1116 }
ff254138 1117
c07aeadf
TG
1118 if (link->network->dhcp_hostname) {
1119 const char *hostname;
ff254138 1120
a6cc569e 1121 r = sd_dhcp_lease_get_hostname(lease, &hostname);
c07aeadf 1122 if (r >= 0) {
b226d99b 1123 r = link_set_hostname(link, hostname);
c07aeadf 1124 if (r < 0)
987efa17 1125 log_error_link(link, "Failed to set transient hostname "
c07aeadf 1126 "to '%s'", hostname);
3bef724f 1127 }
c07aeadf 1128 }
3bef724f 1129
c07aeadf
TG
1130 link_enter_set_addresses(link);
1131
1132 return 0;
1133}
1134
1135static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1136 Link *link = userdata;
aba496a5 1137 int r = 0;
c07aeadf
TG
1138
1139 assert(link);
1140 assert(link->network);
1141 assert(link->manager);
1142
370e9930 1143 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
c07aeadf
TG
1144 return;
1145
1146 switch (event) {
c07aeadf
TG
1147 case DHCP_EVENT_EXPIRED:
1148 case DHCP_EVENT_STOP:
1149 case DHCP_EVENT_IP_CHANGE:
1150 if (link->network->dhcp_critical) {
1151 log_error_link(link, "DHCPv4 connection considered system critical, "
1152 "ignoring request to reconfigure it.");
1153 return;
4f882b2a 1154 }
4f882b2a 1155
17256461
UTL
1156 if (link->dhcp_lease) {
1157 r = dhcp_lease_lost(link);
1158 if (r < 0) {
1159 link_enter_failed(link);
1160 return;
1161 }
c07aeadf 1162 }
1346b1f0 1163
c07aeadf
TG
1164 if (event == DHCP_EVENT_IP_CHANGE) {
1165 r = dhcp_lease_acquired(client, link);
1166 if (r < 0) {
1167 link_enter_failed(link);
1168 return;
1169 }
1346b1f0 1170 }
1346b1f0 1171
68ceb9df
PF
1172 break;
1173 case DHCP_EVENT_RENEW:
1174 r = dhcp_lease_renew(client, link);
1175 if (r < 0) {
1176 link_enter_failed(link);
1177 return;
1178 }
c07aeadf
TG
1179 break;
1180 case DHCP_EVENT_IP_ACQUIRE:
1181 r = dhcp_lease_acquired(client, link);
1182 if (r < 0) {
1183 link_enter_failed(link);
1184 return;
1185 }
1186 break;
1187 default:
1188 if (event < 0)
b1666580 1189 log_warning_link(link, "DHCP error: client failed: %s", strerror(-event));
c07aeadf
TG
1190 else
1191 log_warning_link(link, "DHCP unknown event: %d", event);
c07aeadf 1192 break;
ff254138
TG
1193 }
1194
1195 return;
1196}
1197
aba496a5 1198static int ipv4ll_address_lost(Link *link) {
5c1d3fc9
UTL
1199 int r;
1200 struct in_addr addr;
1201
5c1d3fc9
UTL
1202 assert(link);
1203
1204 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1205 if (r >= 0) {
1206 _cleanup_address_free_ Address *address = NULL;
1207 _cleanup_route_free_ Route *route = NULL;
1208
1209 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1210 ADDRESS_FMT_VAL(addr));
1211
1212 r = address_new_dynamic(&address);
1213 if (r < 0) {
1214 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1215 return r;
1216 }
1217
1218 address->family = AF_INET;
1219 address->in_addr.in = addr;
1220 address->prefixlen = 16;
1221 address->scope = RT_SCOPE_LINK;
1222
1223 address_drop(address, link, &address_drop_handler);
1224
28cc555d 1225 r = route_new_dynamic(&route, RTPROT_UNSPEC);
5c1d3fc9
UTL
1226 if (r < 0) {
1227 log_error_link(link, "Could not allocate route: %s",
1228 strerror(-r));
1229 return r;
1230 }
1231
1232 route->family = AF_INET;
1233 route->scope = RT_SCOPE_LINK;
1234 route->metrics = 99;
1235
1236 route_drop(route, link, &route_drop_handler);
1237 }
1238
1239 return 0;
1240}
1241
1242static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1243 struct in_addr address;
1244 int r;
1245
1246 assert(ll);
1247 assert(link);
1248
1249 r = sd_ipv4ll_get_address(ll, &address);
1250 if (r < 0)
1251 return r;
1252
1253 log_struct_link(LOG_INFO, link,
97578344 1254 "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
987efa17 1255 IFNAMSIZ,
5c1d3fc9
UTL
1256 link->ifname,
1257 ADDRESS_FMT_VAL(address),
1258 NULL);
1259
1260 link_enter_set_addresses(link);
1261
1262 return 0;
1263}
1264
1265static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1266 Link *link = userdata;
1267 int r;
1268
1269 assert(link);
1270 assert(link->network);
1271 assert(link->manager);
1272
370e9930
TG
1273 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1274 return;
1275
5c1d3fc9
UTL
1276 switch(event) {
1277 case IPV4LL_EVENT_STOP:
1278 case IPV4LL_EVENT_CONFLICT:
aba496a5 1279 r = ipv4ll_address_lost(link);
5c1d3fc9
UTL
1280 if (r < 0) {
1281 link_enter_failed(link);
1282 return;
1283 }
1284 break;
1285 case IPV4LL_EVENT_BIND:
1286 r = ipv4ll_address_claimed(ll, link);
1287 if (r < 0) {
1288 link_enter_failed(link);
1289 return;
1290 }
1291 break;
1292 default:
1293 if (event < 0)
1294 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1295 else
1296 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1297 break;
1298 }
1299}
1300
4138fb2c
PF
1301static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
1302 Link *link = userdata;
1303
1304 assert(link);
1305 assert(link->network);
1306 assert(link->manager);
1307
1308 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1309 return;
1310
1311 switch(event) {
1312 case DHCP6_EVENT_STOP:
1313 case DHCP6_EVENT_RESEND_EXPIRE:
1314 case DHCP6_EVENT_RETRANS_MAX:
1315 case DHCP6_EVENT_IP_ACQUIRE:
1316 log_debug_link(link, "DHCPv6 event %d", event);
1317
1318 break;
1319
1320 default:
1321 if (event < 0)
1322 log_warning_link(link, "DHCPv6 error: %s",
1323 strerror(-event));
1324 else
1325 log_warning_link(link, "DHCPv6 unknown event: %d",
1326 event);
1327 return;
1328 }
1329}
1330
1331static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
1332 Link *link = userdata;
1333 int r;
1334
1335 assert(link);
1336 assert(link->network);
1337 assert(link->manager);
1338
1339 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1340 return;
1341
1342 switch(event) {
1343 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
1344 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
1345 return;
1346
1347 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
1348 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
1349 break;
1350
1351 default:
1352 if (event < 0)
1353 log_warning_link(link, "ICMPv6 error: %s",
1354 strerror(-event));
1355 else
1356 log_warning_link(link, "ICMPv6 unknown event: %d",
1357 event);
1358
1359 return;
1360 }
1361
1362 if (link->dhcp6_client)
1363 return;
1364
1365 r = sd_dhcp6_client_new(&link->dhcp6_client);
1366 if (r < 0)
1367 return;
1368
1369 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
1370 if (r < 0) {
1371 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1372 return;
1373 }
1374
1375 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
1376 if (r < 0) {
1377 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1378 return;
1379 }
1380
1381 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
1382 if (r < 0) {
1383 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1384 return;
1385 }
1386
1387 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
1388 link);
1389 if (r < 0) {
1390 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1391 return;
1392 }
1393
1394 r = sd_dhcp6_client_start(link->dhcp6_client);
1395 if (r < 0)
1396 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
1397}
1398
ff254138
TG
1399static int link_acquire_conf(Link *link) {
1400 int r;
1401
1402 assert(link);
1403 assert(link->network);
ff254138
TG
1404 assert(link->manager);
1405 assert(link->manager->event);
1406
5c1d3fc9 1407 if (link->network->ipv4ll) {
eb34d4af 1408 assert(link->ipv4ll);
ff254138 1409
5c1d3fc9
UTL
1410 log_debug_link(link, "acquiring IPv4 link-local address");
1411
1412 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6
TG
1413 if (r < 0) {
1414 log_warning_link(link, "could not acquire IPv4 "
1415 "link-local address");
ff254138 1416 return r;
124fa2c6 1417 }
5c1d3fc9
UTL
1418 }
1419
ed942a9e 1420 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
eb34d4af 1421 assert(link->dhcp_client);
ff254138 1422
5c1d3fc9 1423 log_debug_link(link, "acquiring DHCPv4 lease");
ab47d620 1424
5c1d3fc9 1425 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6
TG
1426 if (r < 0) {
1427 log_warning_link(link, "could not acquire DHCPv4 "
1428 "lease");
5c1d3fc9 1429 return r;
124fa2c6 1430 }
5c1d3fc9 1431 }
ff254138 1432
ed942a9e 1433 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
4138fb2c
PF
1434 assert(link->icmp6_router_discovery);
1435
1436 log_debug_link(link, "discovering IPv6 routers");
1437
1438 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
1439 if (r < 0) {
1440 log_warning_link(link, "could not start IPv6 router discovery");
1441 return r;
1442 }
1443 }
1444
ff254138
TG
1445 return 0;
1446}
1447
bbf7c048 1448bool link_has_carrier(unsigned flags, uint8_t operstate) {
deb2e523
TG
1449 /* see Documentation/networking/operstates.txt in the kernel sources */
1450
1451 if (operstate == IF_OPER_UP)
1452 return true;
1453
1454 if (operstate == IF_OPER_UNKNOWN)
1455 /* operstate may not be implemented, so fall back to flags */
1456 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1457 return true;
1458
1459 return false;
1460}
1461
389cc5f7
TG
1462#define FLAG_STRING(string, flag, old, new) \
1463 (((old ^ new) & flag) \
1464 ? ((old & flag) ? (" -" string) : (" +" string)) \
1465 : "")
1466
1e9be60b 1467static int link_update_flags(Link *link, sd_rtnl_message *m) {
389cc5f7 1468 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1e9be60b
TG
1469 uint8_t operstate;
1470 bool carrier_gained = false, carrier_lost = false;
ff254138
TG
1471 int r;
1472
1473 assert(link);
ff254138 1474
1e9be60b
TG
1475 r = sd_rtnl_message_link_get_flags(m, &flags);
1476 if (r < 0) {
1477 log_warning_link(link, "Could not get link flags");
1478 return r;
1479 }
1480
1481 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1482 if (r < 0)
1483 /* if we got a message without operstate, take it to mean
1484 the state was unchanged */
e375dcde 1485 operstate = link->kernel_operstate;
1e9be60b 1486
e375dcde 1487 if ((link->flags == flags) && (link->kernel_operstate == operstate))
efbc88b8 1488 return 0;
efbc88b8 1489
389cc5f7
TG
1490 if (link->flags != flags) {
1491 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1492 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1493 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1494 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1495 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1496 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1497 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1498 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1499 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1500 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1501 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1502 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1503 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1504 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1505 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1506 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1507 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1508 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1509 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1510 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1511
1512 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1513 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1514 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1515 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1516 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1517 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1518 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1519 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1520
1521 /* link flags are currently at most 18 bits, let's align to printing 20 */
1522 if (unknown_flags_added)
1523 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1524 unknown_flags_added);
1525
1526 if (unknown_flags_removed)
1527 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1528 unknown_flags_removed);
1529 }
505f8da7 1530
e375dcde 1531 carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1e9be60b 1532 link_has_carrier(flags, operstate);
e375dcde 1533 carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1e9be60b
TG
1534 !link_has_carrier(flags, operstate);
1535
1536 link->flags = flags;
e375dcde 1537 link->kernel_operstate = operstate;
1e9be60b 1538
deb2e523
TG
1539 link_save(link);
1540
99b4cc3e
TG
1541 if (link->state == LINK_STATE_FAILED ||
1542 link->state == LINK_STATE_UNMANAGED)
1543 return 0;
1544
7cc832b9
TG
1545 if (carrier_gained) {
1546 log_info_link(link, "gained carrier");
ffba6166 1547
1e9be60b 1548 if (link->network) {
ffba6166
TG
1549 r = link_acquire_conf(link);
1550 if (r < 0) {
ffba6166
TG
1551 link_enter_failed(link);
1552 return r;
ff254138 1553 }
ffba6166 1554 }
7cc832b9
TG
1555 } else if (carrier_lost) {
1556 log_info_link(link, "lost carrier");
efbc88b8 1557
1e9be60b
TG
1558 r = link_stop_clients(link);
1559 if (r < 0) {
1560 link_enter_failed(link);
1561 return r;
ff254138
TG
1562 }
1563 }
1564
ff254138
TG
1565 return 0;
1566}
1567
dd3efc09 1568static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 1569 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
1570 int r;
1571
1746cf2a
TG
1572 assert(link);
1573
5da8149f 1574 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
1575 return 1;
1576
dd3efc09 1577 r = sd_rtnl_message_get_errno(m);
45ad2c13 1578 if (r < 0) {
9b86b393
TG
1579 /* we warn but don't fail the link, as it may
1580 be brought up later */
76800848 1581 log_struct_link(LOG_WARNING, link,
97578344 1582 "MESSAGE=%-*s: could not bring up interface: %s",
987efa17 1583 IFNAMSIZ,
c9ccc19f
TG
1584 link->ifname, strerror(-r),
1585 "ERRNO=%d", -r,
1586 NULL);
45ad2c13
TG
1587 }
1588
f882c247
TG
1589 return 1;
1590}
1591
1592static int link_up(Link *link) {
cf6a8911 1593 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
1594 int r;
1595
f882c247
TG
1596 assert(link);
1597 assert(link->manager);
1598 assert(link->manager->rtnl);
1599
39032b87 1600 log_debug_link(link, "bringing link up");
449f7554 1601
151b9b96
LP
1602 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1603 RTM_SETLINK, link->ifindex);
f579559b 1604 if (r < 0) {
39032b87 1605 log_error_link(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1606 return r;
1607 }
1608
5d4795f3 1609 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1610 if (r < 0) {
3333d748 1611 log_error_link(link, "Could not set link flags: %s", strerror(-r));
fc25d7f8
TG
1612 return r;
1613 }
1614
dd3efc09 1615 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
f579559b 1616 if (r < 0) {
3333d748
ZJS
1617 log_error_link(link,
1618 "Could not send rtnetlink message: %s", strerror(-r));
f579559b
TG
1619 return r;
1620 }
1621
b226d99b
TG
1622 link_ref(link);
1623
f882c247
TG
1624 return 0;
1625}
1626
3f265037 1627static int link_joined(Link *link) {
f882c247
TG
1628 int r;
1629
ef1ba606 1630 assert(link);
52433f6b 1631 assert(link->state == LINK_STATE_ENSLAVING);
f5be5601 1632 assert(link->network);
dd3efc09 1633
505f8da7
TG
1634 if (!(link->flags & IFF_UP)) {
1635 r = link_up(link);
1636 if (r < 0) {
1637 link_enter_failed(link);
1638 return r;
1639 }
ef1ba606 1640 }
f882c247 1641
fb6730c4 1642 return link_enter_set_addresses(link);
02b59d57
TG
1643}
1644
3f265037 1645static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 1646 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1647 int r;
1648
1746cf2a 1649 assert(link);
370e9930
TG
1650 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1651 LINK_STATE_LINGER));
ef1ba606 1652 assert(link->network);
02b59d57 1653
52433f6b
TG
1654 link->enslaving --;
1655
5da8149f 1656 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1657 return 1;
1658
1659 r = sd_rtnl_message_get_errno(m);
856f962c 1660 if (r < 0 && r != -EEXIST) {
c9ccc19f 1661 log_struct_link(LOG_ERR, link,
3f265037 1662 "MESSAGE=%-*s: could not join netdev: %s",
987efa17 1663 IFNAMSIZ,
c9ccc19f
TG
1664 link->ifname, strerror(-r),
1665 "ERRNO=%d", -r,
1666 NULL);
ef1ba606
TG
1667 link_enter_failed(link);
1668 return 1;
ba179154
TG
1669 } else
1670 log_debug_link(link, "joined netdev");
02b59d57 1671
856f962c 1672 if (link->enslaving <= 0)
3f265037 1673 link_joined(link);
02b59d57
TG
1674
1675 return 1;
1676}
1677
3f265037 1678static int link_enter_join_netdev(Link *link) {
6a0a2f86 1679 NetDev *netdev;
672682a6 1680 Iterator i;
02b59d57
TG
1681 int r;
1682
1683 assert(link);
1684 assert(link->network);
505f8da7 1685 assert(link->state == LINK_STATE_INITIALIZING);
02b59d57 1686
52433f6b 1687 link->state = LINK_STATE_ENSLAVING;
02b59d57 1688
fe8db0c5
TG
1689 link_save(link);
1690
7951dea2
SS
1691 if (!link->network->bridge &&
1692 !link->network->bond &&
6a0a2f86 1693 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1694 return link_joined(link);
02b59d57 1695
d9c67ea1 1696 if (link->network->bond) {
52433f6b 1697 log_struct_link(LOG_DEBUG, link,
97578344 1698 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1699 IFNAMSIZ,
af4e9e2c 1700 link->ifname, link->network->bond->ifname,
aa9f1140 1701 NETDEVIF(link->network->bond),
52433f6b 1702 NULL);
449f7554 1703
3f265037 1704 r = netdev_join(link->network->bond, link, &netdev_join_handler);
52433f6b
TG
1705 if (r < 0) {
1706 log_struct_link(LOG_WARNING, link,
3f265037 1707 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1708 IFNAMSIZ,
af4e9e2c 1709 link->ifname, link->network->bond->ifname, strerror(-r),
aa9f1140 1710 NETDEVIF(link->network->bond),
52433f6b
TG
1711 NULL);
1712 link_enter_failed(link);
1713 return r;
1714 }
1715
0ad6148e
MO
1716 link->enslaving ++;
1717 }
1718
d9c67ea1 1719 if (link->network->bridge) {
0ad6148e 1720 log_struct_link(LOG_DEBUG, link,
97578344 1721 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1722 IFNAMSIZ,
af4e9e2c 1723 link->ifname, link->network->bridge->ifname,
aa9f1140 1724 NETDEVIF(link->network->bridge),
0ad6148e
MO
1725 NULL);
1726
3f265037 1727 r = netdev_join(link->network->bridge, link, &netdev_join_handler);
0ad6148e
MO
1728 if (r < 0) {
1729 log_struct_link(LOG_WARNING, link,
3f265037 1730 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1731 IFNAMSIZ,
af4e9e2c 1732 link->ifname, link->network->bridge->ifname, strerror(-r),
aa9f1140 1733 NETDEVIF(link->network->bridge),
0ad6148e
MO
1734 NULL);
1735 link_enter_failed(link);
1736 return r;
1737 }
1738
52433f6b
TG
1739 link->enslaving ++;
1740 }
1741
6a0a2f86 1742 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
7951dea2 1743 log_struct_link(LOG_DEBUG, link,
97578344 1744 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1745 IFNAMSIZ,
6a0a2f86 1746 link->ifname, netdev->ifname, NETDEVIF(netdev), NULL);
7951dea2 1747
6a0a2f86 1748 r = netdev_join(netdev, link, &netdev_join_handler);
7951dea2
SS
1749 if (r < 0) {
1750 log_struct_link(LOG_WARNING, link,
3f265037 1751 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1752 IFNAMSIZ,
6a0a2f86
TG
1753 link->ifname, netdev->ifname, strerror(-r),
1754 NETDEVIF(netdev), NULL);
326cb406
SS
1755 link_enter_failed(link);
1756 return r;
1757 }
1758
326cb406
SS
1759 link->enslaving ++;
1760 }
1761
ef1ba606
TG
1762 return 0;
1763}
1764
a748b692 1765static int link_configure(Link *link) {
02b59d57
TG
1766 int r;
1767
ef1ba606 1768 assert(link);
505f8da7 1769 assert(link->state == LINK_STATE_INITIALIZING);
a748b692 1770
eb34d4af 1771 if (link->network->ipv4ll) {
b5db00e5 1772 uint8_t seed[8];
45ad2c13 1773
eb34d4af
TG
1774 r = sd_ipv4ll_new(&link->ipv4ll);
1775 if (r < 0)
1776 return r;
1777
505f8da7
TG
1778 if (link->udev_device) {
1779 r = net_get_unique_predictable_data(link->udev_device, seed);
1780 if (r >= 0) {
1781 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1782 if (r < 0)
1783 return r;
1784 }
b5db00e5
UTL
1785 }
1786
eb34d4af
TG
1787 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1788 if (r < 0)
1789 return r;
1790
4bb40e81
TG
1791 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1792 if (r < 0)
1793 return r;
1794
eb34d4af
TG
1795 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1796 if (r < 0)
1797 return r;
1798
1799 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1800 if (r < 0)
1801 return r;
1802 }
1803
ed942a9e 1804 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
eb34d4af
TG
1805 r = sd_dhcp_client_new(&link->dhcp_client);
1806 if (r < 0)
1807 return r;
1808
1809 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1810 if (r < 0)
1811 return r;
1812
4bb40e81
TG
1813 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1814 if (r < 0)
1815 return r;
1816
eb34d4af
TG
1817 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1818 if (r < 0)
1819 return r;
1820
1821 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1822 if (r < 0)
1823 return r;
1824
f5de5b00
TG
1825 r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast);
1826 if (r < 0)
1827 return r;
1828
afe7fd56
TG
1829 if (link->mtu) {
1830 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
1831 if (r < 0)
1832 return r;
1833 }
1834
eb34d4af 1835 if (link->network->dhcp_mtu) {
ba179154 1836 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU);
eb34d4af
TG
1837 if (r < 0)
1838 return r;
1839 }
4cc7a82c 1840
e1ea665e
EY
1841 if (link->network->dhcp_routes) {
1842 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE);
1843 if (r < 0)
1844 return r;
1845 r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
1846 if (r < 0)
1847 return r;
1848 }
4cc7a82c
EY
1849
1850 if (link->network->dhcp_sendhost) {
1851 _cleanup_free_ char *hostname = gethostname_malloc();
1852 if (!hostname)
1853 return -ENOMEM;
1854
1855 if (!is_localhost(hostname)) {
1856 r = sd_dhcp_client_set_hostname(link->dhcp_client, hostname);
1857 if (r < 0)
1858 return r;
1859 }
1860 }
edb85f0d
SS
1861
1862 if (link->network->dhcp_vendor_class_identifier) {
1863 r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
1864 link->network->dhcp_vendor_class_identifier);
1865 if (r < 0)
1866 return r;
1867 }
eb34d4af
TG
1868 }
1869
dd43110f 1870 if (link->network->dhcp_server) {
dd43110f
TG
1871 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1872 if (r < 0)
1873 return r;
1874
1875 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1876 if (r < 0)
1877 return r;
dd43110f
TG
1878 }
1879
ed942a9e 1880 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
4138fb2c
PF
1881 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1882 if (r < 0)
1883 return r;
1884
1885 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1886 NULL, 0);
1887 if (r < 0)
1888 return r;
1889
1890 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1891 &link->mac);
1892 if (r < 0)
1893 return r;
1894
1895 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1896 link->ifindex);
1897 if (r < 0)
1898 return r;
1899
1900 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1901 icmp6_router_handler, link);
1902 if (r < 0)
1903 return r;
1904 }
1905
bf0308cb 1906 if (link_has_carrier(link->flags, link->kernel_operstate)) {
1e9be60b
TG
1907 r = link_acquire_conf(link);
1908 if (r < 0)
1909 return r;
cc544d5f 1910 }
1e9be60b 1911
3f265037 1912 return link_enter_join_netdev(link);
505f8da7
TG
1913}
1914
4f561e8e 1915static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 1916 _cleanup_link_unref_ Link *link = userdata;
505f8da7 1917 Network *network;
505f8da7
TG
1918 int r;
1919
1920 assert(link);
1921 assert(link->ifname);
1922 assert(link->manager);
1923
1924 if (link->state != LINK_STATE_INITIALIZING)
5da8149f 1925 return 1;
505f8da7 1926
4f561e8e 1927 log_debug_link(link, "link state is up-to-date");
505f8da7 1928
4f561e8e 1929 r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
57bd6899
TG
1930 if (r == -ENOENT) {
1931 link_enter_unmanaged(link);
5da8149f 1932 return 1;
57bd6899
TG
1933 } else if (r < 0)
1934 return r;
505f8da7
TG
1935
1936 r = network_apply(link->manager, network, link);
1937 if (r < 0)
1938 return r;
1939
a748b692
TG
1940 r = link_configure(link);
1941 if (r < 0)
1942 return r;
1943
5da8149f 1944 return 1;
505f8da7
TG
1945}
1946
4f561e8e
TG
1947int link_initialized(Link *link, struct udev_device *device) {
1948 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1949 int r;
1950
1951 assert(link);
1952 assert(link->manager);
1953 assert(link->manager->rtnl);
1954 assert(device);
1955
1956 if (link->state != LINK_STATE_INITIALIZING)
1957 return 0;
1958
679b3605
TG
1959 if (link->udev_device)
1960 return 0;
1961
4f561e8e
TG
1962 log_debug_link(link, "udev initialized link");
1963
1964 link->udev_device = udev_device_ref(device);
1965
1966 /* udev has initialized the link, but we don't know if we have yet processed
1967 the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1968 we know that the pending NEWLINKs have already been processed and that we
1969 are up-to-date */
1970
1971 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1972 if (r < 0)
1973 return r;
1974
1975 r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1976 if (r < 0)
1977 return r;
1978
5da8149f
TG
1979 link_ref(link);
1980
4f561e8e
TG
1981 return 0;
1982}
1983
fbbeb65a
TG
1984int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1985 Manager *m = userdata;
1986 Link *link = NULL;
1987 uint16_t type;
1988 _cleanup_address_free_ Address *address = NULL;
428fd0a7 1989 Address *ad;
fbbeb65a 1990 char buf[INET6_ADDRSTRLEN];
428fd0a7 1991 bool address_dropped = false;
fbbeb65a
TG
1992 int r, ifindex;
1993
1994 assert(rtnl);
1995 assert(message);
1996 assert(m);
1997
1998 r = sd_rtnl_message_get_type(message, &type);
1999 if (r < 0) {
2000 log_warning("rtnl: could not get message type");
2001 return 0;
2002 }
2003
2004 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
2005 if (r < 0 || ifindex <= 0) {
5ea846cc 2006 log_warning("rtnl: received address message without valid ifindex, ignoring");
fbbeb65a
TG
2007 return 0;
2008 } else {
2009 r = link_get(m, ifindex, &link);
2010 if (r < 0 || !link) {
5ea846cc 2011 log_warning("rtnl: received address for a nonexistent link, ignoring");
fbbeb65a
TG
2012 return 0;
2013 }
2014 }
2015
2016 r = address_new_dynamic(&address);
2017 if (r < 0)
393c0c5e 2018 return r;
fbbeb65a
TG
2019
2020 r = sd_rtnl_message_addr_get_family(message, &address->family);
2021 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
987efa17 2022 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
fbbeb65a
TG
2023 return 0;
2024 }
2025
2026 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
2027 if (r < 0) {
e375dcde
TG
2028 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
2029 return 0;
2030 }
2031
2032 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
2033 if (r < 0) {
2034 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
fbbeb65a
TG
2035 return 0;
2036 }
2037
2038 switch (address->family) {
2039 case AF_INET:
2040 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
2041 if (r < 0) {
987efa17 2042 log_warning_link(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
2043 return 0;
2044 }
2045
2046 break;
2047
2048 case AF_INET6:
2049 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
2050 if (r < 0) {
987efa17 2051 log_warning_link(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
2052 return 0;
2053 }
2054
2055 break;
2056
2057 default:
2058 assert_not_reached("invalid address family");
2059 }
2060
2061 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
987efa17 2062 log_warning_link(link, "could not print address");
fbbeb65a
TG
2063 return 0;
2064 }
2065
428fd0a7
TG
2066 LIST_FOREACH(addresses, ad, link->addresses) {
2067 if (address_equal(ad, address)) {
2068 LIST_REMOVE(addresses, link->addresses, ad);
2069
2070 address_free(ad);
2071
2072 address_dropped = true;
2073
2074 break;
2075 }
2076 }
2077
fbbeb65a
TG
2078 switch (type) {
2079 case RTM_NEWADDR:
428fd0a7
TG
2080 if (!address_dropped)
2081 log_debug_link(link, "added address: %s/%u", buf,
393c0c5e
TG
2082 address->prefixlen);
2083 else
2084 log_debug_link(link, "updated address: %s/%u", buf,
2085 address->prefixlen);
fbbeb65a 2086
428fd0a7
TG
2087 LIST_PREPEND(addresses, link->addresses, address);
2088 address = NULL;
2089
f5602be9
TG
2090 link_save(link);
2091
428fd0a7 2092 break;
fbbeb65a 2093 case RTM_DELADDR:
f5602be9 2094 if (address_dropped) {
428fd0a7 2095 log_debug_link(link, "removed address: %s/%u", buf,
393c0c5e 2096 address->prefixlen);
428fd0a7 2097
f5602be9 2098 link_save(link);
393c0c5e
TG
2099 } else
2100 log_warning_link(link, "removing non-existent address: %s/%u",
2101 buf, address->prefixlen);
f5602be9 2102
fbbeb65a
TG
2103 break;
2104 default:
2105 assert_not_reached("Received invalid RTNL message type");
2106 }
2107
2108 return 1;
2109}
2110
505f8da7
TG
2111int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2112 Link *link;
fbbeb65a 2113 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
505f8da7
TG
2114 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2115 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2116 int r;
2117
2118 assert(m);
fbbeb65a 2119 assert(m->rtnl);
505f8da7
TG
2120 assert(message);
2121 assert(ret);
2122
2123 r = link_new(m, message, ret);
2124 if (r < 0)
2125 return r;
2126
2127 link = *ret;
2128
ae06ab10 2129 log_debug_link(link, "link %d added", link->ifindex);
505f8da7 2130
fbbeb65a
TG
2131 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2132 if (r < 0)
2133 return r;
2134
2135 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2136 if (r < 0)
2137 return r;
2138
5da8149f
TG
2139 link_ref(link);
2140
505f8da7
TG
2141 if (detect_container(NULL) <= 0) {
2142 /* not in a container, udev will be around */
ae06ab10 2143 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7
TG
2144 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2145 if (!device) {
9fecce80
TG
2146 log_warning_link(link, "could not find udev device: %m");
2147 return -errno;
505f8da7
TG
2148 }
2149
3c4cb064 2150 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 2151 /* not yet ready */
16cd414b 2152 log_debug_link(link, "udev initializing link...");
505f8da7 2153 return 0;
3c4cb064 2154 }
505f8da7 2155
4f561e8e
TG
2156 r = link_initialized(link, device);
2157 if (r < 0)
2158 return r;
2159 } else {
5da8149f
TG
2160 /* we are calling a callback directly, so must take a ref */
2161 link_ref(link);
2162
4f561e8e
TG
2163 r = link_initialized_and_synced(m->rtnl, NULL, link);
2164 if (r < 0)
2165 return r;
2166 }
505f8da7 2167
a748b692
TG
2168 return 0;
2169}
2170
22936833 2171int link_update(Link *link, sd_rtnl_message *m) {
c49b33ac 2172 struct ether_addr mac;
ca4e095a 2173 const char *ifname;
afe7fd56 2174 uint32_t mtu;
22936833
TG
2175 int r;
2176
dd3efc09 2177 assert(link);
b8941f74 2178 assert(link->ifname);
22936833
TG
2179 assert(m);
2180
7619683b
TG
2181 if (link->state == LINK_STATE_LINGER) {
2182 link_ref(link);
2183 log_info_link(link, "link readded");
2184 link->state = LINK_STATE_ENSLAVING;
2185 }
2186
b8941f74
TG
2187 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2188 if (r >= 0 && !streq(ifname, link->ifname)) {
2189 log_info_link(link, "renamed to %s", ifname);
2190
2191 free(link->ifname);
2192 link->ifname = strdup(ifname);
2193 if (!link->ifname)
2194 return -ENOMEM;
2195 }
2196
afe7fd56
TG
2197 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
2198 if (r >= 0 && mtu > 0) {
2199 link->mtu = mtu;
2200 if (!link->original_mtu) {
2201 link->original_mtu = mtu;
9842de0d 2202 log_debug_link(link, "saved original MTU: %"
afe7fd56
TG
2203 PRIu32, link->original_mtu);
2204 }
2205
2206 if (link->dhcp_client) {
2207 r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
2208 if (r < 0) {
2209 log_warning_link(link, "Could not update MTU in DHCP client: %s",
2210 strerror(-r));
2211 return r;
2212 }
2213 }
9842de0d 2214 }
69629de9 2215
e9189a1f
TG
2216 /* The kernel may broadcast NEWLINK messages without the MAC address
2217 set, simply ignore them. */
c49b33ac 2218 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 2219 if (r >= 0) {
20861203 2220 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
c49b33ac 2221
20861203 2222 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
c49b33ac 2223
20861203
TG
2224 log_debug_link(link, "MAC address: "
2225 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2226 mac.ether_addr_octet[0],
2227 mac.ether_addr_octet[1],
2228 mac.ether_addr_octet[2],
2229 mac.ether_addr_octet[3],
2230 mac.ether_addr_octet[4],
2231 mac.ether_addr_octet[5]);
c49b33ac 2232
20861203
TG
2233 if (link->ipv4ll) {
2234 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2235 if (r < 0) {
2236 log_warning_link(link, "Could not update MAC "
2237 "address in IPv4LL client: %s",
2238 strerror(-r));
2239 return r;
2240 }
c49b33ac 2241 }
c49b33ac 2242
20861203
TG
2243 if (link->dhcp_client) {
2244 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2245 if (r < 0) {
2246 log_warning_link(link, "Could not update MAC "
2247 "address in DHCP client: %s",
2248 strerror(-r));
2249 return r;
2250 }
c49b33ac 2251 }
4138fb2c
PF
2252
2253 if (link->dhcp6_client) {
2254 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
2255 &link->mac);
2256 if (r < 0) {
2257 log_warning_link(link, "Could not update MAC address in DHCPv6 client: %s",
2258 strerror(-r));
2259 return r;
2260 }
2261 }
c49b33ac 2262 }
4f882b2a
TG
2263 }
2264
1e9be60b 2265 return link_update_flags(link, m);
dd3efc09 2266}
fe8db0c5 2267
e375dcde
TG
2268static void link_update_operstate(Link *link) {
2269
2270 assert(link);
2271
2272 if (link->kernel_operstate == IF_OPER_DORMANT)
2273 link->operstate = LINK_OPERSTATE_DORMANT;
2274 else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2275 Address *address;
2276 uint8_t scope = RT_SCOPE_NOWHERE;
2277
2278 /* if we have carrier, check what addresses we have */
2279 LIST_FOREACH(addresses, address, link->addresses) {
2280 if (address->scope < scope)
2281 scope = address->scope;
2282 }
2283
2284 if (scope < RT_SCOPE_SITE)
2285 /* universally accessible addresses found */
2286 link->operstate = LINK_OPERSTATE_ROUTABLE;
2287 else if (scope < RT_SCOPE_HOST)
2288 /* only link or site local addresses found */
2289 link->operstate = LINK_OPERSTATE_DEGRADED;
2290 else
2291 /* no useful addresses found */
2292 link->operstate = LINK_OPERSTATE_CARRIER;
2293 } else
2294 link->operstate = LINK_OPERSTATE_UNKNOWN;
2295}
2296
fe8db0c5 2297int link_save(Link *link) {
68a8723c 2298 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 2299 _cleanup_fclose_ FILE *f = NULL;
e375dcde 2300 const char *admin_state, *oper_state;
fe8db0c5
TG
2301 int r;
2302
2303 assert(link);
2304 assert(link->state_file);
68a8723c 2305 assert(link->lease_file);
bbf7c048
TG
2306 assert(link->manager);
2307
e375dcde
TG
2308 link_update_operstate(link);
2309
bbf7c048
TG
2310 r = manager_save(link->manager);
2311 if (r < 0)
2312 return r;
fe8db0c5 2313
370e9930
TG
2314 if (link->state == LINK_STATE_LINGER) {
2315 unlink(link->state_file);
2316 return 0;
2317 }
2318
deb2e523
TG
2319 admin_state = link_state_to_string(link->state);
2320 assert(admin_state);
2321
e375dcde
TG
2322 oper_state = link_operstate_to_string(link->operstate);
2323 assert(oper_state);
deb2e523 2324
fe8db0c5
TG
2325 r = fopen_temporary(link->state_file, &f, &temp_path);
2326 if (r < 0)
c2d6bd61 2327 return r;
fe8db0c5
TG
2328
2329 fchmod(fileno(f), 0644);
2330
2331 fprintf(f,
2332 "# This is private data. Do not parse.\n"
deb2e523 2333 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
2334 "OPER_STATE=%s\n",
2335 admin_state, oper_state);
fe8db0c5 2336
bcb7a07e 2337 if (link->network) {
b0e39c82
TG
2338 char **address;
2339
2340 fputs("DNS=", f);
2341
2342 if (link->network->dhcp_dns &&
2343 link->dhcp_lease) {
2344 const struct in_addr *addresses;
2345
2346 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2347 if (r > 0) {
2348 serialize_in_addrs(f, addresses, r);
2349 if (link->network->dns)
2350 fputs(" ", f);
2351 }
2352 }
2353
2354 STRV_FOREACH(address, link->network->dns)
2355 fprintf(f, "%s%s", *address,
2356 (address + 1 ? " " : ""));
2357
2358 fputs("\n", f);
2359
2360 fprintf(f, "NTP=");
2361
2362 if (link->network->dhcp_ntp &&
2363 link->dhcp_lease) {
2364 const struct in_addr *addresses;
2365
2366 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2367 if (r > 0) {
2368 serialize_in_addrs(f, addresses, r);
2369 if (link->network->ntp)
2370 fputs(" ", f);
2371 }
2372 }
2373
2374 STRV_FOREACH(address, link->network->ntp)
2375 fprintf(f, "%s%s", *address,
2376 (address + 1 ? " " : ""));
2377
2378 fputs("\n", f);
bd8f6538
TG
2379
2380 fprintf(f, "LLMNR=%s\n", llmnr_support_to_string(link->network->llmnr));
bcb7a07e 2381 }
7374f9d8 2382
fe8db0c5 2383 if (link->dhcp_lease) {
d9876a52
TG
2384 assert(link->network);
2385
68a8723c 2386 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2387 if (r < 0)
c2d6bd61 2388 goto fail;
fe8db0c5 2389
7374f9d8 2390 fprintf(f,
b0e39c82
TG
2391 "DHCP_LEASE=%s\n",
2392 link->lease_file);
deb2e523 2393 } else
68a8723c 2394 unlink(link->lease_file);
fe8db0c5 2395
c2d6bd61
LP
2396 r = fflush_and_check(f);
2397 if (r < 0)
2398 goto fail;
fe8db0c5 2399
c2d6bd61 2400 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2401 r = -errno;
c2d6bd61 2402 goto fail;
fe8db0c5
TG
2403 }
2404
c2d6bd61 2405 return 0;
fe8db0c5 2406
c2d6bd61
LP
2407fail:
2408 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2409 unlink(link->state_file);
2410 unlink(temp_path);
fe8db0c5
TG
2411 return r;
2412}
2413
2414static const char* const link_state_table[_LINK_STATE_MAX] = {
deb2e523 2415 [LINK_STATE_INITIALIZING] = "initializing",
fe8db0c5
TG
2416 [LINK_STATE_ENSLAVING] = "configuring",
2417 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2418 [LINK_STATE_SETTING_ROUTES] = "configuring",
2419 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 2420 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 2421 [LINK_STATE_FAILED] = "failed",
370e9930 2422 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
2423};
2424
2425DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
2426
2427static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2428 [LINK_OPERSTATE_UNKNOWN] = "unknown",
2429 [LINK_OPERSTATE_DORMANT] = "dormant",
2430 [LINK_OPERSTATE_CARRIER] = "carrier",
2431 [LINK_OPERSTATE_DEGRADED] = "degraded",
2432 [LINK_OPERSTATE_ROUTABLE] = "routable",
2433};
2434
2435DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);