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