]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
sd-dhcp-lease: move in_addr (de)serialization to shared network code
[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
315db1a8
ZJS
78 r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
79 link->ifindex);
fe8db0c5 80 if (r < 0)
315db1a8 81 return -ENOMEM;
fe8db0c5 82
68a8723c
TG
83 r = asprintf(&link->lease_file, "/run/systemd/network/leases/%"PRIu64,
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
TG
857 struct in_addr *nameservers;
858 size_t nameservers_size;
859 int r;
1346b1f0 860
c07aeadf
TG
861 assert(client);
862 assert(link);
ff254138 863
a6cc569e
TG
864 r = sd_dhcp_client_get_lease(client, &lease);
865 if (r < 0) {
866 log_warning_link(link, "DHCP error: no lease: %s",
867 strerror(-r));
868 return r;
869 }
870
871 r = sd_dhcp_lease_get_address(lease, &address);
ff254138 872 if (r < 0) {
c07aeadf
TG
873 log_warning_link(link, "DHCP error: no address: %s",
874 strerror(-r));
875 return r;
ff254138
TG
876 }
877
a6cc569e 878 r = sd_dhcp_lease_get_netmask(lease, &netmask);
ff254138 879 if (r < 0) {
c07aeadf
TG
880 log_warning_link(link, "DHCP error: no netmask: %s",
881 strerror(-r));
882 return r;
ff254138
TG
883 }
884
377a218f 885 prefixlen = net_netmask_to_prefixlen(&netmask);
ff254138 886
a6cc569e 887 r = sd_dhcp_lease_get_router(lease, &gateway);
8ddbeaa2
UTL
888 if (r < 0 && r != -ENOENT) {
889 log_warning_link(link, "DHCP error: %s", strerror(-r));
c07aeadf 890 return r;
ff254138
TG
891 }
892
8ddbeaa2
UTL
893 if (r >= 0)
894 log_struct_link(LOG_INFO, link,
987efa17
TG
895 "MESSAGE=%*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
896 IFNAMSIZ,
8ddbeaa2
UTL
897 link->ifname,
898 ADDRESS_FMT_VAL(address),
899 prefixlen,
900 ADDRESS_FMT_VAL(gateway),
901 "ADDRESS=%u.%u.%u.%u",
902 ADDRESS_FMT_VAL(address),
903 "PREFIXLEN=%u",
904 prefixlen,
905 "GATEWAY=%u.%u.%u.%u",
906 ADDRESS_FMT_VAL(gateway),
907 NULL);
908 else
909 log_struct_link(LOG_INFO, link,
987efa17
TG
910 "MESSAGE=%*s: DHCPv4 address %u.%u.%u.%u/%u",
911 IFNAMSIZ,
8ddbeaa2
UTL
912 link->ifname,
913 ADDRESS_FMT_VAL(address),
914 prefixlen,
915 "ADDRESS=%u.%u.%u.%u",
916 ADDRESS_FMT_VAL(address),
917 "PREFIXLEN=%u",
918 prefixlen,
919 NULL);
c07aeadf 920
d50cf59b
TG
921 link->dhcp_lease = lease;
922
c07aeadf 923 if (link->network->dhcp_dns) {
a6cc569e 924 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
c07aeadf
TG
925 if (r >= 0) {
926 r = manager_update_resolv_conf(link->manager);
927 if (r < 0)
987efa17 928 log_error_link(link, "Failed to update resolv.conf");
ff254138 929 }
c07aeadf 930 }
ff254138 931
c07aeadf
TG
932 if (link->network->dhcp_mtu) {
933 uint16_t mtu;
934
a6cc569e 935 r = sd_dhcp_lease_get_mtu(lease, &mtu);
c07aeadf
TG
936 if (r >= 0) {
937 r = link_set_mtu(link, mtu);
938 if (r < 0)
939 log_error_link(link, "Failed to set MTU "
940 "to %" PRIu16, mtu);
941 }
942 }
ff254138 943
c07aeadf
TG
944 if (link->network->dhcp_hostname) {
945 const char *hostname;
ff254138 946
a6cc569e 947 r = sd_dhcp_lease_get_hostname(lease, &hostname);
c07aeadf 948 if (r >= 0) {
b226d99b 949 r = link_set_hostname(link, hostname);
c07aeadf 950 if (r < 0)
987efa17 951 log_error_link(link, "Failed to set transient hostname "
c07aeadf 952 "to '%s'", hostname);
3bef724f 953 }
c07aeadf 954 }
3bef724f 955
c07aeadf
TG
956 link_enter_set_addresses(link);
957
958 return 0;
959}
960
961static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
962 Link *link = userdata;
aba496a5 963 int r = 0;
c07aeadf
TG
964
965 assert(link);
966 assert(link->network);
967 assert(link->manager);
968
370e9930 969 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
c07aeadf
TG
970 return;
971
972 switch (event) {
973 case DHCP_EVENT_NO_LEASE:
974 log_debug_link(link, "IP address in use.");
975 break;
976 case DHCP_EVENT_EXPIRED:
977 case DHCP_EVENT_STOP:
978 case DHCP_EVENT_IP_CHANGE:
979 if (link->network->dhcp_critical) {
980 log_error_link(link, "DHCPv4 connection considered system critical, "
981 "ignoring request to reconfigure it.");
982 return;
4f882b2a 983 }
4f882b2a 984
17256461
UTL
985 if (link->dhcp_lease) {
986 r = dhcp_lease_lost(link);
987 if (r < 0) {
988 link_enter_failed(link);
989 return;
990 }
c07aeadf 991 }
1346b1f0 992
c07aeadf
TG
993 if (event == DHCP_EVENT_IP_CHANGE) {
994 r = dhcp_lease_acquired(client, link);
995 if (r < 0) {
996 link_enter_failed(link);
997 return;
998 }
1346b1f0 999 }
1346b1f0 1000
5c1d3fc9 1001 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
aba496a5
UTL
1002 if (!sd_ipv4ll_is_running(link->ipv4ll))
1003 r = sd_ipv4ll_start(link->ipv4ll);
1004 else if (ipv4ll_is_bound(link->ipv4ll))
1005 r = ipv4ll_address_update(link, false);
5c1d3fc9
UTL
1006 if (r < 0) {
1007 link_enter_failed(link);
1008 return;
1009 }
1010 }
1011
c07aeadf
TG
1012 break;
1013 case DHCP_EVENT_IP_ACQUIRE:
1014 r = dhcp_lease_acquired(client, link);
1015 if (r < 0) {
1016 link_enter_failed(link);
1017 return;
1018 }
5c1d3fc9 1019 if (link->ipv4ll) {
aba496a5
UTL
1020 if (ipv4ll_is_bound(link->ipv4ll))
1021 r = ipv4ll_address_update(link, true);
1022 else
1023 r = sd_ipv4ll_stop(link->ipv4ll);
5c1d3fc9
UTL
1024 if (r < 0) {
1025 link_enter_failed(link);
1026 return;
1027 }
1028 }
c07aeadf
TG
1029 break;
1030 default:
1031 if (event < 0)
1032 log_warning_link(link, "DHCP error: %s", strerror(-event));
1033 else
1034 log_warning_link(link, "DHCP unknown event: %d", event);
c07aeadf 1035 break;
ff254138
TG
1036 }
1037
1038 return;
1039}
1040
aba496a5
UTL
1041static int ipv4ll_address_update(Link *link, bool deprecate) {
1042 int r;
1043 struct in_addr addr;
1044
1045 assert(link);
1046
1047 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1048 if (r >= 0) {
1049 _cleanup_address_free_ Address *address = NULL;
1050
1051 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1052 deprecate ? "deprecate" : "approve",
1053 ADDRESS_FMT_VAL(addr));
1054
1055 r = address_new_dynamic(&address);
1056 if (r < 0) {
1057 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1058 return r;
1059 }
1060
1061 address->family = AF_INET;
1062 address->in_addr.in = addr;
1063 address->prefixlen = 16;
1064 address->scope = RT_SCOPE_LINK;
1065 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1066 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1067
1068 address_update(address, link, &address_update_handler);
b226d99b 1069 link_ref(link);
aba496a5
UTL
1070 }
1071
1072 return 0;
1073
1074}
1075
1076static int ipv4ll_address_lost(Link *link) {
5c1d3fc9
UTL
1077 int r;
1078 struct in_addr addr;
1079
5c1d3fc9
UTL
1080 assert(link);
1081
1082 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1083 if (r >= 0) {
1084 _cleanup_address_free_ Address *address = NULL;
1085 _cleanup_route_free_ Route *route = NULL;
1086
1087 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1088 ADDRESS_FMT_VAL(addr));
1089
1090 r = address_new_dynamic(&address);
1091 if (r < 0) {
1092 log_error_link(link, "Could not allocate address: %s", strerror(-r));
1093 return r;
1094 }
1095
1096 address->family = AF_INET;
1097 address->in_addr.in = addr;
1098 address->prefixlen = 16;
1099 address->scope = RT_SCOPE_LINK;
1100
1101 address_drop(address, link, &address_drop_handler);
b226d99b 1102 link_ref(link);
5c1d3fc9
UTL
1103
1104 r = route_new_dynamic(&route);
1105 if (r < 0) {
1106 log_error_link(link, "Could not allocate route: %s",
1107 strerror(-r));
1108 return r;
1109 }
1110
1111 route->family = AF_INET;
1112 route->scope = RT_SCOPE_LINK;
1113 route->metrics = 99;
1114
1115 route_drop(route, link, &route_drop_handler);
b226d99b 1116 link_ref(link);
5c1d3fc9
UTL
1117 }
1118
1119 return 0;
1120}
1121
aba496a5
UTL
1122static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1123 int r;
1124 struct in_addr addr;
1125
1126 assert(ll);
1127
1128 r = sd_ipv4ll_get_address(ll, &addr);
1129 if (r < 0)
1130 return false;
1131 return true;
1132}
1133
5c1d3fc9
UTL
1134static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1135 struct in_addr address;
1136 int r;
1137
1138 assert(ll);
1139 assert(link);
1140
1141 r = sd_ipv4ll_get_address(ll, &address);
1142 if (r < 0)
1143 return r;
1144
1145 log_struct_link(LOG_INFO, link,
987efa17
TG
1146 "MESSAGE=%*s: IPv4 link-local address %u.%u.%u.%u",
1147 IFNAMSIZ,
5c1d3fc9
UTL
1148 link->ifname,
1149 ADDRESS_FMT_VAL(address),
1150 NULL);
1151
1152 link_enter_set_addresses(link);
1153
1154 return 0;
1155}
1156
1157static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1158 Link *link = userdata;
1159 int r;
1160
1161 assert(link);
1162 assert(link->network);
1163 assert(link->manager);
1164
370e9930
TG
1165 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1166 return;
1167
5c1d3fc9
UTL
1168 switch(event) {
1169 case IPV4LL_EVENT_STOP:
1170 case IPV4LL_EVENT_CONFLICT:
aba496a5 1171 r = ipv4ll_address_lost(link);
5c1d3fc9
UTL
1172 if (r < 0) {
1173 link_enter_failed(link);
1174 return;
1175 }
1176 break;
1177 case IPV4LL_EVENT_BIND:
1178 r = ipv4ll_address_claimed(ll, link);
1179 if (r < 0) {
1180 link_enter_failed(link);
1181 return;
1182 }
1183 break;
1184 default:
1185 if (event < 0)
1186 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1187 else
1188 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1189 break;
1190 }
1191}
1192
ff254138
TG
1193static int link_acquire_conf(Link *link) {
1194 int r;
1195
1196 assert(link);
1197 assert(link->network);
ff254138
TG
1198 assert(link->manager);
1199 assert(link->manager->event);
1200
5c1d3fc9 1201 if (link->network->ipv4ll) {
eb34d4af 1202 assert(link->ipv4ll);
ff254138 1203
5c1d3fc9
UTL
1204 log_debug_link(link, "acquiring IPv4 link-local address");
1205
1206 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6
TG
1207 if (r < 0) {
1208 log_warning_link(link, "could not acquire IPv4 "
1209 "link-local address");
ff254138 1210 return r;
124fa2c6 1211 }
5c1d3fc9
UTL
1212 }
1213
1214 if (link->network->dhcp) {
eb34d4af 1215 assert(link->dhcp_client);
ff254138 1216
5c1d3fc9 1217 log_debug_link(link, "acquiring DHCPv4 lease");
ab47d620 1218
5c1d3fc9 1219 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6
TG
1220 if (r < 0) {
1221 log_warning_link(link, "could not acquire DHCPv4 "
1222 "lease");
5c1d3fc9 1223 return r;
124fa2c6 1224 }
5c1d3fc9 1225 }
ff254138
TG
1226
1227 return 0;
1228}
1229
bbf7c048 1230bool link_has_carrier(unsigned flags, uint8_t operstate) {
deb2e523
TG
1231 /* see Documentation/networking/operstates.txt in the kernel sources */
1232
1233 if (operstate == IF_OPER_UP)
1234 return true;
1235
1236 if (operstate == IF_OPER_UNKNOWN)
1237 /* operstate may not be implemented, so fall back to flags */
1238 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1239 return true;
1240
1241 return false;
1242}
1243
389cc5f7
TG
1244#define FLAG_STRING(string, flag, old, new) \
1245 (((old ^ new) & flag) \
1246 ? ((old & flag) ? (" -" string) : (" +" string)) \
1247 : "")
1248
1e9be60b 1249static int link_update_flags(Link *link, sd_rtnl_message *m) {
389cc5f7 1250 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1e9be60b
TG
1251 uint8_t operstate;
1252 bool carrier_gained = false, carrier_lost = false;
ff254138
TG
1253 int r;
1254
1255 assert(link);
ff254138 1256
1e9be60b
TG
1257 r = sd_rtnl_message_link_get_flags(m, &flags);
1258 if (r < 0) {
1259 log_warning_link(link, "Could not get link flags");
1260 return r;
1261 }
1262
1263 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1264 if (r < 0)
1265 /* if we got a message without operstate, take it to mean
1266 the state was unchanged */
1267 operstate = link->operstate;
1268
1269 if ((link->flags == flags) && (link->operstate == operstate))
efbc88b8 1270 return 0;
efbc88b8 1271
389cc5f7
TG
1272 if (link->flags != flags) {
1273 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",
1274 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1275 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1276 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1277 FLAG_STRING("UP", IFF_UP, link->flags, flags),
1278 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1279 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1280 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1281 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1282 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1283 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1284 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1285 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1286 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1287 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1288 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1289 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1290 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1291 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1292 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1293
1294 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1295 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1296 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1297 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1298 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1299 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1300 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1301 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1302
1303 /* link flags are currently at most 18 bits, let's align to printing 20 */
1304 if (unknown_flags_added)
1305 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1306 unknown_flags_added);
1307
1308 if (unknown_flags_removed)
1309 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1310 unknown_flags_removed);
1311 }
505f8da7 1312
1e9be60b
TG
1313 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1314 link_has_carrier(flags, operstate);
1315 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1316 !link_has_carrier(flags, operstate);
1317
1318 link->flags = flags;
1319 link->operstate = operstate;
1320
deb2e523
TG
1321 link_save(link);
1322
99b4cc3e
TG
1323 if (link->state == LINK_STATE_FAILED ||
1324 link->state == LINK_STATE_UNMANAGED)
1325 return 0;
1326
7cc832b9
TG
1327 if (carrier_gained) {
1328 log_info_link(link, "gained carrier");
ffba6166 1329
1e9be60b 1330 if (link->network) {
ffba6166
TG
1331 r = link_acquire_conf(link);
1332 if (r < 0) {
ffba6166
TG
1333 link_enter_failed(link);
1334 return r;
ff254138 1335 }
ffba6166 1336 }
7cc832b9
TG
1337 } else if (carrier_lost) {
1338 log_info_link(link, "lost carrier");
efbc88b8 1339
1e9be60b
TG
1340 r = link_stop_clients(link);
1341 if (r < 0) {
1342 link_enter_failed(link);
1343 return r;
ff254138
TG
1344 }
1345 }
1346
ff254138
TG
1347 return 0;
1348}
1349
dd3efc09
TG
1350static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1351 Link *link = userdata;
1352 int r;
1353
1746cf2a
TG
1354 assert(link);
1355
370e9930 1356 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
b226d99b 1357 link_unref(link);
1746cf2a 1358 return 1;
b226d99b 1359 }
1746cf2a 1360
dd3efc09 1361 r = sd_rtnl_message_get_errno(m);
45ad2c13 1362 if (r < 0) {
9b86b393
TG
1363 /* we warn but don't fail the link, as it may
1364 be brought up later */
76800848 1365 log_struct_link(LOG_WARNING, link,
987efa17
TG
1366 "MESSAGE=%*s: could not bring up interface: %s",
1367 IFNAMSIZ,
c9ccc19f
TG
1368 link->ifname, strerror(-r),
1369 "ERRNO=%d", -r,
1370 NULL);
45ad2c13
TG
1371 }
1372
b226d99b
TG
1373 link_unref(link);
1374
f882c247
TG
1375 return 1;
1376}
1377
1378static int link_up(Link *link) {
cf6a8911 1379 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
1380 int r;
1381
f882c247
TG
1382 assert(link);
1383 assert(link->manager);
1384 assert(link->manager->rtnl);
1385
39032b87 1386 log_debug_link(link, "bringing link up");
449f7554 1387
151b9b96
LP
1388 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1389 RTM_SETLINK, link->ifindex);
f579559b 1390 if (r < 0) {
39032b87 1391 log_error_link(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1392 return r;
1393 }
1394
5d4795f3 1395 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1396 if (r < 0) {
3333d748 1397 log_error_link(link, "Could not set link flags: %s", strerror(-r));
fc25d7f8
TG
1398 return r;
1399 }
1400
dd3efc09 1401 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
f579559b 1402 if (r < 0) {
3333d748
ZJS
1403 log_error_link(link,
1404 "Could not send rtnetlink message: %s", strerror(-r));
f579559b
TG
1405 return r;
1406 }
1407
b226d99b
TG
1408 link_ref(link);
1409
f882c247
TG
1410 return 0;
1411}
1412
52433f6b 1413static int link_enslaved(Link *link) {
f882c247
TG
1414 int r;
1415
ef1ba606 1416 assert(link);
52433f6b 1417 assert(link->state == LINK_STATE_ENSLAVING);
f5be5601 1418 assert(link->network);
dd3efc09 1419
505f8da7
TG
1420 if (!(link->flags & IFF_UP)) {
1421 r = link_up(link);
1422 if (r < 0) {
1423 link_enter_failed(link);
1424 return r;
1425 }
ef1ba606 1426 }
f882c247 1427
5c1d3fc9 1428 if (!link->network->dhcp && !link->network->ipv4ll)
1746cf2a 1429 return link_enter_set_addresses(link);
ef1ba606
TG
1430
1431 return 0;
02b59d57
TG
1432}
1433
52433f6b 1434static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
02b59d57
TG
1435 Link *link = userdata;
1436 int r;
1437
1746cf2a 1438 assert(link);
370e9930
TG
1439 assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1440 LINK_STATE_LINGER));
ef1ba606 1441 assert(link->network);
02b59d57 1442
52433f6b
TG
1443 link->enslaving --;
1444
370e9930 1445 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
b226d99b 1446 link_unref(link);
02b59d57 1447 return 1;
b226d99b 1448 }
02b59d57
TG
1449
1450 r = sd_rtnl_message_get_errno(m);
ef1ba606 1451 if (r < 0) {
c9ccc19f 1452 log_struct_link(LOG_ERR, link,
987efa17
TG
1453 "MESSAGE=%*s: could not enslave: %s",
1454 IFNAMSIZ,
c9ccc19f
TG
1455 link->ifname, strerror(-r),
1456 "ERRNO=%d", -r,
1457 NULL);
ef1ba606 1458 link_enter_failed(link);
b226d99b 1459 link_unref(link);
ef1ba606 1460 return 1;
3333d748 1461 }
02b59d57 1462
52433f6b 1463 log_debug_link(link, "enslaved");
ab47d620 1464
52433f6b
TG
1465 if (link->enslaving == 0)
1466 link_enslaved(link);
02b59d57 1467
b226d99b
TG
1468 link_unref(link);
1469
02b59d57
TG
1470 return 1;
1471}
1472
52433f6b 1473static int link_enter_enslave(Link *link) {
fe6b2d55 1474 NetDev *vlan, *macvlan;
672682a6 1475 Iterator i;
02b59d57
TG
1476 int r;
1477
1478 assert(link);
1479 assert(link->network);
505f8da7 1480 assert(link->state == LINK_STATE_INITIALIZING);
02b59d57 1481
52433f6b 1482 link->state = LINK_STATE_ENSLAVING;
02b59d57 1483
fe8db0c5
TG
1484 link_save(link);
1485
7951dea2
SS
1486 if (!link->network->bridge &&
1487 !link->network->bond &&
1488 !link->network->tunnel &&
fe6b2d55
TG
1489 hashmap_isempty(link->network->vlans) &&
1490 hashmap_isempty(link->network->macvlans))
52433f6b 1491 return link_enslaved(link);
02b59d57 1492
d9c67ea1 1493 if (link->network->bond) {
52433f6b 1494 log_struct_link(LOG_DEBUG, link,
987efa17
TG
1495 "MESSAGE=%*s: enslaving by '%s'",
1496 IFNAMSIZ,
af4e9e2c 1497 link->ifname, link->network->bond->ifname,
d9c67ea1 1498 NETDEV(link->network->bond),
52433f6b 1499 NULL);
449f7554 1500
d9c67ea1 1501 r = netdev_enslave(link->network->bond, link, &enslave_handler);
52433f6b
TG
1502 if (r < 0) {
1503 log_struct_link(LOG_WARNING, link,
987efa17
TG
1504 "MESSAGE=%*s: could not enslave by '%s': %s",
1505 IFNAMSIZ,
af4e9e2c 1506 link->ifname, link->network->bond->ifname, strerror(-r),
d9c67ea1 1507 NETDEV(link->network->bond),
52433f6b
TG
1508 NULL);
1509 link_enter_failed(link);
1510 return r;
1511 }
1512
b226d99b 1513 link_ref(link);
0ad6148e
MO
1514 link->enslaving ++;
1515 }
1516
d9c67ea1 1517 if (link->network->bridge) {
0ad6148e 1518 log_struct_link(LOG_DEBUG, link,
987efa17
TG
1519 "MESSAGE=%*s: enslaving by '%s'",
1520 IFNAMSIZ,
af4e9e2c 1521 link->ifname, link->network->bridge->ifname,
d9c67ea1 1522 NETDEV(link->network->bridge),
0ad6148e
MO
1523 NULL);
1524
d9c67ea1 1525 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
0ad6148e
MO
1526 if (r < 0) {
1527 log_struct_link(LOG_WARNING, link,
987efa17
TG
1528 "MESSAGE=%*s: could not enslave by '%s': %s",
1529 IFNAMSIZ,
af4e9e2c 1530 link->ifname, link->network->bridge->ifname, strerror(-r),
d9c67ea1 1531 NETDEV(link->network->bridge),
0ad6148e
MO
1532 NULL);
1533 link_enter_failed(link);
1534 return r;
1535 }
1536
b226d99b 1537 link_ref(link);
52433f6b
TG
1538 link->enslaving ++;
1539 }
1540
7951dea2
SS
1541 if (link->network->tunnel) {
1542 log_struct_link(LOG_DEBUG, link,
987efa17
TG
1543 "MESSAGE=%*s: enslaving by '%s'",
1544 IFNAMSIZ,
af4e9e2c 1545 link->ifname, link->network->tunnel->ifname,
7951dea2
SS
1546 NETDEV(link->network->tunnel),
1547 NULL);
1548
1549 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1550 if (r < 0) {
1551 log_struct_link(LOG_WARNING, link,
987efa17
TG
1552 "MESSAGE=%*s: could not enslave by '%s': %s",
1553 IFNAMSIZ,
af4e9e2c 1554 link->ifname, link->network->tunnel->ifname, strerror(-r),
7951dea2
SS
1555 NETDEV(link->network->tunnel),
1556 NULL);
1557 link_enter_failed(link);
1558 return r;
1559 }
1560
1561 link_ref(link);
1562 link->enslaving ++;
1563 }
1564
672682a6 1565 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
52433f6b 1566 log_struct_link(LOG_DEBUG, link,
987efa17
TG
1567 "MESSAGE=%*s: enslaving by '%s'",
1568 IFNAMSIZ,
af4e9e2c 1569 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
52433f6b 1570
672682a6 1571 r = netdev_enslave(vlan, link, &enslave_handler);
52433f6b
TG
1572 if (r < 0) {
1573 log_struct_link(LOG_WARNING, link,
987efa17
TG
1574 "MESSAGE=%*s: could not enslave by '%s': %s",
1575 IFNAMSIZ,
af4e9e2c 1576 link->ifname, vlan->ifname, strerror(-r),
672682a6 1577 NETDEV(vlan), NULL);
52433f6b
TG
1578 link_enter_failed(link);
1579 return r;
1580 }
1581
b226d99b 1582 link_ref(link);
52433f6b 1583 link->enslaving ++;
ef1ba606
TG
1584 }
1585
fe6b2d55
TG
1586 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1587 log_struct_link(LOG_DEBUG, link,
987efa17
TG
1588 "MESSAGE=%*s: enslaving by '%s'",
1589 IFNAMSIZ,
af4e9e2c 1590 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
fe6b2d55
TG
1591
1592 r = netdev_enslave(macvlan, link, &enslave_handler);
1593 if (r < 0) {
1594 log_struct_link(LOG_WARNING, link,
987efa17
TG
1595 "MESSAGE=%*s: could not enslave by '%s': %s",
1596 IFNAMSIZ,
af4e9e2c 1597 link->ifname, macvlan->ifname, strerror(-r),
fe6b2d55
TG
1598 NETDEV(macvlan), NULL);
1599 link_enter_failed(link);
1600 return r;
1601 }
1602
b226d99b 1603 link_ref(link);
fe6b2d55
TG
1604 link->enslaving ++;
1605 }
1606
ef1ba606
TG
1607 return 0;
1608}
1609
a748b692 1610static int link_configure(Link *link) {
02b59d57
TG
1611 int r;
1612
ef1ba606 1613 assert(link);
505f8da7 1614 assert(link->state == LINK_STATE_INITIALIZING);
a748b692 1615
eb34d4af 1616 if (link->network->ipv4ll) {
b5db00e5 1617 uint8_t seed[8];
45ad2c13 1618
eb34d4af
TG
1619 r = sd_ipv4ll_new(&link->ipv4ll);
1620 if (r < 0)
1621 return r;
1622
505f8da7
TG
1623 if (link->udev_device) {
1624 r = net_get_unique_predictable_data(link->udev_device, seed);
1625 if (r >= 0) {
1626 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1627 if (r < 0)
1628 return r;
1629 }
b5db00e5
UTL
1630 }
1631
eb34d4af
TG
1632 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1633 if (r < 0)
1634 return r;
1635
4bb40e81
TG
1636 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1637 if (r < 0)
1638 return r;
1639
eb34d4af
TG
1640 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1641 if (r < 0)
1642 return r;
1643
1644 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1645 if (r < 0)
1646 return r;
1647 }
1648
1649 if (link->network->dhcp) {
1650 r = sd_dhcp_client_new(&link->dhcp_client);
1651 if (r < 0)
1652 return r;
1653
1654 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1655 if (r < 0)
1656 return r;
1657
4bb40e81
TG
1658 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1659 if (r < 0)
1660 return r;
1661
eb34d4af
TG
1662 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1663 if (r < 0)
1664 return r;
1665
1666 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1667 if (r < 0)
1668 return r;
1669
1670 if (link->network->dhcp_mtu) {
1671 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1672 if (r < 0)
1673 return r;
1674 }
1675 }
1676
deb2e523 1677 if (link_has_carrier(link->flags, link->operstate)) {
1e9be60b
TG
1678 r = link_acquire_conf(link);
1679 if (r < 0)
1680 return r;
cc544d5f 1681 }
1e9be60b 1682
505f8da7
TG
1683 return link_enter_enslave(link);
1684}
1685
1686int link_initialized(Link *link, struct udev_device *device) {
1687 Network *network;
505f8da7
TG
1688 int r;
1689
1690 assert(link);
1691 assert(link->ifname);
1692 assert(link->manager);
1693
1694 if (link->state != LINK_STATE_INITIALIZING)
1695 return 0;
1696
1697 if (device)
1698 link->udev_device = udev_device_ref(device);
1699
16cd414b 1700 log_debug_link(link, "udev initialized link");
505f8da7
TG
1701
1702 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
57bd6899
TG
1703 if (r == -ENOENT) {
1704 link_enter_unmanaged(link);
1705 return 0;
1706 } else if (r < 0)
1707 return r;
505f8da7
TG
1708
1709 r = network_apply(link->manager, network, link);
1710 if (r < 0)
1711 return r;
1712
a748b692
TG
1713 r = link_configure(link);
1714 if (r < 0)
1715 return r;
1716
505f8da7
TG
1717 return 0;
1718}
1719
fbbeb65a
TG
1720int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1721 Manager *m = userdata;
1722 Link *link = NULL;
1723 uint16_t type;
1724 _cleanup_address_free_ Address *address = NULL;
428fd0a7 1725 Address *ad;
fbbeb65a 1726 char buf[INET6_ADDRSTRLEN];
428fd0a7 1727 bool address_dropped = false;
fbbeb65a
TG
1728 int r, ifindex;
1729
1730 assert(rtnl);
1731 assert(message);
1732 assert(m);
1733
1734 r = sd_rtnl_message_get_type(message, &type);
1735 if (r < 0) {
1736 log_warning("rtnl: could not get message type");
1737 return 0;
1738 }
1739
1740 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1741 if (r < 0 || ifindex <= 0) {
5ea846cc 1742 log_warning("rtnl: received address message without valid ifindex, ignoring");
fbbeb65a
TG
1743 return 0;
1744 } else {
1745 r = link_get(m, ifindex, &link);
1746 if (r < 0 || !link) {
5ea846cc 1747 log_warning("rtnl: received address for a nonexistent link, ignoring");
fbbeb65a
TG
1748 return 0;
1749 }
1750 }
1751
1752 r = address_new_dynamic(&address);
1753 if (r < 0)
1754 return 0;
1755
1756 r = sd_rtnl_message_addr_get_family(message, &address->family);
1757 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
987efa17 1758 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
fbbeb65a
TG
1759 return 0;
1760 }
1761
1762 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1763 if (r < 0) {
987efa17 1764 log_warning_link(link, "rtnl: recevied address with invalid prefixlen, ignoring");
fbbeb65a
TG
1765 return 0;
1766 }
1767
1768 switch (address->family) {
1769 case AF_INET:
1770 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1771 if (r < 0) {
987efa17 1772 log_warning_link(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1773 return 0;
1774 }
1775
1776 break;
1777
1778 case AF_INET6:
1779 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1780 if (r < 0) {
987efa17 1781 log_warning_link(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1782 return 0;
1783 }
1784
1785 break;
1786
1787 default:
1788 assert_not_reached("invalid address family");
1789 }
1790
1791 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
987efa17 1792 log_warning_link(link, "could not print address");
fbbeb65a
TG
1793 return 0;
1794 }
1795
428fd0a7
TG
1796 LIST_FOREACH(addresses, ad, link->addresses) {
1797 if (address_equal(ad, address)) {
1798 LIST_REMOVE(addresses, link->addresses, ad);
1799
1800 address_free(ad);
1801
1802 address_dropped = true;
1803
1804 break;
1805 }
1806 }
1807
fbbeb65a
TG
1808 switch (type) {
1809 case RTM_NEWADDR:
428fd0a7
TG
1810 if (!address_dropped)
1811 log_debug_link(link, "added address: %s/%u", buf,
1812 address->prefixlen);
fbbeb65a 1813
428fd0a7
TG
1814 LIST_PREPEND(addresses, link->addresses, address);
1815 address = NULL;
1816
1817 break;
fbbeb65a 1818 case RTM_DELADDR:
428fd0a7
TG
1819 if (address_dropped)
1820 log_debug_link(link, "removed address: %s/%u", buf,
1821 address->prefixlen);
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
TG
1978
1979int link_save(Link *link) {
68a8723c 1980 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 1981 _cleanup_fclose_ FILE *f = NULL;
deb2e523 1982 const char *admin_state, *oper_state = "unknown";
fe8db0c5
TG
1983 int r;
1984
1985 assert(link);
1986 assert(link->state_file);
68a8723c 1987 assert(link->lease_file);
bbf7c048
TG
1988 assert(link->manager);
1989
1990 r = manager_save(link->manager);
1991 if (r < 0)
1992 return r;
fe8db0c5 1993
370e9930
TG
1994 if (link->state == LINK_STATE_LINGER) {
1995 unlink(link->state_file);
1996 return 0;
1997 }
1998
deb2e523
TG
1999 admin_state = link_state_to_string(link->state);
2000 assert(admin_state);
2001
75adc218 2002 if (link->operstate == IF_OPER_DORMANT)
deb2e523
TG
2003 oper_state = "dormant";
2004 else if (link_has_carrier(link->flags, link->operstate))
2005 oper_state = "carrier";
2006
fe8db0c5
TG
2007 r = fopen_temporary(link->state_file, &f, &temp_path);
2008 if (r < 0)
2009 goto finish;
2010
2011 fchmod(fileno(f), 0644);
2012
2013 fprintf(f,
2014 "# This is private data. Do not parse.\n"
deb2e523
TG
2015 "ADMIN_STATE=%s\n"
2016 "OPER_STATE=%s\n"
2017 "FLAGS=%u\n",
2018 admin_state, oper_state, link->flags);
fe8db0c5
TG
2019
2020 if (link->dhcp_lease) {
68a8723c 2021 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5
TG
2022 if (r < 0)
2023 goto finish;
2024
68a8723c 2025 fprintf(f, "DHCP_LEASE=%s\n", link->lease_file);
deb2e523 2026 } else
68a8723c 2027 unlink(link->lease_file);
fe8db0c5
TG
2028
2029 fflush(f);
2030
2031 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2032 r = -errno;
2033 unlink(link->state_file);
2034 unlink(temp_path);
2035 }
2036
2037finish:
2038 if (r < 0)
987efa17 2039 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
fe8db0c5
TG
2040
2041 return r;
2042}
2043
2044static const char* const link_state_table[_LINK_STATE_MAX] = {
deb2e523 2045 [LINK_STATE_INITIALIZING] = "initializing",
fe8db0c5
TG
2046 [LINK_STATE_ENSLAVING] = "configuring",
2047 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2048 [LINK_STATE_SETTING_ROUTES] = "configuring",
2049 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 2050 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 2051 [LINK_STATE_FAILED] = "failed",
370e9930 2052 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
2053};
2054
2055DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);