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