]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
build: don't install busname units and target if kdbus support is disabled
[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>
4cc7a82c 24#include <unistd.h>
f579559b 25
0b1831c2 26#include "networkd-link.h"
3be1d7e0 27#include "networkd-netdev.h"
f579559b 28#include "libudev-private.h"
505f8da7 29#include "udev-util.h"
f579559b 30#include "util.h"
505f8da7 31#include "virt.h"
1346b1f0 32#include "bus-util.h"
c6f7c917 33#include "network-internal.h"
ed942a9e 34#include "conf-parser.h"
f579559b 35
fe8db0c5
TG
36#include "dhcp-lease-internal.h"
37
51d18171
TG
38#define FLAG_STRING(string, flag, old, new) \
39 (((old ^ new) & flag) \
40 ? ((old & flag) ? (" -" string) : (" +" string)) \
41 : "")
42
43static int link_update_flags(Link *link, sd_rtnl_message *m) {
44 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
45 uint8_t operstate;
46 int r;
47
48 assert(link);
49
50 r = sd_rtnl_message_link_get_flags(m, &flags);
51 if (r < 0) {
52 log_warning_link(link, "Could not get link flags");
53 return r;
54 }
55
56 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
57 if (r < 0)
58 /* if we got a message without operstate, take it to mean
59 the state was unchanged */
60 operstate = link->kernel_operstate;
61
62 if ((link->flags == flags) && (link->kernel_operstate == operstate))
63 return 0;
64
65 if (link->flags != flags) {
66 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
67 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
68 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
69 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
70 FLAG_STRING("UP", IFF_UP, link->flags, flags),
71 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
72 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
73 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
74 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
75 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
76 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
77 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
78 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
79 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
80 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
81 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
82 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
83 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
84 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
85 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
86
87 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
88 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
89 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
90 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
91 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
92 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
93 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
94 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
95
96 /* link flags are currently at most 18 bits, let's align to
97 * printing 20 */
98 if (unknown_flags_added)
99 log_debug_link(link,
100 "unknown link flags gained: %#.5x (ignoring)",
101 unknown_flags_added);
102
103 if (unknown_flags_removed)
104 log_debug_link(link,
105 "unknown link flags lost: %#.5x (ignoring)",
106 unknown_flags_removed);
107 }
108
109 link->flags = flags;
110 link->kernel_operstate = operstate;
111
112 link_save(link);
113
114 return 0;
115}
116
505f8da7 117static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
14b746f7 118 _cleanup_link_unref_ Link *link = NULL;
505f8da7 119 uint16_t type;
ca4e095a 120 const char *ifname;
505f8da7 121 int r, ifindex;
f579559b 122
0c2f9b84 123 assert(manager);
505f8da7 124 assert(message);
f579559b
TG
125 assert(ret);
126
505f8da7
TG
127 r = sd_rtnl_message_get_type(message, &type);
128 if (r < 0)
129 return r;
130 else if (type != RTM_NEWLINK)
131 return -EINVAL;
132
133 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
134 if (r < 0)
135 return r;
136 else if (ifindex <= 0)
137 return -EINVAL;
138
139 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
140 if (r < 0)
141 return r;
142
f579559b
TG
143 link = new0(Link, 1);
144 if (!link)
145 return -ENOMEM;
146
14b746f7 147 link->n_ref = 1;
5a3eb5a7 148 link->manager = manager;
8434fd5c 149 link->state = LINK_STATE_PENDING;
505f8da7
TG
150 link->ifindex = ifindex;
151 link->ifname = strdup(ifname);
152 if (!link->ifname)
153 return -ENOMEM;
f579559b 154
512922f8
TG
155 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
156 if (r < 0)
1a941ac4 157 log_debug_link(link, "MAC address not found for new device, continuing without");
512922f8 158
3c9b8860
TG
159 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
160 link->ifindex);
fe8db0c5 161 if (r < 0)
315db1a8 162 return -ENOMEM;
fe8db0c5 163
3c9b8860
TG
164 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
165 link->ifindex);
68a8723c
TG
166 if (r < 0)
167 return -ENOMEM;
168
ae06ab10
TG
169 r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
170 if (r < 0)
171 return r;
172
173 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
f579559b
TG
174 if (r < 0)
175 return r;
176
51d18171
TG
177 r = link_update_flags(link, message);
178 if (r < 0)
179 return r;
180
f579559b
TG
181 *ret = link;
182 link = NULL;
183
184 return 0;
185}
186
14b746f7 187static void link_free(Link *link) {
428fd0a7
TG
188 Address *address;
189
f579559b
TG
190 if (!link)
191 return;
192
428fd0a7
TG
193 while ((address = link->addresses)) {
194 LIST_REMOVE(addresses, link->addresses, address);
195 address_free(address);
196 }
197
11bf3cce
LP
198 while ((address = link->pool_addresses)) {
199 LIST_REMOVE(addresses, link->pool_addresses, address);
200 address_free(address);
201 }
202
e5b04c8d 203 sd_dhcp_client_unref(link->dhcp_client);
a6cc569e 204 sd_dhcp_lease_unref(link->dhcp_lease);
f5be5601 205
68a8723c
TG
206 unlink(link->lease_file);
207 free(link->lease_file);
208
56cd007a 209 sd_ipv4ll_unref(link->ipv4ll);
4138fb2c 210 sd_dhcp6_client_unref(link->dhcp6_client);
6b66097b 211 sd_icmp6_nd_unref(link->icmp6_router_discovery);
4138fb2c 212
28aeb07f 213 if (link->manager)
ae06ab10 214 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
f579559b 215
c166a070 216 free(link->ifname);
68a8723c
TG
217
218 unlink(link->state_file);
fe8db0c5 219 free(link->state_file);
c166a070 220
b5db00e5
UTL
221 udev_device_unref(link->udev_device);
222
f579559b
TG
223 free(link);
224}
225
14b746f7
TG
226Link *link_unref(Link *link) {
227 if (link && (-- link->n_ref <= 0))
228 link_free(link);
229
230 return NULL;
231}
232
233Link *link_ref(Link *link) {
234 if (link)
235 assert_se(++ link->n_ref >= 2);
236
237 return link;
238}
239
11a7f229
TG
240int link_get(Manager *m, int ifindex, Link **ret) {
241 Link *link;
11a7f229
TG
242
243 assert(m);
11a7f229
TG
244 assert(ifindex);
245 assert(ret);
246
ae06ab10 247 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
11a7f229
TG
248 if (!link)
249 return -ENODEV;
250
251 *ret = link;
252
253 return 0;
254}
255
370e9930
TG
256void link_drop(Link *link) {
257 if (!link || link->state == LINK_STATE_LINGER)
258 return;
259
260 link->state = LINK_STATE_LINGER;
261
7619683b 262 log_debug_link(link, "link removed");
370e9930
TG
263
264 link_unref(link);
265
266 return;
267}
268
57bd6899
TG
269static void link_enter_unmanaged(Link *link) {
270 assert(link);
271
df9aa406 272 log_debug_link(link, "unmanaged");
57bd6899
TG
273
274 link->state = LINK_STATE_UNMANAGED;
275
276 link_save(link);
277}
278
111bb8f9
TG
279static int link_stop_clients(Link *link) {
280 int r = 0, k;
281
282 assert(link);
283 assert(link->manager);
284 assert(link->manager->event);
285
286 if (!link->network)
287 return 0;
288
ba179154 289 if (link->dhcp_client) {
111bb8f9
TG
290 k = sd_dhcp_client_stop(link->dhcp_client);
291 if (k < 0) {
3c9b8860
TG
292 log_warning_link(link, "Could not stop DHCPv4 client: %s",
293 strerror(-r));
111bb8f9
TG
294 r = k;
295 }
296 }
297
ba179154 298 if (link->ipv4ll) {
111bb8f9
TG
299 k = sd_ipv4ll_stop(link->ipv4ll);
300 if (k < 0) {
3c9b8860
TG
301 log_warning_link(link, "Could not stop IPv4 link-local: %s",
302 strerror(-r));
111bb8f9
TG
303 r = k;
304 }
305 }
306
ba179154 307 if (link->dhcp_server) {
dd43110f
TG
308 k = sd_dhcp_server_stop(link->dhcp_server);
309 if (k < 0) {
3c9b8860
TG
310 log_warning_link(link, "Could not stop DHCPv4 server: %s",
311 strerror(-r));
dd43110f
TG
312 r = k;
313 }
314 }
315
ba179154 316 if(link->icmp6_router_discovery) {
1873a3d3
PF
317
318 if (link->dhcp6_client) {
319 k = sd_dhcp6_client_stop(link->dhcp6_client);
320 if (k < 0) {
3c9b8860
TG
321 log_warning_link(link, "Could not stop DHCPv6 client: %s",
322 strerror(-r));
1873a3d3
PF
323 r = k;
324 }
325 }
4138fb2c 326
1873a3d3 327 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
4138fb2c 328 if (k < 0) {
3c9b8860
TG
329 log_warning_link(link,
330 "Could not stop ICMPv6 router discovery: %s",
331 strerror(-r));
4138fb2c
PF
332 r = k;
333 }
334 }
335
111bb8f9
TG
336 return r;
337}
338
b22d8a00 339void link_enter_failed(Link *link) {
ef1ba606 340 assert(link);
f882c247 341
370e9930 342 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2139694e
TG
343 return;
344
39032b87 345 log_warning_link(link, "failed");
449f7554 346
ef1ba606 347 link->state = LINK_STATE_FAILED;
fe8db0c5 348
111bb8f9
TG
349 link_stop_clients(link);
350
fe8db0c5 351 link_save(link);
f882c247
TG
352}
353
4f434938
LP
354static Address* link_find_dhcp_server_address(Link *link) {
355 Address *address;
356
357 assert(link);
358 assert(link->network);
359
360 /* The the first statically configured address if there is any */
361 LIST_FOREACH(addresses, address, link->network->static_addresses) {
362
363 if (address->family != AF_INET)
364 continue;
365
af93291c 366 if (in_addr_is_null(address->family, &address->in_addr))
4f434938
LP
367 continue;
368
369 return address;
370 }
371
372 /* If that didn't work, find a suitable address we got from the pool */
373 LIST_FOREACH(addresses, address, link->pool_addresses) {
374 if (address->family != AF_INET)
375 continue;
376
377 return address;
378 }
379
380 return NULL;
381}
382
dd43110f
TG
383static int link_enter_configured(Link *link) {
384 int r;
385
386 assert(link);
387 assert(link->network);
388 assert(link->state == LINK_STATE_SETTING_ROUTES);
389
7c16313f
TG
390 if (link->network->dhcp_server &&
391 !sd_dhcp_server_is_running(link->dhcp_server)) {
4f434938
LP
392 struct in_addr pool_start;
393 Address *address;
394
395 address = link_find_dhcp_server_address(link);
396 if (!address) {
3c9b8860
TG
397 log_warning_link(link,
398 "Failed to find suitable address for DHCPv4 server instance.");
4f434938
LP
399 link_enter_failed(link);
400 return 0;
401 }
402
dd43110f
TG
403 log_debug_link(link, "offering DHCPv4 leases");
404
3c9b8860
TG
405 r = sd_dhcp_server_set_address(link->dhcp_server,
406 &address->in_addr.in,
407 address->prefixlen);
4f434938
LP
408 if (r < 0)
409 return r;
410
411 /* offer 32 addresses starting from the address following the server address */
412 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
413 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
414 &pool_start, 32);
415 if (r < 0)
416 return r;
417
418 /* TODO:
419 r = sd_dhcp_server_set_router(link->dhcp_server,
420 &main_address->in_addr.in);
421 if (r < 0)
422 return r;
423
424 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
425 main_address->prefixlen);
426 if (r < 0)
427 return r;
428 */
429
dd43110f
TG
430 r = sd_dhcp_server_start(link->dhcp_server);
431 if (r < 0) {
432 log_warning_link(link, "could not start DHCPv4 server "
433 "instance: %s", strerror(-r));
434
435 link_enter_failed(link);
436
437 return 0;
438 }
439 }
440
441 log_info_link(link, "link configured");
442
443 link->state = LINK_STATE_CONFIGURED;
444
445 link_save(link);
446
447 return 0;
448}
449
3c9b8860
TG
450void link_client_handler(Link *link) {
451 assert(link);
452 assert(link->network);
453
454 if (!link->static_configured)
455 return;
456
457 if (link->network->ipv4ll)
458 if (!link->ipv4ll_address ||
459 !link->ipv4ll_route)
460 return;
461
462 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4))
463 if (!link->dhcp4_configured)
464 return;
465
9fdaa992
TG
466 if (link->state != LINK_STATE_CONFIGURED)
467 link_enter_configured(link);
3c9b8860
TG
468
469 return;
470}
471
f882c247 472static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 473 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
474 int r;
475
3c9b8860 476 assert(link->link_messages > 0);
370e9930
TG
477 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
478 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
479 LINK_STATE_LINGER));
f882c247 480
3c9b8860 481 link->link_messages --;
f882c247 482
77a008c0 483 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
484 return 1;
485
486 r = sd_rtnl_message_get_errno(m);
c166a070 487 if (r < 0 && r != -EEXIST)
c9ccc19f 488 log_struct_link(LOG_WARNING, link,
97578344 489 "MESSAGE=%-*s: could not set route: %s",
987efa17 490 IFNAMSIZ,
c9ccc19f
TG
491 link->ifname, strerror(-r),
492 "ERRNO=%d", -r,
493 NULL);
f882c247 494
3c9b8860 495 if (link->link_messages == 0) {
39032b87 496 log_debug_link(link, "routes set");
3c9b8860
TG
497 link->static_configured = true;
498 link_client_handler(link);
dd3efc09 499 }
f882c247
TG
500
501 return 1;
502}
503
504static int link_enter_set_routes(Link *link) {
a6cc569e 505 Route *rt;
f882c247
TG
506 int r;
507
508 assert(link);
509 assert(link->network);
ef1ba606 510 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 511
ef1ba606 512 link->state = LINK_STATE_SETTING_ROUTES;
f882c247 513
3d3d4255 514 LIST_FOREACH(routes, rt, link->network->static_routes) {
a6cc569e 515 r = route_configure(rt, link, &route_handler);
dd3efc09 516 if (r < 0) {
3333d748 517 log_warning_link(link,
3c9b8860 518 "could not set routes: %s",
b1666580 519 strerror(-r));
3c9b8860 520 link_enter_failed(link);
a6cc569e
TG
521 return r;
522 }
523
3c9b8860 524 link->link_messages ++;
8ddbeaa2 525 }
f5be5601 526
3c9b8860
TG
527 if (link->link_messages == 0) {
528 link->static_configured = true;
529 link_client_handler(link);
431ca2ce
TG
530 } else
531 log_debug_link(link, "setting routes");
f882c247
TG
532
533 return 0;
534}
535
b22d8a00 536int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 537 _cleanup_link_unref_ Link *link = userdata;
5c1d3fc9
UTL
538 int r;
539
540 assert(m);
541 assert(link);
542 assert(link->ifname);
543
5da8149f 544 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
5c1d3fc9
UTL
545 return 1;
546
547 r = sd_rtnl_message_get_errno(m);
b90b025a 548 if (r < 0 && r != -ESRCH)
5c1d3fc9 549 log_struct_link(LOG_WARNING, link,
97578344 550 "MESSAGE=%-*s: could not drop route: %s",
987efa17 551 IFNAMSIZ,
5c1d3fc9
UTL
552 link->ifname, strerror(-r),
553 "ERRNO=%d", -r,
554 NULL);
555
5bdd314c 556 return 1;
5c1d3fc9
UTL
557}
558
b22d8a00 559int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
4958aee4
TG
560 _cleanup_link_unref_ Link *link = userdata;
561 int r;
562
563 assert(rtnl);
564 assert(m);
565 assert(link);
566 assert(link->manager);
567
568 for (; m; m = sd_rtnl_message_next(m)) {
569 r = sd_rtnl_message_get_errno(m);
570 if (r < 0) {
3c9b8860
TG
571 log_debug_link(link, "getting address failed: %s",
572 strerror(-r));
4958aee4
TG
573 continue;
574 }
575
576 r = link_rtnl_process_address(rtnl, m, link->manager);
577 if (r < 0)
3c9b8860
TG
578 log_warning_link(link, "could not process address: %s",
579 strerror(-r));
4958aee4
TG
580 }
581
582 return 1;
583}
584
f882c247 585static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 586 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
587 int r;
588
4958aee4 589 assert(rtnl);
f5be5601
TG
590 assert(m);
591 assert(link);
592 assert(link->ifname);
3c9b8860 593 assert(link->link_messages > 0);
370e9930
TG
594 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
595 LINK_STATE_FAILED, LINK_STATE_LINGER));
f882c247 596
3c9b8860 597 link->link_messages --;
f882c247 598
5da8149f 599 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
600 return 1;
601
602 r = sd_rtnl_message_get_errno(m);
c166a070 603 if (r < 0 && r != -EEXIST)
c9ccc19f 604 log_struct_link(LOG_WARNING, link,
97578344 605 "MESSAGE=%-*s: could not set address: %s",
987efa17 606 IFNAMSIZ,
3333d748
ZJS
607 link->ifname, strerror(-r),
608 "ERRNO=%d", -r,
609 NULL);
5bdd314c 610 else if (r >= 0) {
4958aee4
TG
611 /* calling handler directly so take a ref */
612 link_ref(link);
613 link_get_address_handler(rtnl, m, link);
614 }
f882c247 615
3c9b8860 616 if (link->link_messages == 0) {
39032b87 617 log_debug_link(link, "addresses set");
ef1ba606 618 link_enter_set_routes(link);
dd3efc09 619 }
f882c247
TG
620
621 return 1;
622}
623
624static int link_enter_set_addresses(Link *link) {
a6cc569e 625 Address *ad;
f882c247
TG
626 int r;
627
628 assert(link);
629 assert(link->network);
f5be5601 630 assert(link->state != _LINK_STATE_INVALID);
f882c247 631
ef1ba606 632 link->state = LINK_STATE_SETTING_ADDRESSES;
f882c247 633
3d3d4255 634 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
a6cc569e 635 r = address_configure(ad, link, &address_handler);
dd3efc09 636 if (r < 0) {
3333d748 637 log_warning_link(link,
3c9b8860 638 "could not set addresses: %s",
a6cc569e 639 strerror(-r));
f5be5601
TG
640 link_enter_failed(link);
641 return r;
642 }
643
3c9b8860 644 link->link_messages ++;
f882c247
TG
645 }
646
3c9b8860 647 if (link->link_messages == 0) {
431ca2ce
TG
648 link_enter_set_routes(link);
649 } else
650 log_debug_link(link, "setting addresses");
651
f882c247
TG
652 return 0;
653}
654
b22d8a00 655int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 656 _cleanup_link_unref_ Link *link = userdata;
ff254138
TG
657 int r;
658
659 assert(m);
660 assert(link);
661 assert(link->ifname);
662
5da8149f 663 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ff254138
TG
664 return 1;
665
666 r = sd_rtnl_message_get_errno(m);
b90b025a 667 if (r < 0 && r != -EADDRNOTAVAIL)
c9ccc19f 668 log_struct_link(LOG_WARNING, link,
97578344 669 "MESSAGE=%-*s: could not drop address: %s",
987efa17 670 IFNAMSIZ,
c9ccc19f
TG
671 link->ifname, strerror(-r),
672 "ERRNO=%d", -r,
673 NULL);
ff254138 674
5bdd314c 675 return 1;
ff254138
TG
676}
677
3c9b8860
TG
678static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
679 sd_bus_error *ret_error) {
5da8149f 680 _cleanup_link_unref_ Link *link = userdata;
1346b1f0
TG
681 int r;
682
b226d99b
TG
683 assert(link);
684
5da8149f 685 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
370e9930 686 return 1;
370e9930 687
1346b1f0
TG
688 r = sd_bus_message_get_errno(m);
689 if (r < 0)
70b34f5d
MM
690 r = -r;
691 if (r > 0)
3c9b8860
TG
692 log_warning_link(link, "Could not set hostname: %s",
693 strerror(r));
1346b1f0
TG
694
695 return 1;
696}
697
3c9b8860 698int link_set_hostname(Link *link, const char *hostname) {
1346b1f0
TG
699 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
700 int r = 0;
701
b226d99b
TG
702 assert(link);
703 assert(link->manager);
1346b1f0
TG
704 assert(hostname);
705
b226d99b 706 log_debug_link(link, "Setting transient hostname: '%s'", hostname);
1346b1f0 707
3c9b8860
TG
708 if (!link->manager->bus) {
709 /* TODO: replace by assert when we can rely on kdbus */
710 log_info_link(link,
711 "Not connected to system bus, ignoring transient hostname.");
bcbca829
TG
712 return 0;
713 }
714
1346b1f0 715 r = sd_bus_message_new_method_call(
b226d99b 716 link->manager->bus,
151b9b96 717 &m,
1346b1f0
TG
718 "org.freedesktop.hostname1",
719 "/org/freedesktop/hostname1",
720 "org.freedesktop.hostname1",
151b9b96 721 "SetHostname");
1346b1f0
TG
722 if (r < 0)
723 return r;
724
725 r = sd_bus_message_append(m, "sb", hostname, false);
726 if (r < 0)
727 return r;
728
3c9b8860
TG
729 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
730 link, 0);
5da8149f 731 if (r < 0) {
3c9b8860
TG
732 log_error_link(link, "Could not set transient hostname: %s",
733 strerror(-r));
5da8149f
TG
734 return r;
735 }
b226d99b
TG
736
737 link_ref(link);
1346b1f0 738
5da8149f 739 return 0;
1346b1f0
TG
740}
741
4f882b2a 742static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 743 _cleanup_link_unref_ Link *link = userdata;
4f882b2a
TG
744 int r;
745
746 assert(m);
747 assert(link);
748 assert(link->ifname);
749
5da8149f 750 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
4f882b2a
TG
751 return 1;
752
753 r = sd_rtnl_message_get_errno(m);
c9ccc19f
TG
754 if (r < 0)
755 log_struct_link(LOG_WARNING, link,
97578344
TG
756 "MESSAGE=%-*s: could not set MTU: %s",
757 IFNAMSIZ, link->ifname, strerror(-r),
c9ccc19f
TG
758 "ERRNO=%d", -r,
759 NULL);
4f882b2a
TG
760
761 return 1;
762}
763
3c9b8860 764int link_set_mtu(Link *link, uint32_t mtu) {
cf6a8911 765 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
4f882b2a
TG
766 int r;
767
768 assert(link);
769 assert(link->manager);
770 assert(link->manager->rtnl);
771
772 log_debug_link(link, "setting MTU: %" PRIu32, mtu);
773
151b9b96
LP
774 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
775 RTM_SETLINK, link->ifindex);
4f882b2a
TG
776 if (r < 0) {
777 log_error_link(link, "Could not allocate RTM_SETLINK message");
778 return r;
779 }
780
781 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
782 if (r < 0) {
783 log_error_link(link, "Could not append MTU: %s", strerror(-r));
784 return r;
785 }
786
3c9b8860
TG
787 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
788 0, NULL);
4f882b2a
TG
789 if (r < 0) {
790 log_error_link(link,
3c9b8860
TG
791 "Could not send rtnetlink message: %s",
792 strerror(-r));
4f882b2a
TG
793 return r;
794 }
795
ae941762 796 link_ref(link);
b226d99b 797
4f882b2a
TG
798 return 0;
799}
800
4138fb2c
PF
801static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
802 Link *link = userdata;
803
804 assert(link);
805 assert(link->network);
806 assert(link->manager);
807
808 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
809 return;
810
811 switch(event) {
812 case DHCP6_EVENT_STOP:
813 case DHCP6_EVENT_RESEND_EXPIRE:
814 case DHCP6_EVENT_RETRANS_MAX:
815 case DHCP6_EVENT_IP_ACQUIRE:
816 log_debug_link(link, "DHCPv6 event %d", event);
817
818 break;
819
820 default:
821 if (event < 0)
822 log_warning_link(link, "DHCPv6 error: %s",
823 strerror(-event));
824 else
825 log_warning_link(link, "DHCPv6 unknown event: %d",
826 event);
827 return;
828 }
829}
830
831static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
832 Link *link = userdata;
833 int r;
834
835 assert(link);
836 assert(link->network);
837 assert(link->manager);
838
839 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
840 return;
841
842 switch(event) {
843 case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
844 case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
845 return;
846
847 case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
848 case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
849 break;
850
851 default:
852 if (event < 0)
853 log_warning_link(link, "ICMPv6 error: %s",
854 strerror(-event));
855 else
856 log_warning_link(link, "ICMPv6 unknown event: %d",
857 event);
858
859 return;
860 }
861
862 if (link->dhcp6_client)
863 return;
864
865 r = sd_dhcp6_client_new(&link->dhcp6_client);
866 if (r < 0)
867 return;
868
869 r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
870 if (r < 0) {
871 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
872 return;
873 }
874
875 r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
876 if (r < 0) {
877 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
878 return;
879 }
880
881 r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
882 if (r < 0) {
883 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
884 return;
885 }
886
887 r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
888 link);
889 if (r < 0) {
890 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
891 return;
892 }
893
894 r = sd_dhcp6_client_start(link->dhcp6_client);
895 if (r < 0)
896 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
897}
898
ff254138
TG
899static int link_acquire_conf(Link *link) {
900 int r;
901
902 assert(link);
903 assert(link->network);
ff254138
TG
904 assert(link->manager);
905 assert(link->manager->event);
906
5c1d3fc9 907 if (link->network->ipv4ll) {
eb34d4af 908 assert(link->ipv4ll);
ff254138 909
5c1d3fc9
UTL
910 log_debug_link(link, "acquiring IPv4 link-local address");
911
912 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6
TG
913 if (r < 0) {
914 log_warning_link(link, "could not acquire IPv4 "
915 "link-local address");
ff254138 916 return r;
124fa2c6 917 }
5c1d3fc9
UTL
918 }
919
ed942a9e 920 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
eb34d4af 921 assert(link->dhcp_client);
ff254138 922
5c1d3fc9 923 log_debug_link(link, "acquiring DHCPv4 lease");
ab47d620 924
5c1d3fc9 925 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6
TG
926 if (r < 0) {
927 log_warning_link(link, "could not acquire DHCPv4 "
928 "lease");
5c1d3fc9 929 return r;
124fa2c6 930 }
5c1d3fc9 931 }
ff254138 932
ed942a9e 933 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
4138fb2c
PF
934 assert(link->icmp6_router_discovery);
935
936 log_debug_link(link, "discovering IPv6 routers");
937
938 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
939 if (r < 0) {
3c9b8860
TG
940 log_warning_link(link,
941 "could not start IPv6 router discovery");
4138fb2c
PF
942 return r;
943 }
944 }
945
ff254138
TG
946 return 0;
947}
948
a61bb41c 949bool link_has_carrier(Link *link) {
deb2e523
TG
950 /* see Documentation/networking/operstates.txt in the kernel sources */
951
a61bb41c 952 if (link->kernel_operstate == IF_OPER_UP)
deb2e523
TG
953 return true;
954
a61bb41c 955 if (link->kernel_operstate == IF_OPER_UNKNOWN)
deb2e523 956 /* operstate may not be implemented, so fall back to flags */
a61bb41c 957 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
deb2e523
TG
958 return true;
959
960 return false;
961}
962
dd3efc09 963static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 964 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
965 int r;
966
1746cf2a
TG
967 assert(link);
968
5da8149f 969 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
970 return 1;
971
dd3efc09 972 r = sd_rtnl_message_get_errno(m);
45ad2c13 973 if (r < 0) {
9b86b393
TG
974 /* we warn but don't fail the link, as it may
975 be brought up later */
76800848 976 log_struct_link(LOG_WARNING, link,
97578344 977 "MESSAGE=%-*s: could not bring up interface: %s",
987efa17 978 IFNAMSIZ,
c9ccc19f
TG
979 link->ifname, strerror(-r),
980 "ERRNO=%d", -r,
981 NULL);
45ad2c13
TG
982 }
983
f882c247
TG
984 return 1;
985}
986
987static int link_up(Link *link) {
cf6a8911 988 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
989 int r;
990
f882c247
TG
991 assert(link);
992 assert(link->manager);
993 assert(link->manager->rtnl);
994
39032b87 995 log_debug_link(link, "bringing link up");
449f7554 996
151b9b96
LP
997 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
998 RTM_SETLINK, link->ifindex);
f579559b 999 if (r < 0) {
39032b87 1000 log_error_link(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1001 return r;
1002 }
1003
5d4795f3 1004 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1005 if (r < 0) {
3c9b8860
TG
1006 log_error_link(link, "Could not set link flags: %s",
1007 strerror(-r));
fc25d7f8
TG
1008 return r;
1009 }
1010
3c9b8860
TG
1011 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1012 0, NULL);
f579559b 1013 if (r < 0) {
3333d748 1014 log_error_link(link,
3c9b8860
TG
1015 "Could not send rtnetlink message: %s",
1016 strerror(-r));
f579559b
TG
1017 return r;
1018 }
1019
b226d99b
TG
1020 link_ref(link);
1021
f882c247
TG
1022 return 0;
1023}
1024
3f265037 1025static int link_joined(Link *link) {
f882c247
TG
1026 int r;
1027
ef1ba606 1028 assert(link);
f5be5601 1029 assert(link->network);
dd3efc09 1030
505f8da7
TG
1031 if (!(link->flags & IFF_UP)) {
1032 r = link_up(link);
1033 if (r < 0) {
1034 link_enter_failed(link);
1035 return r;
1036 }
ef1ba606 1037 }
f882c247 1038
fb6730c4 1039 return link_enter_set_addresses(link);
02b59d57
TG
1040}
1041
3c9b8860
TG
1042static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1043 void *userdata) {
5da8149f 1044 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1045 int r;
1046
1746cf2a 1047 assert(link);
ef1ba606 1048 assert(link->network);
02b59d57 1049
52433f6b
TG
1050 link->enslaving --;
1051
5da8149f 1052 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1053 return 1;
1054
1055 r = sd_rtnl_message_get_errno(m);
856f962c 1056 if (r < 0 && r != -EEXIST) {
c9ccc19f 1057 log_struct_link(LOG_ERR, link,
3f265037 1058 "MESSAGE=%-*s: could not join netdev: %s",
987efa17 1059 IFNAMSIZ,
c9ccc19f
TG
1060 link->ifname, strerror(-r),
1061 "ERRNO=%d", -r,
1062 NULL);
ef1ba606
TG
1063 link_enter_failed(link);
1064 return 1;
ba179154
TG
1065 } else
1066 log_debug_link(link, "joined netdev");
02b59d57 1067
856f962c 1068 if (link->enslaving <= 0)
3f265037 1069 link_joined(link);
02b59d57
TG
1070
1071 return 1;
1072}
1073
3f265037 1074static int link_enter_join_netdev(Link *link) {
6a0a2f86 1075 NetDev *netdev;
672682a6 1076 Iterator i;
02b59d57
TG
1077 int r;
1078
1079 assert(link);
1080 assert(link->network);
8434fd5c 1081 assert(link->state == LINK_STATE_PENDING);
02b59d57 1082
52433f6b 1083 link->state = LINK_STATE_ENSLAVING;
02b59d57 1084
fe8db0c5
TG
1085 link_save(link);
1086
7951dea2
SS
1087 if (!link->network->bridge &&
1088 !link->network->bond &&
6a0a2f86 1089 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1090 return link_joined(link);
02b59d57 1091
d9c67ea1 1092 if (link->network->bond) {
52433f6b 1093 log_struct_link(LOG_DEBUG, link,
97578344 1094 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1095 IFNAMSIZ,
af4e9e2c 1096 link->ifname, link->network->bond->ifname,
aa9f1140 1097 NETDEVIF(link->network->bond),
52433f6b 1098 NULL);
449f7554 1099
3f265037 1100 r = netdev_join(link->network->bond, link, &netdev_join_handler);
52433f6b
TG
1101 if (r < 0) {
1102 log_struct_link(LOG_WARNING, link,
3f265037 1103 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1104 IFNAMSIZ,
3c9b8860
TG
1105 link->ifname, link->network->bond->ifname,
1106 strerror(-r),
aa9f1140 1107 NETDEVIF(link->network->bond),
52433f6b
TG
1108 NULL);
1109 link_enter_failed(link);
1110 return r;
1111 }
1112
0ad6148e
MO
1113 link->enslaving ++;
1114 }
1115
d9c67ea1 1116 if (link->network->bridge) {
0ad6148e 1117 log_struct_link(LOG_DEBUG, link,
97578344 1118 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1119 IFNAMSIZ,
af4e9e2c 1120 link->ifname, link->network->bridge->ifname,
aa9f1140 1121 NETDEVIF(link->network->bridge),
0ad6148e
MO
1122 NULL);
1123
3c9b8860
TG
1124 r = netdev_join(link->network->bridge, link,
1125 &netdev_join_handler);
0ad6148e
MO
1126 if (r < 0) {
1127 log_struct_link(LOG_WARNING, link,
3f265037 1128 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1129 IFNAMSIZ,
3c9b8860
TG
1130 link->ifname, link->network->bridge->ifname,
1131 strerror(-r),
aa9f1140 1132 NETDEVIF(link->network->bridge),
0ad6148e
MO
1133 NULL);
1134 link_enter_failed(link);
1135 return r;
1136 }
1137
52433f6b
TG
1138 link->enslaving ++;
1139 }
1140
6a0a2f86 1141 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
7951dea2 1142 log_struct_link(LOG_DEBUG, link,
97578344 1143 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1144 IFNAMSIZ,
3c9b8860
TG
1145 link->ifname, netdev->ifname, NETDEVIF(netdev),
1146 NULL);
7951dea2 1147
6a0a2f86 1148 r = netdev_join(netdev, link, &netdev_join_handler);
7951dea2
SS
1149 if (r < 0) {
1150 log_struct_link(LOG_WARNING, link,
3f265037 1151 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1152 IFNAMSIZ,
3c9b8860
TG
1153 link->ifname, netdev->ifname,
1154 strerror(-r),
6a0a2f86 1155 NETDEVIF(netdev), NULL);
326cb406
SS
1156 link_enter_failed(link);
1157 return r;
1158 }
1159
326cb406
SS
1160 link->enslaving ++;
1161 }
1162
ef1ba606
TG
1163 return 0;
1164}
1165
a748b692 1166static int link_configure(Link *link) {
02b59d57
TG
1167 int r;
1168
ef1ba606 1169 assert(link);
b22d8a00 1170 assert(link->network);
8434fd5c 1171 assert(link->state == LINK_STATE_PENDING);
a748b692 1172
eb34d4af 1173 if (link->network->ipv4ll) {
b22d8a00 1174 r = ipv4ll_configure(link);
eb34d4af
TG
1175 if (r < 0)
1176 return r;
1177 }
1178
ed942a9e 1179 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
3c9b8860 1180 r = dhcp4_configure(link);
eb34d4af
TG
1181 if (r < 0)
1182 return r;
eb34d4af
TG
1183 }
1184
dd43110f 1185 if (link->network->dhcp_server) {
dd43110f
TG
1186 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1187 if (r < 0)
1188 return r;
1189
1190 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1191 if (r < 0)
1192 return r;
dd43110f
TG
1193 }
1194
ed942a9e 1195 if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
4138fb2c
PF
1196 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1197 if (r < 0)
1198 return r;
1199
1200 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1201 NULL, 0);
1202 if (r < 0)
1203 return r;
1204
1205 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1206 &link->mac);
1207 if (r < 0)
1208 return r;
1209
1210 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1211 link->ifindex);
1212 if (r < 0)
1213 return r;
1214
1215 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1216 icmp6_router_handler, link);
1217 if (r < 0)
1218 return r;
1219 }
1220
a61bb41c 1221 if (link_has_carrier(link)) {
1e9be60b
TG
1222 r = link_acquire_conf(link);
1223 if (r < 0)
1224 return r;
cc544d5f 1225 }
1e9be60b 1226
3f265037 1227 return link_enter_join_netdev(link);
505f8da7
TG
1228}
1229
3c9b8860
TG
1230static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1231 void *userdata) {
5da8149f 1232 _cleanup_link_unref_ Link *link = userdata;
505f8da7 1233 Network *network;
505f8da7
TG
1234 int r;
1235
1236 assert(link);
1237 assert(link->ifname);
1238 assert(link->manager);
1239
8434fd5c 1240 if (link->state != LINK_STATE_PENDING)
5da8149f 1241 return 1;
505f8da7 1242
4f561e8e 1243 log_debug_link(link, "link state is up-to-date");
505f8da7 1244
3c9b8860
TG
1245 r = network_get(link->manager, link->udev_device, link->ifname,
1246 &link->mac, &network);
57bd6899
TG
1247 if (r == -ENOENT) {
1248 link_enter_unmanaged(link);
5da8149f 1249 return 1;
57bd6899
TG
1250 } else if (r < 0)
1251 return r;
505f8da7 1252
bd2efe92
TG
1253 if (link->flags & IFF_LOOPBACK) {
1254 log_debug_link(link, "matching network ignored for loopback link");
1255 link_enter_unmanaged(link);
1256 return 1;
1257 }
1258
505f8da7
TG
1259 r = network_apply(link->manager, network, link);
1260 if (r < 0)
1261 return r;
1262
a748b692
TG
1263 r = link_configure(link);
1264 if (r < 0)
1265 return r;
1266
5da8149f 1267 return 1;
505f8da7
TG
1268}
1269
4f561e8e
TG
1270int link_initialized(Link *link, struct udev_device *device) {
1271 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1272 int r;
1273
1274 assert(link);
1275 assert(link->manager);
1276 assert(link->manager->rtnl);
1277 assert(device);
1278
8434fd5c 1279 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
1280 return 0;
1281
679b3605
TG
1282 if (link->udev_device)
1283 return 0;
1284
4f561e8e
TG
1285 log_debug_link(link, "udev initialized link");
1286
1287 link->udev_device = udev_device_ref(device);
1288
3c9b8860
TG
1289 /* udev has initialized the link, but we don't know if we have yet
1290 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1291 * when it returns we know that the pending NEWLINKs have already been
1292 * processed and that we are up-to-date */
4f561e8e 1293
3c9b8860
TG
1294 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1295 link->ifindex);
4f561e8e
TG
1296 if (r < 0)
1297 return r;
1298
3c9b8860
TG
1299 r = sd_rtnl_call_async(link->manager->rtnl, req,
1300 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
1301 if (r < 0)
1302 return r;
1303
5da8149f
TG
1304 link_ref(link);
1305
4f561e8e
TG
1306 return 0;
1307}
1308
3c9b8860
TG
1309int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
1310 void *userdata) {
fbbeb65a
TG
1311 Manager *m = userdata;
1312 Link *link = NULL;
1313 uint16_t type;
1314 _cleanup_address_free_ Address *address = NULL;
428fd0a7 1315 Address *ad;
fbbeb65a 1316 char buf[INET6_ADDRSTRLEN];
c6d3b303
TG
1317 char valid_buf[FORMAT_TIMESPAN_MAX];
1318 const char *valid_str = NULL;
428fd0a7 1319 bool address_dropped = false;
fbbeb65a
TG
1320 int r, ifindex;
1321
1322 assert(rtnl);
1323 assert(message);
1324 assert(m);
1325
1326 r = sd_rtnl_message_get_type(message, &type);
1327 if (r < 0) {
1328 log_warning("rtnl: could not get message type");
1329 return 0;
1330 }
1331
1332 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1333 if (r < 0 || ifindex <= 0) {
5ea846cc 1334 log_warning("rtnl: received address message without valid ifindex, ignoring");
fbbeb65a
TG
1335 return 0;
1336 } else {
1337 r = link_get(m, ifindex, &link);
1338 if (r < 0 || !link) {
a821cbb0 1339 log_warning("rtnl: received address for a nonexistent link (%d), ignoring", ifindex);
fbbeb65a
TG
1340 return 0;
1341 }
1342 }
1343
1344 r = address_new_dynamic(&address);
1345 if (r < 0)
393c0c5e 1346 return r;
fbbeb65a
TG
1347
1348 r = sd_rtnl_message_addr_get_family(message, &address->family);
1349 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
3c9b8860
TG
1350 log_warning_link(link,
1351 "rtnl: received address with invalid family, ignoring");
fbbeb65a
TG
1352 return 0;
1353 }
1354
1355 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1356 if (r < 0) {
3c9b8860
TG
1357 log_warning_link(link,
1358 "rtnl: received address with invalid prefixlen, ignoring");
e375dcde
TG
1359 return 0;
1360 }
1361
1362 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1363 if (r < 0) {
3c9b8860
TG
1364 log_warning_link(link,
1365 "rtnl: received address with invalid scope, ignoring");
fbbeb65a
TG
1366 return 0;
1367 }
1368
81163121
TG
1369 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1370 if (r < 0) {
1371 log_warning_link(link,
1372 "rtnl: received address with invalid flags, ignoring");
1373 return 0;
1374 }
1375
fbbeb65a
TG
1376 switch (address->family) {
1377 case AF_INET:
3c9b8860
TG
1378 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1379 &address->in_addr.in);
fbbeb65a 1380 if (r < 0) {
3c9b8860
TG
1381 log_warning_link(link,
1382 "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1383 return 0;
1384 }
1385
1386 break;
1387
1388 case AF_INET6:
3c9b8860
TG
1389 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1390 &address->in_addr.in6);
fbbeb65a 1391 if (r < 0) {
3c9b8860
TG
1392 log_warning_link(link,
1393 "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1394 return 0;
1395 }
1396
1397 break;
1398
1399 default:
1400 assert_not_reached("invalid address family");
1401 }
1402
3c9b8860
TG
1403 if (!inet_ntop(address->family, &address->in_addr, buf,
1404 INET6_ADDRSTRLEN)) {
987efa17 1405 log_warning_link(link, "could not print address");
fbbeb65a
TG
1406 return 0;
1407 }
1408
c6d3b303
TG
1409 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1410 &address->cinfo);
1411 if (r >= 0) {
1412 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1413 valid_str = "ever";
1414 else
1415 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1416 address->cinfo.ifa_valid * USEC_PER_SEC,
1417 USEC_PER_SEC);
1418 }
1419
428fd0a7
TG
1420 LIST_FOREACH(addresses, ad, link->addresses) {
1421 if (address_equal(ad, address)) {
1422 LIST_REMOVE(addresses, link->addresses, ad);
1423
1424 address_free(ad);
1425
1426 address_dropped = true;
1427
1428 break;
1429 }
1430 }
1431
fbbeb65a
TG
1432 switch (type) {
1433 case RTM_NEWADDR:
428fd0a7 1434 if (!address_dropped)
c6d3b303
TG
1435 log_debug_link(link, "added address: %s/%u (valid for %s)",
1436 buf, address->prefixlen,
1437 strna(valid_str));
393c0c5e 1438 else
c6d3b303
TG
1439 log_debug_link(link, "updated address: %s/%u (valid for %s)",
1440 buf, address->prefixlen,
1441 strna(valid_str));
fbbeb65a 1442
428fd0a7
TG
1443 LIST_PREPEND(addresses, link->addresses, address);
1444 address = NULL;
1445
f5602be9
TG
1446 link_save(link);
1447
428fd0a7 1448 break;
fbbeb65a 1449 case RTM_DELADDR:
f5602be9 1450 if (address_dropped) {
c6d3b303
TG
1451 log_debug_link(link, "removed address: %s/%u (valid for %s)",
1452 buf, address->prefixlen,
1453 strna(valid_str));
428fd0a7 1454
f5602be9 1455 link_save(link);
393c0c5e 1456 } else
3c9b8860 1457 log_warning_link(link,
c6d3b303
TG
1458 "removing non-existent address: %s/%u (valid for %s)",
1459 buf, address->prefixlen,
1460 strna(valid_str));
f5602be9 1461
fbbeb65a
TG
1462 break;
1463 default:
1464 assert_not_reached("Received invalid RTNL message type");
1465 }
1466
1467 return 1;
1468}
1469
505f8da7
TG
1470int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1471 Link *link;
fbbeb65a 1472 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
505f8da7
TG
1473 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1474 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1475 int r;
1476
1477 assert(m);
fbbeb65a 1478 assert(m->rtnl);
505f8da7
TG
1479 assert(message);
1480 assert(ret);
1481
1482 r = link_new(m, message, ret);
1483 if (r < 0)
1484 return r;
1485
1486 link = *ret;
1487
ae06ab10 1488 log_debug_link(link, "link %d added", link->ifindex);
505f8da7 1489
3c9b8860
TG
1490 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
1491 0);
fbbeb65a
TG
1492 if (r < 0)
1493 return r;
1494
3c9b8860
TG
1495 r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
1496 NULL);
fbbeb65a
TG
1497 if (r < 0)
1498 return r;
1499
5da8149f
TG
1500 link_ref(link);
1501
505f8da7
TG
1502 if (detect_container(NULL) <= 0) {
1503 /* not in a container, udev will be around */
ae06ab10 1504 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7
TG
1505 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1506 if (!device) {
3c9b8860
TG
1507 log_warning_link(link,
1508 "could not find udev device: %m");
9fecce80 1509 return -errno;
505f8da7
TG
1510 }
1511
3c4cb064 1512 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 1513 /* not yet ready */
8434fd5c 1514 log_debug_link(link, "link pending udev initialization...");
505f8da7 1515 return 0;
3c4cb064 1516 }
505f8da7 1517
4f561e8e
TG
1518 r = link_initialized(link, device);
1519 if (r < 0)
1520 return r;
1521 } else {
5da8149f
TG
1522 /* we are calling a callback directly, so must take a ref */
1523 link_ref(link);
1524
4f561e8e
TG
1525 r = link_initialized_and_synced(m->rtnl, NULL, link);
1526 if (r < 0)
1527 return r;
1528 }
505f8da7 1529
a748b692
TG
1530 return 0;
1531}
1532
22936833 1533int link_update(Link *link, sd_rtnl_message *m) {
c49b33ac 1534 struct ether_addr mac;
ca4e095a 1535 const char *ifname;
afe7fd56 1536 uint32_t mtu;
a61bb41c 1537 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
1538 int r;
1539
dd3efc09 1540 assert(link);
b8941f74 1541 assert(link->ifname);
22936833
TG
1542 assert(m);
1543
7619683b
TG
1544 if (link->state == LINK_STATE_LINGER) {
1545 link_ref(link);
1546 log_info_link(link, "link readded");
1547 link->state = LINK_STATE_ENSLAVING;
1548 }
1549
b8941f74
TG
1550 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1551 if (r >= 0 && !streq(ifname, link->ifname)) {
1552 log_info_link(link, "renamed to %s", ifname);
1553
1554 free(link->ifname);
1555 link->ifname = strdup(ifname);
1556 if (!link->ifname)
1557 return -ENOMEM;
1558 }
1559
afe7fd56
TG
1560 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1561 if (r >= 0 && mtu > 0) {
1562 link->mtu = mtu;
1563 if (!link->original_mtu) {
1564 link->original_mtu = mtu;
9842de0d 1565 log_debug_link(link, "saved original MTU: %"
afe7fd56
TG
1566 PRIu32, link->original_mtu);
1567 }
1568
1569 if (link->dhcp_client) {
3c9b8860
TG
1570 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1571 link->mtu);
afe7fd56 1572 if (r < 0) {
3c9b8860
TG
1573 log_warning_link(link,
1574 "Could not update MTU in DHCP client: %s",
afe7fd56
TG
1575 strerror(-r));
1576 return r;
1577 }
1578 }
9842de0d 1579 }
69629de9 1580
e9189a1f
TG
1581 /* The kernel may broadcast NEWLINK messages without the MAC address
1582 set, simply ignore them. */
c49b33ac 1583 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 1584 if (r >= 0) {
3c9b8860
TG
1585 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1586 ETH_ALEN)) {
c49b33ac 1587
3c9b8860
TG
1588 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1589 ETH_ALEN);
c49b33ac 1590
20861203
TG
1591 log_debug_link(link, "MAC address: "
1592 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1593 mac.ether_addr_octet[0],
1594 mac.ether_addr_octet[1],
1595 mac.ether_addr_octet[2],
1596 mac.ether_addr_octet[3],
1597 mac.ether_addr_octet[4],
1598 mac.ether_addr_octet[5]);
c49b33ac 1599
20861203
TG
1600 if (link->ipv4ll) {
1601 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1602 if (r < 0) {
3c9b8860
TG
1603 log_warning_link(link,
1604 "Could not update MAC address in IPv4LL client: %s",
20861203
TG
1605 strerror(-r));
1606 return r;
1607 }
c49b33ac 1608 }
c49b33ac 1609
20861203 1610 if (link->dhcp_client) {
3c9b8860
TG
1611 r = sd_dhcp_client_set_mac(link->dhcp_client,
1612 &link->mac);
20861203 1613 if (r < 0) {
3c9b8860
TG
1614 log_warning_link(link,
1615 "Could not update MAC address in DHCP client: %s",
20861203
TG
1616 strerror(-r));
1617 return r;
1618 }
c49b33ac 1619 }
4138fb2c
PF
1620
1621 if (link->dhcp6_client) {
1622 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1623 &link->mac);
1624 if (r < 0) {
3c9b8860
TG
1625 log_warning_link(link,
1626 "Could not update MAC address in DHCPv6 client: %s",
4138fb2c
PF
1627 strerror(-r));
1628 return r;
1629 }
1630 }
c49b33ac 1631 }
4f882b2a
TG
1632 }
1633
a61bb41c
TG
1634 had_carrier = link_has_carrier(link);
1635
1636 r = link_update_flags(link, m);
1637 if (r < 0)
1638 return r;
1639
1640 carrier_gained = !had_carrier && link_has_carrier(link);
1641 carrier_lost = had_carrier && !link_has_carrier(link);
1642
1643 if (carrier_gained) {
1644 log_info_link(link, "gained carrier");
1645
1646 if (link->network) {
1647 r = link_acquire_conf(link);
1648 if (r < 0) {
1649 link_enter_failed(link);
1650 return r;
1651 }
1652 }
1653 } else if (carrier_lost) {
1654 log_info_link(link, "lost carrier");
1655
1656 r = link_stop_clients(link);
1657 if (r < 0) {
1658 link_enter_failed(link);
1659 return r;
1660 }
1661 }
1662
1663 return 0;
dd3efc09 1664}
fe8db0c5 1665
e375dcde
TG
1666static void link_update_operstate(Link *link) {
1667
1668 assert(link);
1669
1670 if (link->kernel_operstate == IF_OPER_DORMANT)
1671 link->operstate = LINK_OPERSTATE_DORMANT;
a61bb41c 1672 else if (link_has_carrier(link)) {
e375dcde
TG
1673 Address *address;
1674 uint8_t scope = RT_SCOPE_NOWHERE;
1675
1676 /* if we have carrier, check what addresses we have */
1677 LIST_FOREACH(addresses, address, link->addresses) {
81163121
TG
1678 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1679 continue;
1680
e375dcde
TG
1681 if (address->scope < scope)
1682 scope = address->scope;
1683 }
1684
1685 if (scope < RT_SCOPE_SITE)
1686 /* universally accessible addresses found */
1687 link->operstate = LINK_OPERSTATE_ROUTABLE;
1688 else if (scope < RT_SCOPE_HOST)
1689 /* only link or site local addresses found */
1690 link->operstate = LINK_OPERSTATE_DEGRADED;
1691 else
1692 /* no useful addresses found */
1693 link->operstate = LINK_OPERSTATE_CARRIER;
54cba0b1 1694 } else if (link->flags & IFF_UP)
d3df0e39 1695 link->operstate = LINK_OPERSTATE_NO_CARRIER;
54cba0b1 1696 else
d3df0e39 1697 link->operstate = LINK_OPERSTATE_OFF;
e375dcde
TG
1698}
1699
fe8db0c5 1700int link_save(Link *link) {
68a8723c 1701 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 1702 _cleanup_fclose_ FILE *f = NULL;
e375dcde 1703 const char *admin_state, *oper_state;
fe8db0c5
TG
1704 int r;
1705
1706 assert(link);
1707 assert(link->state_file);
68a8723c 1708 assert(link->lease_file);
bbf7c048
TG
1709 assert(link->manager);
1710
e375dcde
TG
1711 link_update_operstate(link);
1712
bbf7c048
TG
1713 r = manager_save(link->manager);
1714 if (r < 0)
1715 return r;
fe8db0c5 1716
370e9930
TG
1717 if (link->state == LINK_STATE_LINGER) {
1718 unlink(link->state_file);
1719 return 0;
1720 }
1721
deb2e523
TG
1722 admin_state = link_state_to_string(link->state);
1723 assert(admin_state);
1724
e375dcde
TG
1725 oper_state = link_operstate_to_string(link->operstate);
1726 assert(oper_state);
deb2e523 1727
fe8db0c5
TG
1728 r = fopen_temporary(link->state_file, &f, &temp_path);
1729 if (r < 0)
c2d6bd61 1730 return r;
fe8db0c5
TG
1731
1732 fchmod(fileno(f), 0644);
1733
1734 fprintf(f,
1735 "# This is private data. Do not parse.\n"
deb2e523 1736 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
1737 "OPER_STATE=%s\n",
1738 admin_state, oper_state);
fe8db0c5 1739
bcb7a07e 1740 if (link->network) {
ea352b40
LP
1741 char **address, **domain;
1742 bool space;
b0e39c82
TG
1743
1744 fputs("DNS=", f);
ea352b40
LP
1745 space = false;
1746 STRV_FOREACH(address, link->network->dns) {
1747 if (space)
1748 fputc(' ', f);
1749 fputs(*address, f);
1750 space = true;
1751 }
d5314fff 1752
b0e39c82
TG
1753 if (link->network->dhcp_dns &&
1754 link->dhcp_lease) {
1755 const struct in_addr *addresses;
1756
1757 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1758 if (r > 0) {
ea352b40
LP
1759 if (space)
1760 fputc(' ', f);
b0e39c82 1761 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
1762 }
1763 }
1764
b0e39c82
TG
1765 fputs("\n", f);
1766
1767 fprintf(f, "NTP=");
ea352b40
LP
1768 space = false;
1769 STRV_FOREACH(address, link->network->ntp) {
1770 if (space)
1771 fputc(' ', f);
1772 fputs(*address, f);
1773 space = true;
1774 }
d5314fff 1775
b0e39c82
TG
1776 if (link->network->dhcp_ntp &&
1777 link->dhcp_lease) {
1778 const struct in_addr *addresses;
1779
1780 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1781 if (r > 0) {
ea352b40
LP
1782 if (space)
1783 fputc(' ', f);
b0e39c82 1784 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
1785 }
1786 }
1787
b0e39c82 1788 fputs("\n", f);
bd8f6538 1789
6192b846 1790 fprintf(f, "DOMAINS=");
ea352b40
LP
1791 space = false;
1792 STRV_FOREACH(domain, link->network->domains) {
1793 if (space)
1794 fputc(' ', f);
1795 fputs(*domain, f);
1796 space = true;
1797 }
d5314fff 1798
ad0734e8 1799 if (link->network->dhcp_domains &&
9b4d1882
TG
1800 link->dhcp_lease) {
1801 const char *domainname;
1802
1803 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 1804 if (r >= 0) {
ea352b40
LP
1805 if (space)
1806 fputc(' ', f);
6192b846 1807 fputs(domainname, f);
6192b846 1808 }
9b4d1882
TG
1809 }
1810
6192b846
TG
1811 fputs("\n", f);
1812
67272d15
TG
1813 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1814 yes_no(link->network->wildcard_domain));
1815
3c9b8860
TG
1816 fprintf(f, "LLMNR=%s\n",
1817 llmnr_support_to_string(link->network->llmnr));
bcb7a07e 1818 }
7374f9d8 1819
fe8db0c5 1820 if (link->dhcp_lease) {
d9876a52
TG
1821 assert(link->network);
1822
68a8723c 1823 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 1824 if (r < 0)
c2d6bd61 1825 goto fail;
fe8db0c5 1826
7374f9d8 1827 fprintf(f,
b0e39c82
TG
1828 "DHCP_LEASE=%s\n",
1829 link->lease_file);
deb2e523 1830 } else
68a8723c 1831 unlink(link->lease_file);
fe8db0c5 1832
c2d6bd61
LP
1833 r = fflush_and_check(f);
1834 if (r < 0)
1835 goto fail;
fe8db0c5 1836
c2d6bd61 1837 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 1838 r = -errno;
c2d6bd61 1839 goto fail;
fe8db0c5
TG
1840 }
1841
c2d6bd61 1842 return 0;
c2d6bd61
LP
1843fail:
1844 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1845 unlink(link->state_file);
1846 unlink(temp_path);
fe8db0c5
TG
1847 return r;
1848}
1849
1850static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 1851 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
1852 [LINK_STATE_ENSLAVING] = "configuring",
1853 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1854 [LINK_STATE_SETTING_ROUTES] = "configuring",
1855 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 1856 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 1857 [LINK_STATE_FAILED] = "failed",
370e9930 1858 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
1859};
1860
1861DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
1862
1863static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
1864 [LINK_OPERSTATE_OFF] = "off",
1865 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
1866 [LINK_OPERSTATE_DORMANT] = "dormant",
1867 [LINK_OPERSTATE_CARRIER] = "carrier",
1868 [LINK_OPERSTATE_DEGRADED] = "degraded",
1869 [LINK_OPERSTATE_ROUTABLE] = "routable",
1870};
1871
1872DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);