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