]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
man: sd_journal_send does nothing when journald is not available
[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);
8ddbeaa2
UTL
304 if (r < 0 && r != -ENOENT) {
305 log_warning_link(link, "DHCP error: %s", strerror(-r));
a6cc569e
TG
306 return r;
307 }
308
8ddbeaa2
UTL
309 if (r >= 0) {
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 }
a6cc569e 316
8ddbeaa2
UTL
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 }
9765ce69 323
8ddbeaa2
UTL
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;
9765ce69 331
8ddbeaa2
UTL
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 }
9765ce69 338
8ddbeaa2 339 link->route_messages ++;
9765ce69 340
8ddbeaa2
UTL
341 route->family = AF_INET;
342 route->in_addr.in = gateway;
a6cc569e 343
8ddbeaa2
UTL
344 r = route_configure(route, link, &route_handler);
345 if (r < 0) {
346 log_warning_link(link,
347 "could not set routes: %s", strerror(-r));
348 link_enter_failed(link);
349 return r;
350 }
351
352 link->route_messages ++;
f5be5601 353 }
8ddbeaa2 354 }
f5be5601 355
8ddbeaa2
UTL
356 if (link->route_messages == 0) {
357 link_enter_configured(link);
f882c247
TG
358 }
359
360 return 0;
361}
362
5c1d3fc9
UTL
363static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
364 Link *link = userdata;
365 int r;
366
367 assert(m);
368 assert(link);
369 assert(link->ifname);
370
371 if (link->state == LINK_STATE_FAILED)
372 return 1;
373
374 r = sd_rtnl_message_get_errno(m);
375 if (r < 0 && r != -ENOENT)
376 log_struct_link(LOG_WARNING, link,
377 "MESSAGE=%s: could not drop route: %s",
378 link->ifname, strerror(-r),
379 "ERRNO=%d", -r,
380 NULL);
381
382 return 0;
383}
384
f882c247
TG
385static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
386 Link *link = userdata;
387 int r;
388
f5be5601
TG
389 assert(m);
390 assert(link);
391 assert(link->ifname);
392 assert(link->addr_messages > 0);
ef1ba606 393 assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
f882c247 394
f5be5601 395 link->addr_messages --;
f882c247
TG
396
397 if (link->state == LINK_STATE_FAILED)
398 return 1;
399
400 r = sd_rtnl_message_get_errno(m);
c166a070 401 if (r < 0 && r != -EEXIST)
c9ccc19f 402 log_struct_link(LOG_WARNING, link,
3333d748
ZJS
403 "MESSAGE=%s: could not set address: %s",
404 link->ifname, strerror(-r),
405 "ERRNO=%d", -r,
406 NULL);
f882c247 407
f5be5601 408 if (link->addr_messages == 0) {
39032b87 409 log_debug_link(link, "addresses set");
ef1ba606 410 link_enter_set_routes(link);
dd3efc09 411 }
f882c247
TG
412
413 return 1;
414}
415
416static int link_enter_set_addresses(Link *link) {
a6cc569e 417 Address *ad;
f882c247
TG
418 int r;
419
420 assert(link);
421 assert(link->network);
f5be5601 422 assert(link->state != _LINK_STATE_INVALID);
f882c247 423
ef1ba606 424 link->state = LINK_STATE_SETTING_ADDRESSES;
f882c247 425
5c1d3fc9 426 if (!link->network->static_addresses && !link->dhcp_lease &&
aba496a5 427 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
ef1ba606 428 return link_enter_set_routes(link);
f882c247 429
39032b87 430 log_debug_link(link, "setting addresses");
449f7554 431
a6cc569e
TG
432 LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
433 r = address_configure(ad, link, &address_handler);
dd3efc09 434 if (r < 0) {
3333d748
ZJS
435 log_warning_link(link,
436 "could not set addresses: %s", strerror(-r));
ef1ba606
TG
437 link_enter_failed(link);
438 return r;
dd3efc09 439 }
c166a070 440
f5be5601
TG
441 link->addr_messages ++;
442 }
443
5c1d3fc9
UTL
444 if (link->ipv4ll && !link->dhcp_lease) {
445 _cleanup_address_free_ Address *ll_addr = NULL;
446 struct in_addr addr;
447
448 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
449 if (r < 0 && r != -ENOENT) {
450 log_warning_link(link, "IPV4LL error: no address: %s",
451 strerror(-r));
452 return r;
453 }
454
455 if (r != -ENOENT) {
456 r = address_new_dynamic(&ll_addr);
457 if (r < 0) {
458 log_error_link(link, "Could not allocate address: %s", strerror(-r));
459 return r;
460 }
461
462 ll_addr->family = AF_INET;
463 ll_addr->in_addr.in = addr;
464 ll_addr->prefixlen = 16;
465 ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
466 ll_addr->scope = RT_SCOPE_LINK;
467
468 r = address_configure(ll_addr, link, &address_handler);
469 if (r < 0) {
470 log_warning_link(link,
471 "could not set addresses: %s", strerror(-r));
472 link_enter_failed(link);
473 return r;
474 }
475
476 link->addr_messages ++;
477 }
478 }
479
a6cc569e
TG
480 if (link->dhcp_lease) {
481 _cleanup_address_free_ Address *address = NULL;
482 struct in_addr addr;
483 struct in_addr netmask;
484 unsigned prefixlen;
485
486 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
487 if (r < 0) {
488 log_warning_link(link, "DHCP error: no address: %s",
489 strerror(-r));
490 return r;
491 }
492
493 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
494 if (r < 0) {
495 log_warning_link(link, "DHCP error: no netmask: %s",
496 strerror(-r));
497 return r;
498 }
499
500 prefixlen = net_netmask_to_prefixlen(&netmask);
501
502 r = address_new_dynamic(&address);
503 if (r < 0) {
504 log_error_link(link, "Could not allocate address: %s",
505 strerror(-r));
506 return r;
507 }
508
509 address->family = AF_INET;
510 address->in_addr.in = addr;
511 address->prefixlen = prefixlen;
512 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
513
514 r = address_configure(address, link, &address_handler);
f5be5601 515 if (r < 0) {
3333d748
ZJS
516 log_warning_link(link,
517 "could not set addresses: %s", strerror(-r));
f5be5601
TG
518 link_enter_failed(link);
519 return r;
520 }
521
522 link->addr_messages ++;
f882c247
TG
523 }
524
525 return 0;
526}
527
aba496a5
UTL
528static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
529 Link *link = userdata;
530 int r;
531
532 assert(m);
533 assert(link);
534 assert(link->ifname);
535
536 if (link->state == LINK_STATE_FAILED)
537 return 1;
538
539 r = sd_rtnl_message_get_errno(m);
540 if (r < 0 && r != -ENOENT)
541 log_struct_link(LOG_WARNING, link,
542 "MESSAGE=%s: could not update address: %s",
543 link->ifname, strerror(-r),
544 "ERRNO=%d", -r,
545 NULL);
546
547 return 0;
548}
549
ff254138
TG
550static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
551 Link *link = userdata;
552 int r;
553
554 assert(m);
555 assert(link);
556 assert(link->ifname);
557
558 if (link->state == LINK_STATE_FAILED)
559 return 1;
560
561 r = sd_rtnl_message_get_errno(m);
c9ccc19f
TG
562 if (r < 0 && r != -ENOENT)
563 log_struct_link(LOG_WARNING, link,
564 "MESSAGE=%s: could not drop address: %s",
565 link->ifname, strerror(-r),
566 "ERRNO=%d", -r,
567 NULL);
ff254138 568
5c1d3fc9 569 return 0;
ff254138
TG
570}
571
1346b1f0
TG
572static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
573 int r;
574
575 r = sd_bus_message_get_errno(m);
576 if (r < 0)
577 log_warning("Could not set hostname: %s", strerror(-r));
578
579 return 1;
580}
581
582static int set_hostname(sd_bus *bus, const char *hostname) {
583 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
584 int r = 0;
585
1346b1f0
TG
586 assert(hostname);
587
588 log_debug("Setting transient hostname: '%s'", hostname);
589
bcbca829
TG
590 if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
591 log_info("Not connected to system bus, ignoring transient hostname.");
592 return 0;
593 }
594
1346b1f0
TG
595 r = sd_bus_message_new_method_call(
596 bus,
151b9b96 597 &m,
1346b1f0
TG
598 "org.freedesktop.hostname1",
599 "/org/freedesktop/hostname1",
600 "org.freedesktop.hostname1",
151b9b96 601 "SetHostname");
1346b1f0
TG
602 if (r < 0)
603 return r;
604
605 r = sd_bus_message_append(m, "sb", hostname, false);
606 if (r < 0)
607 return r;
608
609 r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
610 if (r < 0)
611 log_error("Could not set transient hostname: %s", strerror(-r));
612
613 return r;
614}
615
4f882b2a
TG
616static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
617 Link *link = userdata;
618 int r;
619
620 assert(m);
621 assert(link);
622 assert(link->ifname);
623
624 if (link->state == LINK_STATE_FAILED)
625 return 1;
626
627 r = sd_rtnl_message_get_errno(m);
c9ccc19f
TG
628 if (r < 0)
629 log_struct_link(LOG_WARNING, link,
630 "MESSAGE=%s: could not set MTU: %s",
631 link->ifname, strerror(-r),
632 "ERRNO=%d", -r,
633 NULL);
4f882b2a
TG
634
635 return 1;
636}
637
638static int link_set_mtu(Link *link, uint32_t mtu) {
cf6a8911 639 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
4f882b2a
TG
640 int r;
641
642 assert(link);
643 assert(link->manager);
644 assert(link->manager->rtnl);
645
646 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
647
151b9b96
LP
648 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
649 RTM_SETLINK, link->ifindex);
4f882b2a
TG
650 if (r < 0) {
651 log_error_link(link, "Could not allocate RTM_SETLINK message");
652 return r;
653 }
654
655 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
656 if (r < 0) {
657 log_error_link(link, "Could not append MTU: %s", strerror(-r));
658 return r;
659 }
660
661 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
662 if (r < 0) {
663 log_error_link(link,
664 "Could not send rtnetlink message: %s", strerror(-r));
665 return r;
666 }
667
668 return 0;
669}
670
a6cc569e
TG
671static int dhcp_lease_lost(Link *link) {
672 _cleanup_address_free_ Address *address = NULL;
3e790eae
UTL
673 _cleanup_route_free_ Route *route_gw = NULL;
674 _cleanup_route_free_ Route *route = NULL;
a6cc569e
TG
675 struct in_addr addr;
676 struct in_addr netmask;
3e790eae 677 struct in_addr gateway;
a6cc569e 678 unsigned prefixlen;
ff254138
TG
679 int r;
680
681 assert(link);
a6cc569e 682 assert(link->dhcp_lease);
ff254138 683
14efd761
TG
684 log_warning_link(link, "DHCP lease lost");
685
a6cc569e
TG
686 r = address_new_dynamic(&address);
687 if (r >= 0) {
8ddbeaa2 688 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
3e790eae 689 if (r >= 0) {
8ddbeaa2
UTL
690 r = route_new_dynamic(&route_gw);
691 if (r >= 0) {
692 route_gw->family = AF_INET;
693 route_gw->dst_addr.in = gateway;
694 route_gw->dst_prefixlen = 32;
695 route_gw->scope = RT_SCOPE_LINK;
696
697 route_drop(route_gw, link, &route_drop_handler);
698 }
3e790eae 699
8ddbeaa2
UTL
700 r = route_new_dynamic(&route);
701 if (r >= 0) {
702 route->family = AF_INET;
703 route->in_addr.in = gateway;
3e790eae 704
8ddbeaa2
UTL
705 route_drop(route, link, &route_drop_handler);
706 }
3e790eae
UTL
707 }
708
8ddbeaa2
UTL
709 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
710 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
711 prefixlen = net_netmask_to_prefixlen(&netmask);
712
a6cc569e
TG
713 address->family = AF_INET;
714 address->in_addr.in = addr;
715 address->prefixlen = prefixlen;
ff254138 716
5c1d3fc9 717 address_drop(address, link, &address_drop_handler);
c07aeadf 718 }
eb27aeca 719
c07aeadf
TG
720 if (link->network->dhcp_mtu) {
721 uint16_t mtu;
ff254138 722
a6cc569e 723 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
c07aeadf
TG
724 if (r >= 0 && link->original_mtu != mtu) {
725 r = link_set_mtu(link, link->original_mtu);
726 if (r < 0) {
727 log_warning_link(link, "DHCP error: could not reset MTU");
728 link_enter_failed(link);
729 return r;
730 }
ff254138 731 }
c07aeadf 732 }
ff254138 733
c07aeadf 734 if (link->network->dhcp_hostname) {
216816c6
TG
735 const char *hostname = NULL;
736
737 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
738 if (r >= 0 && hostname) {
739 r = set_hostname(link->manager->bus, "");
740 if (r < 0)
741 log_error("Failed to reset transient hostname");
742 }
c07aeadf 743 }
4f882b2a 744
a6cc569e
TG
745 link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
746
c07aeadf
TG
747 return 0;
748}
4f882b2a 749
c07aeadf 750static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
a6cc569e 751 sd_dhcp_lease *lease;
c07aeadf
TG
752 struct in_addr address;
753 struct in_addr netmask;
754 struct in_addr gateway;
755 unsigned prefixlen;
c07aeadf
TG
756 struct in_addr *nameservers;
757 size_t nameservers_size;
758 int r;
1346b1f0 759
c07aeadf
TG
760 assert(client);
761 assert(link);
ff254138 762
a6cc569e
TG
763 r = sd_dhcp_client_get_lease(client, &lease);
764 if (r < 0) {
765 log_warning_link(link, "DHCP error: no lease: %s",
766 strerror(-r));
767 return r;
768 }
769
770 r = sd_dhcp_lease_get_address(lease, &address);
ff254138 771 if (r < 0) {
c07aeadf
TG
772 log_warning_link(link, "DHCP error: no address: %s",
773 strerror(-r));
774 return r;
ff254138
TG
775 }
776
a6cc569e 777 r = sd_dhcp_lease_get_netmask(lease, &netmask);
ff254138 778 if (r < 0) {
c07aeadf
TG
779 log_warning_link(link, "DHCP error: no netmask: %s",
780 strerror(-r));
781 return r;
ff254138
TG
782 }
783
377a218f 784 prefixlen = net_netmask_to_prefixlen(&netmask);
ff254138 785
a6cc569e 786 r = sd_dhcp_lease_get_router(lease, &gateway);
8ddbeaa2
UTL
787 if (r < 0 && r != -ENOENT) {
788 log_warning_link(link, "DHCP error: %s", strerror(-r));
c07aeadf 789 return r;
ff254138
TG
790 }
791
8ddbeaa2
UTL
792 if (r >= 0)
793 log_struct_link(LOG_INFO, link,
794 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
795 link->ifname,
796 ADDRESS_FMT_VAL(address),
797 prefixlen,
798 ADDRESS_FMT_VAL(gateway),
799 "ADDRESS=%u.%u.%u.%u",
800 ADDRESS_FMT_VAL(address),
801 "PREFIXLEN=%u",
802 prefixlen,
803 "GATEWAY=%u.%u.%u.%u",
804 ADDRESS_FMT_VAL(gateway),
805 NULL);
806 else
807 log_struct_link(LOG_INFO, link,
808 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u",
809 link->ifname,
810 ADDRESS_FMT_VAL(address),
811 prefixlen,
812 "ADDRESS=%u.%u.%u.%u",
813 ADDRESS_FMT_VAL(address),
814 "PREFIXLEN=%u",
815 prefixlen,
816 NULL);
c07aeadf 817
d50cf59b
TG
818 link->dhcp_lease = lease;
819
c07aeadf 820 if (link->network->dhcp_dns) {
a6cc569e 821 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
c07aeadf
TG
822 if (r >= 0) {
823 r = manager_update_resolv_conf(link->manager);
824 if (r < 0)
825 log_error("Failed to update resolv.conf");
ff254138 826 }
c07aeadf 827 }
ff254138 828
c07aeadf
TG
829 if (link->network->dhcp_mtu) {
830 uint16_t mtu;
831
a6cc569e 832 r = sd_dhcp_lease_get_mtu(lease, &mtu);
c07aeadf
TG
833 if (r >= 0) {
834 r = link_set_mtu(link, mtu);
835 if (r < 0)
836 log_error_link(link, "Failed to set MTU "
837 "to %" PRIu16, mtu);
838 }
839 }
ff254138 840
c07aeadf
TG
841 if (link->network->dhcp_hostname) {
842 const char *hostname;
ff254138 843
a6cc569e 844 r = sd_dhcp_lease_get_hostname(lease, &hostname);
c07aeadf
TG
845 if (r >= 0) {
846 r = set_hostname(link->manager->bus, hostname);
847 if (r < 0)
848 log_error("Failed to set transient hostname "
849 "to '%s'", hostname);
3bef724f 850 }
c07aeadf 851 }
3bef724f 852
c07aeadf
TG
853 link_enter_set_addresses(link);
854
855 return 0;
856}
857
858static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
859 Link *link = userdata;
aba496a5 860 int r = 0;
c07aeadf
TG
861
862 assert(link);
863 assert(link->network);
864 assert(link->manager);
865
866 if (link->state == LINK_STATE_FAILED)
867 return;
868
869 switch (event) {
870 case DHCP_EVENT_NO_LEASE:
871 log_debug_link(link, "IP address in use.");
872 break;
873 case DHCP_EVENT_EXPIRED:
874 case DHCP_EVENT_STOP:
875 case DHCP_EVENT_IP_CHANGE:
876 if (link->network->dhcp_critical) {
877 log_error_link(link, "DHCPv4 connection considered system critical, "
878 "ignoring request to reconfigure it.");
879 return;
4f882b2a 880 }
4f882b2a 881
17256461
UTL
882 if (link->dhcp_lease) {
883 r = dhcp_lease_lost(link);
884 if (r < 0) {
885 link_enter_failed(link);
886 return;
887 }
c07aeadf 888 }
1346b1f0 889
c07aeadf
TG
890 if (event == DHCP_EVENT_IP_CHANGE) {
891 r = dhcp_lease_acquired(client, link);
892 if (r < 0) {
893 link_enter_failed(link);
894 return;
895 }
1346b1f0 896 }
1346b1f0 897
5c1d3fc9 898 if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
aba496a5
UTL
899 if (!sd_ipv4ll_is_running(link->ipv4ll))
900 r = sd_ipv4ll_start(link->ipv4ll);
901 else if (ipv4ll_is_bound(link->ipv4ll))
902 r = ipv4ll_address_update(link, false);
5c1d3fc9
UTL
903 if (r < 0) {
904 link_enter_failed(link);
905 return;
906 }
907 }
908
c07aeadf
TG
909 break;
910 case DHCP_EVENT_IP_ACQUIRE:
911 r = dhcp_lease_acquired(client, link);
912 if (r < 0) {
913 link_enter_failed(link);
914 return;
915 }
5c1d3fc9 916 if (link->ipv4ll) {
aba496a5
UTL
917 if (ipv4ll_is_bound(link->ipv4ll))
918 r = ipv4ll_address_update(link, true);
919 else
920 r = sd_ipv4ll_stop(link->ipv4ll);
5c1d3fc9
UTL
921 if (r < 0) {
922 link_enter_failed(link);
923 return;
924 }
925 }
c07aeadf
TG
926 break;
927 default:
928 if (event < 0)
929 log_warning_link(link, "DHCP error: %s", strerror(-event));
930 else
931 log_warning_link(link, "DHCP unknown event: %d", event);
c07aeadf 932 break;
ff254138
TG
933 }
934
935 return;
936}
937
aba496a5
UTL
938static int ipv4ll_address_update(Link *link, bool deprecate) {
939 int r;
940 struct in_addr addr;
941
942 assert(link);
943
944 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
945 if (r >= 0) {
946 _cleanup_address_free_ Address *address = NULL;
947
948 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
949 deprecate ? "deprecate" : "approve",
950 ADDRESS_FMT_VAL(addr));
951
952 r = address_new_dynamic(&address);
953 if (r < 0) {
954 log_error_link(link, "Could not allocate address: %s", strerror(-r));
955 return r;
956 }
957
958 address->family = AF_INET;
959 address->in_addr.in = addr;
960 address->prefixlen = 16;
961 address->scope = RT_SCOPE_LINK;
962 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
963 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
964
965 address_update(address, link, &address_update_handler);
966 }
967
968 return 0;
969
970}
971
972static int ipv4ll_address_lost(Link *link) {
5c1d3fc9
UTL
973 int r;
974 struct in_addr addr;
975
5c1d3fc9
UTL
976 assert(link);
977
978 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
979 if (r >= 0) {
980 _cleanup_address_free_ Address *address = NULL;
981 _cleanup_route_free_ Route *route = NULL;
982
983 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
984 ADDRESS_FMT_VAL(addr));
985
986 r = address_new_dynamic(&address);
987 if (r < 0) {
988 log_error_link(link, "Could not allocate address: %s", strerror(-r));
989 return r;
990 }
991
992 address->family = AF_INET;
993 address->in_addr.in = addr;
994 address->prefixlen = 16;
995 address->scope = RT_SCOPE_LINK;
996
997 address_drop(address, link, &address_drop_handler);
998
999 r = route_new_dynamic(&route);
1000 if (r < 0) {
1001 log_error_link(link, "Could not allocate route: %s",
1002 strerror(-r));
1003 return r;
1004 }
1005
1006 route->family = AF_INET;
1007 route->scope = RT_SCOPE_LINK;
1008 route->metrics = 99;
1009
1010 route_drop(route, link, &route_drop_handler);
1011 }
1012
1013 return 0;
1014}
1015
aba496a5
UTL
1016static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1017 int r;
1018 struct in_addr addr;
1019
1020 assert(ll);
1021
1022 r = sd_ipv4ll_get_address(ll, &addr);
1023 if (r < 0)
1024 return false;
1025 return true;
1026}
1027
5c1d3fc9
UTL
1028static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1029 struct in_addr address;
1030 int r;
1031
1032 assert(ll);
1033 assert(link);
1034
1035 r = sd_ipv4ll_get_address(ll, &address);
1036 if (r < 0)
1037 return r;
1038
1039 log_struct_link(LOG_INFO, link,
1040 "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
1041 link->ifname,
1042 ADDRESS_FMT_VAL(address),
1043 NULL);
1044
1045 link_enter_set_addresses(link);
1046
1047 return 0;
1048}
1049
1050static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1051 Link *link = userdata;
1052 int r;
1053
1054 assert(link);
1055 assert(link->network);
1056 assert(link->manager);
1057
1058 switch(event) {
1059 case IPV4LL_EVENT_STOP:
1060 case IPV4LL_EVENT_CONFLICT:
aba496a5 1061 r = ipv4ll_address_lost(link);
5c1d3fc9
UTL
1062 if (r < 0) {
1063 link_enter_failed(link);
1064 return;
1065 }
1066 break;
1067 case IPV4LL_EVENT_BIND:
1068 r = ipv4ll_address_claimed(ll, link);
1069 if (r < 0) {
1070 link_enter_failed(link);
1071 return;
1072 }
1073 break;
1074 default:
1075 if (event < 0)
1076 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1077 else
1078 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1079 break;
1080 }
1081}
1082
ff254138
TG
1083static int link_acquire_conf(Link *link) {
1084 int r;
1085
1086 assert(link);
1087 assert(link->network);
ff254138
TG
1088 assert(link->manager);
1089 assert(link->manager->event);
1090
5c1d3fc9 1091 if (link->network->ipv4ll) {
eb34d4af 1092 assert(link->ipv4ll);
ff254138 1093
5c1d3fc9
UTL
1094 log_debug_link(link, "acquiring IPv4 link-local address");
1095
1096 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6
TG
1097 if (r < 0) {
1098 log_warning_link(link, "could not acquire IPv4 "
1099 "link-local address");
ff254138 1100 return r;
124fa2c6 1101 }
5c1d3fc9
UTL
1102 }
1103
1104 if (link->network->dhcp) {
eb34d4af 1105 assert(link->dhcp_client);
ff254138 1106
5c1d3fc9 1107 log_debug_link(link, "acquiring DHCPv4 lease");
ab47d620 1108
5c1d3fc9 1109 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6
TG
1110 if (r < 0) {
1111 log_warning_link(link, "could not acquire DHCPv4 "
1112 "lease");
5c1d3fc9 1113 return r;
124fa2c6 1114 }
5c1d3fc9 1115 }
ff254138
TG
1116
1117 return 0;
1118}
1119
bbf7c048 1120bool link_has_carrier(unsigned flags, uint8_t operstate) {
deb2e523
TG
1121 /* see Documentation/networking/operstates.txt in the kernel sources */
1122
1123 if (operstate == IF_OPER_UP)
1124 return true;
1125
1126 if (operstate == IF_OPER_UNKNOWN)
1127 /* operstate may not be implemented, so fall back to flags */
1128 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1129 return true;
1130
1131 return false;
1132}
1133
1e9be60b
TG
1134static int link_update_flags(Link *link, sd_rtnl_message *m) {
1135 unsigned flags, flags_added, flags_removed, generic_flags;
1136 uint8_t operstate;
1137 bool carrier_gained = false, carrier_lost = false;
ff254138
TG
1138 int r;
1139
1140 assert(link);
ff254138 1141
1e9be60b
TG
1142 r = sd_rtnl_message_link_get_flags(m, &flags);
1143 if (r < 0) {
1144 log_warning_link(link, "Could not get link flags");
1145 return r;
1146 }
1147
1148 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1149 if (r < 0)
1150 /* if we got a message without operstate, take it to mean
1151 the state was unchanged */
1152 operstate = link->operstate;
1153
1154 if ((link->flags == flags) && (link->operstate == operstate))
efbc88b8 1155 return 0;
efbc88b8 1156
ffba6166
TG
1157 flags_added = (link->flags ^ flags) & flags;
1158 flags_removed = (link->flags ^ flags) & link->flags;
c6a1eb79
TG
1159 generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_DORMANT | IFF_DEBUG |
1160 IFF_MULTICAST | IFF_BROADCAST | IFF_PROMISC |
d96e629f 1161 IFF_NOARP | IFF_MASTER | IFF_SLAVE | IFF_RUNNING);
c49b33ac 1162
ffba6166 1163 if (flags_added & IFF_UP)
df9aa406 1164 log_debug_link(link, "link is up");
ffba6166 1165 else if (flags_removed & IFF_UP)
df9aa406 1166 log_debug_link(link, "link is down");
ffba6166
TG
1167
1168 if (flags_added & IFF_LOWER_UP)
3379e257 1169 log_debug_link(link, "link is lower up");
ffba6166 1170 else if (flags_removed & IFF_LOWER_UP)
3379e257 1171 log_debug_link(link, "link is lower down");
ffba6166 1172
75ee87c8
TG
1173 if (flags_added & IFF_DORMANT)
1174 log_debug_link(link, "link is dormant");
1175 else if (flags_removed & IFF_DORMANT)
1176 log_debug_link(link, "link is not dormant");
ffba6166 1177
c6a1eb79
TG
1178 if (flags_added & IFF_DEBUG)
1179 log_debug_link(link, "debugging enabled in the kernel");
1180 else if (flags_removed & IFF_DEBUG)
1181 log_debug_link(link, "debugging disabled in the kernel");
1182
1183 if (flags_added & IFF_MULTICAST)
1184 log_debug_link(link, "multicast enabled");
1185 else if (flags_removed & IFF_MULTICAST)
1186 log_debug_link(link, "multicast disabled");
1187
1188 if (flags_added & IFF_BROADCAST)
1189 log_debug_link(link, "broadcast enabled");
1190 else if (flags_removed & IFF_BROADCAST)
1191 log_debug_link(link, "broadcast disabled");
1192
1193 if (flags_added & IFF_PROMISC)
1194 log_debug_link(link, "promiscuous mode enabled");
1195 else if (flags_removed & IFF_PROMISC)
1196 log_debug_link(link, "promiscuous mode disabled");
1197
1198 if (flags_added & IFF_NOARP)
1199 log_debug_link(link, "ARP protocol disabled");
1200 else if (flags_removed & IFF_NOARP)
1201 log_debug_link(link, "ARP protocol enabled");
1202
1203 if (flags_added & IFF_MASTER)
1204 log_debug_link(link, "link is master");
1205 else if (flags_removed & IFF_MASTER)
1206 log_debug_link(link, "link is no longer master");
1207
1208 if (flags_added & IFF_SLAVE)
1209 log_debug_link(link, "link is slave");
1210 else if (flags_removed & IFF_SLAVE)
1211 log_debug_link(link, "link is no longer slave");
1212
069e10a0 1213 /* link flags are currently at most 18 bits, let's default to printing 20 */
505f8da7 1214 if (flags_added & generic_flags)
069e10a0 1215 log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
505f8da7
TG
1216 flags_added & generic_flags);
1217
1218 if (flags_removed & generic_flags)
069e10a0 1219 log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
75ee87c8 1220 flags_removed & generic_flags);
505f8da7 1221
1e9be60b
TG
1222 carrier_gained = !link_has_carrier(link->flags, link->operstate) &&
1223 link_has_carrier(flags, operstate);
1224 carrier_lost = link_has_carrier(link->flags, link->operstate) &&
1225 !link_has_carrier(flags, operstate);
1226
1227 link->flags = flags;
1228 link->operstate = operstate;
1229
deb2e523
TG
1230 link_save(link);
1231
99b4cc3e
TG
1232 if (link->state == LINK_STATE_FAILED ||
1233 link->state == LINK_STATE_UNMANAGED)
1234 return 0;
1235
7cc832b9
TG
1236 if (carrier_gained) {
1237 log_info_link(link, "gained carrier");
ffba6166 1238
1e9be60b 1239 if (link->network) {
ffba6166
TG
1240 r = link_acquire_conf(link);
1241 if (r < 0) {
ffba6166
TG
1242 link_enter_failed(link);
1243 return r;
ff254138 1244 }
ffba6166 1245 }
7cc832b9
TG
1246 } else if (carrier_lost) {
1247 log_info_link(link, "lost carrier");
efbc88b8 1248
1e9be60b
TG
1249 r = link_stop_clients(link);
1250 if (r < 0) {
1251 link_enter_failed(link);
1252 return r;
ff254138
TG
1253 }
1254 }
1255
ff254138
TG
1256 return 0;
1257}
1258
dd3efc09
TG
1259static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1260 Link *link = userdata;
1261 int r;
1262
1746cf2a
TG
1263 assert(link);
1264
1265 if (link->state == LINK_STATE_FAILED)
1266 return 1;
1267
dd3efc09 1268 r = sd_rtnl_message_get_errno(m);
45ad2c13 1269 if (r < 0) {
9b86b393
TG
1270 /* we warn but don't fail the link, as it may
1271 be brought up later */
76800848 1272 log_struct_link(LOG_WARNING, link,
c9ccc19f
TG
1273 "MESSAGE=%s: could not bring up interface: %s",
1274 link->ifname, strerror(-r),
1275 "ERRNO=%d", -r,
1276 NULL);
45ad2c13
TG
1277 }
1278
f882c247
TG
1279 return 1;
1280}
1281
1282static int link_up(Link *link) {
cf6a8911 1283 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
1284 int r;
1285
f882c247
TG
1286 assert(link);
1287 assert(link->manager);
1288 assert(link->manager->rtnl);
1289
39032b87 1290 log_debug_link(link, "bringing link up");
449f7554 1291
151b9b96
LP
1292 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1293 RTM_SETLINK, link->ifindex);
f579559b 1294 if (r < 0) {
39032b87 1295 log_error_link(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1296 return r;
1297 }
1298
5d4795f3 1299 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1300 if (r < 0) {
3333d748 1301 log_error_link(link, "Could not set link flags: %s", strerror(-r));
fc25d7f8
TG
1302 return r;
1303 }
1304
dd3efc09 1305 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
f579559b 1306 if (r < 0) {
3333d748
ZJS
1307 log_error_link(link,
1308 "Could not send rtnetlink message: %s", strerror(-r));
f579559b
TG
1309 return r;
1310 }
1311
f882c247
TG
1312 return 0;
1313}
1314
52433f6b 1315static int link_enslaved(Link *link) {
f882c247
TG
1316 int r;
1317
ef1ba606 1318 assert(link);
52433f6b 1319 assert(link->state == LINK_STATE_ENSLAVING);
f5be5601 1320 assert(link->network);
dd3efc09 1321
505f8da7
TG
1322 if (!(link->flags & IFF_UP)) {
1323 r = link_up(link);
1324 if (r < 0) {
1325 link_enter_failed(link);
1326 return r;
1327 }
ef1ba606 1328 }
f882c247 1329
5c1d3fc9 1330 if (!link->network->dhcp && !link->network->ipv4ll)
1746cf2a 1331 return link_enter_set_addresses(link);
ef1ba606
TG
1332
1333 return 0;
02b59d57
TG
1334}
1335
52433f6b 1336static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
02b59d57
TG
1337 Link *link = userdata;
1338 int r;
1339
1746cf2a 1340 assert(link);
52433f6b 1341 assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
ef1ba606 1342 assert(link->network);
02b59d57 1343
52433f6b
TG
1344 link->enslaving --;
1345
02b59d57
TG
1346 if (link->state == LINK_STATE_FAILED)
1347 return 1;
1348
1349 r = sd_rtnl_message_get_errno(m);
ef1ba606 1350 if (r < 0) {
c9ccc19f
TG
1351 log_struct_link(LOG_ERR, link,
1352 "MESSAGE=%s: could not enslave: %s",
1353 link->ifname, strerror(-r),
1354 "ERRNO=%d", -r,
1355 NULL);
ef1ba606
TG
1356 link_enter_failed(link);
1357 return 1;
3333d748 1358 }
02b59d57 1359
52433f6b 1360 log_debug_link(link, "enslaved");
ab47d620 1361
52433f6b
TG
1362 if (link->enslaving == 0)
1363 link_enslaved(link);
02b59d57
TG
1364
1365 return 1;
1366}
1367
52433f6b 1368static int link_enter_enslave(Link *link) {
fe6b2d55 1369 NetDev *vlan, *macvlan;
672682a6 1370 Iterator i;
02b59d57
TG
1371 int r;
1372
1373 assert(link);
1374 assert(link->network);
505f8da7 1375 assert(link->state == LINK_STATE_INITIALIZING);
02b59d57 1376
52433f6b 1377 link->state = LINK_STATE_ENSLAVING;
02b59d57 1378
fe8db0c5
TG
1379 link_save(link);
1380
63ffa720 1381 if (!link->network->bridge && !link->network->bond &&
fe6b2d55
TG
1382 hashmap_isempty(link->network->vlans) &&
1383 hashmap_isempty(link->network->macvlans))
52433f6b 1384 return link_enslaved(link);
02b59d57 1385
52433f6b
TG
1386 if (link->network->bridge) {
1387 log_struct_link(LOG_DEBUG, link,
1388 "MESSAGE=%s: enslaving by '%s'",
c9ccc19f 1389 link->ifname, link->network->bridge->name,
52433f6b
TG
1390 NETDEV(link->network->bridge),
1391 NULL);
449f7554 1392
52433f6b
TG
1393 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1394 if (r < 0) {
1395 log_struct_link(LOG_WARNING, link,
1396 "MESSAGE=%s: could not enslave by '%s': %s",
c9ccc19f 1397 link->ifname, link->network->bridge->name, strerror(-r),
52433f6b
TG
1398 NETDEV(link->network->bridge),
1399 NULL);
1400 link_enter_failed(link);
1401 return r;
1402 }
1403
0ad6148e
MO
1404 link->enslaving ++;
1405 }
1406
1407 if (link->network->bond) {
1408 log_struct_link(LOG_DEBUG, link,
1409 "MESSAGE=%s: enslaving by '%s'",
1410 link->ifname, link->network->bond->name,
1411 NETDEV(link->network->bond),
1412 NULL);
1413
1414 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1415 if (r < 0) {
1416 log_struct_link(LOG_WARNING, link,
1417 "MESSAGE=%s: could not enslave by '%s': %s",
1418 link->ifname, link->network->bond->name, strerror(-r),
1419 NETDEV(link->network->bond),
1420 NULL);
1421 link_enter_failed(link);
1422 return r;
1423 }
1424
52433f6b
TG
1425 link->enslaving ++;
1426 }
1427
672682a6 1428 HASHMAP_FOREACH(vlan, link->network->vlans, i) {
52433f6b
TG
1429 log_struct_link(LOG_DEBUG, link,
1430 "MESSAGE=%s: enslaving by '%s'",
672682a6 1431 link->ifname, vlan->name, NETDEV(vlan), NULL);
52433f6b 1432
672682a6 1433 r = netdev_enslave(vlan, link, &enslave_handler);
52433f6b
TG
1434 if (r < 0) {
1435 log_struct_link(LOG_WARNING, link,
1436 "MESSAGE=%s: could not enslave by '%s': %s",
672682a6
TG
1437 link->ifname, vlan->name, strerror(-r),
1438 NETDEV(vlan), NULL);
52433f6b
TG
1439 link_enter_failed(link);
1440 return r;
1441 }
1442
1443 link->enslaving ++;
ef1ba606
TG
1444 }
1445
fe6b2d55
TG
1446 HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1447 log_struct_link(LOG_DEBUG, link,
1448 "MESSAGE=%s: enslaving by '%s'",
1449 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1450
1451 r = netdev_enslave(macvlan, link, &enslave_handler);
1452 if (r < 0) {
1453 log_struct_link(LOG_WARNING, link,
1454 "MESSAGE=%s: could not enslave by '%s': %s",
1455 link->ifname, macvlan->name, strerror(-r),
1456 NETDEV(macvlan), NULL);
1457 link_enter_failed(link);
1458 return r;
1459 }
1460
1461 link->enslaving ++;
1462 }
1463
ef1ba606
TG
1464 return 0;
1465}
1466
a748b692 1467static int link_configure(Link *link) {
02b59d57
TG
1468 int r;
1469
ef1ba606 1470 assert(link);
505f8da7 1471 assert(link->state == LINK_STATE_INITIALIZING);
a748b692 1472
eb34d4af 1473 if (link->network->ipv4ll) {
b5db00e5 1474 uint8_t seed[8];
45ad2c13 1475
eb34d4af
TG
1476 r = sd_ipv4ll_new(&link->ipv4ll);
1477 if (r < 0)
1478 return r;
1479
505f8da7
TG
1480 if (link->udev_device) {
1481 r = net_get_unique_predictable_data(link->udev_device, seed);
1482 if (r >= 0) {
1483 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1484 if (r < 0)
1485 return r;
1486 }
b5db00e5
UTL
1487 }
1488
eb34d4af
TG
1489 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1490 if (r < 0)
1491 return r;
1492
4bb40e81
TG
1493 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1494 if (r < 0)
1495 return r;
1496
eb34d4af
TG
1497 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1498 if (r < 0)
1499 return r;
1500
1501 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1502 if (r < 0)
1503 return r;
1504 }
1505
1506 if (link->network->dhcp) {
1507 r = sd_dhcp_client_new(&link->dhcp_client);
1508 if (r < 0)
1509 return r;
1510
1511 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1512 if (r < 0)
1513 return r;
1514
4bb40e81
TG
1515 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1516 if (r < 0)
1517 return r;
1518
eb34d4af
TG
1519 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1520 if (r < 0)
1521 return r;
1522
1523 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1524 if (r < 0)
1525 return r;
1526
1527 if (link->network->dhcp_mtu) {
1528 r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1529 if (r < 0)
1530 return r;
1531 }
1532 }
1533
deb2e523 1534 if (link_has_carrier(link->flags, link->operstate)) {
1e9be60b
TG
1535 r = link_acquire_conf(link);
1536 if (r < 0)
1537 return r;
cc544d5f 1538 }
1e9be60b 1539
505f8da7
TG
1540 return link_enter_enslave(link);
1541}
1542
1543int link_initialized(Link *link, struct udev_device *device) {
1544 Network *network;
505f8da7
TG
1545 int r;
1546
1547 assert(link);
1548 assert(link->ifname);
1549 assert(link->manager);
1550
1551 if (link->state != LINK_STATE_INITIALIZING)
1552 return 0;
1553
1554 if (device)
1555 link->udev_device = udev_device_ref(device);
1556
1557 log_debug_link(link, "link initialized");
1558
1559 r = network_get(link->manager, device, link->ifname, &link->mac, &network);
57bd6899
TG
1560 if (r == -ENOENT) {
1561 link_enter_unmanaged(link);
1562 return 0;
1563 } else if (r < 0)
1564 return r;
505f8da7
TG
1565
1566 r = network_apply(link->manager, network, link);
1567 if (r < 0)
1568 return r;
1569
a748b692
TG
1570 r = link_configure(link);
1571 if (r < 0)
1572 return r;
1573
505f8da7
TG
1574 return 0;
1575}
1576
1577int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1578 Link *link;
1579 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1580 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1581 int r;
1582
1583 assert(m);
1584 assert(message);
1585 assert(ret);
1586
1587 r = link_new(m, message, ret);
1588 if (r < 0)
1589 return r;
1590
1591 link = *ret;
1592
df9aa406 1593 log_debug_link(link, "link added");
505f8da7
TG
1594
1595 if (detect_container(NULL) <= 0) {
1596 /* not in a container, udev will be around */
1597 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
1598 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1599 if (!device) {
1600 log_warning_link(link, "could not find udev device");
1601 return -errno;
1602 }
1603
1604 if (udev_device_get_is_initialized(device) <= 0)
1605 /* not yet ready */
1606 return 0;
1607 }
1608
1609 r = link_initialized(link, device);
1610 if (r < 0)
1611 return r;
1612
a748b692
TG
1613 return 0;
1614}
1615
22936833 1616int link_update(Link *link, sd_rtnl_message *m) {
c49b33ac 1617 struct ether_addr mac;
b8941f74 1618 char *ifname;
22936833
TG
1619 int r;
1620
dd3efc09 1621 assert(link);
b8941f74 1622 assert(link->ifname);
22936833
TG
1623 assert(m);
1624
b8941f74
TG
1625 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1626 if (r >= 0 && !streq(ifname, link->ifname)) {
1627 log_info_link(link, "renamed to %s", ifname);
1628
1629 free(link->ifname);
1630 link->ifname = strdup(ifname);
1631 if (!link->ifname)
1632 return -ENOMEM;
1633 }
1634
505f8da7 1635 if (!link->original_mtu) {
9842de0d
TG
1636 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1637 if (r >= 0)
1638 log_debug_link(link, "saved original MTU: %"
1639 PRIu16, link->original_mtu);
1640 }
69629de9 1641
e9189a1f
TG
1642 /* The kernel may broadcast NEWLINK messages without the MAC address
1643 set, simply ignore them. */
c49b33ac 1644 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 1645 if (r >= 0) {
20861203 1646 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
c49b33ac 1647
20861203 1648 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
c49b33ac 1649
20861203
TG
1650 log_debug_link(link, "MAC address: "
1651 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1652 mac.ether_addr_octet[0],
1653 mac.ether_addr_octet[1],
1654 mac.ether_addr_octet[2],
1655 mac.ether_addr_octet[3],
1656 mac.ether_addr_octet[4],
1657 mac.ether_addr_octet[5]);
c49b33ac 1658
20861203
TG
1659 if (link->ipv4ll) {
1660 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1661 if (r < 0) {
1662 log_warning_link(link, "Could not update MAC "
1663 "address in IPv4LL client: %s",
1664 strerror(-r));
1665 return r;
1666 }
c49b33ac 1667 }
c49b33ac 1668
20861203
TG
1669 if (link->dhcp_client) {
1670 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1671 if (r < 0) {
1672 log_warning_link(link, "Could not update MAC "
1673 "address in DHCP client: %s",
1674 strerror(-r));
1675 return r;
1676 }
c49b33ac
TG
1677 }
1678 }
4f882b2a
TG
1679 }
1680
1e9be60b 1681 return link_update_flags(link, m);
dd3efc09 1682}
fe8db0c5
TG
1683
1684int link_save(Link *link) {
deb2e523 1685 _cleanup_free_ char *temp_path = NULL, *lease_file = NULL;
fe8db0c5 1686 _cleanup_fclose_ FILE *f = NULL;
deb2e523 1687 const char *admin_state, *oper_state = "unknown";
fe8db0c5
TG
1688 int r;
1689
1690 assert(link);
1691 assert(link->state_file);
bbf7c048
TG
1692 assert(link->manager);
1693
1694 r = manager_save(link->manager);
1695 if (r < 0)
1696 return r;
fe8db0c5 1697
deb2e523
TG
1698 admin_state = link_state_to_string(link->state);
1699 assert(admin_state);
1700
75adc218 1701 if (link->operstate == IF_OPER_DORMANT)
deb2e523
TG
1702 oper_state = "dormant";
1703 else if (link_has_carrier(link->flags, link->operstate))
1704 oper_state = "carrier";
1705
1706 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1707 link->ifindex);
1708 if (r < 0)
1709 return -ENOMEM;
7ff8f4b5 1710
fe8db0c5
TG
1711 r = fopen_temporary(link->state_file, &f, &temp_path);
1712 if (r < 0)
1713 goto finish;
1714
1715 fchmod(fileno(f), 0644);
1716
1717 fprintf(f,
1718 "# This is private data. Do not parse.\n"
deb2e523
TG
1719 "ADMIN_STATE=%s\n"
1720 "OPER_STATE=%s\n"
1721 "FLAGS=%u\n",
1722 admin_state, oper_state, link->flags);
fe8db0c5
TG
1723
1724 if (link->dhcp_lease) {
fe8db0c5
TG
1725 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1726 if (r < 0)
1727 goto finish;
1728
1729 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
deb2e523
TG
1730 } else
1731 unlink(lease_file);
fe8db0c5
TG
1732
1733 fflush(f);
1734
1735 if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1736 r = -errno;
1737 unlink(link->state_file);
1738 unlink(temp_path);
1739 }
1740
1741finish:
1742 if (r < 0)
bbf7c048 1743 log_error("Failed to save link data to %s: %s", link->state_file, strerror(-r));
fe8db0c5
TG
1744
1745 return r;
1746}
1747
1748static const char* const link_state_table[_LINK_STATE_MAX] = {
deb2e523 1749 [LINK_STATE_INITIALIZING] = "initializing",
fe8db0c5
TG
1750 [LINK_STATE_ENSLAVING] = "configuring",
1751 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1752 [LINK_STATE_SETTING_ROUTES] = "configuring",
1753 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 1754 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5
TG
1755 [LINK_STATE_FAILED] = "failed",
1756};
1757
1758DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);