]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
networkd: ndisc - fix token support
[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
b5efdb8a 26#include "alloc-util.h"
1346b1f0 27#include "bus-util.h"
bd91b83e 28#include "dhcp-lease-internal.h"
f833694d 29#include "event-util.h"
3ffd4af2 30#include "fd-util.h"
cf1d700d
TG
31#include "fileio.h"
32#include "netlink-util.h"
c6f7c917 33#include "network-internal.h"
3ffd4af2
LP
34#include "networkd-link.h"
35#include "networkd-netdev.h"
cf1d700d
TG
36#include "set.h"
37#include "socket-util.h"
15a5e950 38#include "stdio-util.h"
8b43440b 39#include "string-table.h"
cf1d700d
TG
40#include "udev-util.h"
41#include "util.h"
42#include "virt.h"
fc2f9534 43
a97dcc12 44bool link_dhcp6_enabled(Link *link) {
78c958f8
TG
45 if (link->flags & IFF_LOOPBACK)
46 return false;
47
48 if (!link->network)
49 return false;
50
e0ee46f2 51 return link->network->dhcp & ADDRESS_FAMILY_IPV6;
78c958f8
TG
52}
53
a97dcc12 54bool link_dhcp4_enabled(Link *link) {
78c958f8
TG
55 if (link->flags & IFF_LOOPBACK)
56 return false;
57
58 if (!link->network)
59 return false;
60
e0ee46f2 61 return link->network->dhcp & ADDRESS_FAMILY_IPV4;
78c958f8
TG
62}
63
a97dcc12 64bool link_dhcp4_server_enabled(Link *link) {
78c958f8
TG
65 if (link->flags & IFF_LOOPBACK)
66 return false;
67
68 if (!link->network)
69 return false;
70
71 return link->network->dhcp_server;
72}
73
a97dcc12 74bool link_ipv4ll_enabled(Link *link) {
78c958f8
TG
75 if (link->flags & IFF_LOOPBACK)
76 return false;
77
78 if (!link->network)
79 return false;
80
e0ee46f2 81 return link->network->link_local & ADDRESS_FAMILY_IPV4;
d0d6a4cd
TG
82}
83
84bool link_ipv6ll_enabled(Link *link) {
85 if (link->flags & IFF_LOOPBACK)
86 return false;
87
88 if (!link->network)
89 return false;
90
e0ee46f2 91 return link->network->link_local & ADDRESS_FAMILY_IPV6;
78c958f8
TG
92}
93
a97dcc12 94bool link_lldp_enabled(Link *link) {
ce43e484
SS
95 if (link->flags & IFF_LOOPBACK)
96 return false;
97
98 if (!link->network)
99 return false;
100
5a8bcb67 101 if (link->network->bridge)
ce43e484
SS
102 return false;
103
104 return link->network->lldp;
105}
106
769d324c 107static bool link_ipv4_forward_enabled(Link *link) {
5a8bcb67
LP
108 if (link->flags & IFF_LOOPBACK)
109 return false;
110
111 if (!link->network)
112 return false;
113
765afd5c
LP
114 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
115 return false;
116
e0ee46f2 117 return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
769d324c
LP
118}
119
120static bool link_ipv6_forward_enabled(Link *link) {
765afd5c
LP
121
122 if (!socket_ipv6_is_supported())
123 return false;
124
769d324c
LP
125 if (link->flags & IFF_LOOPBACK)
126 return false;
127
128 if (!link->network)
129 return false;
130
765afd5c
LP
131 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
132 return false;
133
e0ee46f2 134 return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
5a8bcb67
LP
135}
136
f5a8c43f
TG
137bool link_ipv6_accept_ra_enabled(Link *link) {
138 if (link->flags & IFF_LOOPBACK)
139 return false;
140
141 if (!link->network)
142 return false;
143
144 /* If unset use system default (enabled if local forwarding is disabled.
145 * disabled if local forwarding is enabled).
146 * If set, ignore or enforce RA independent of local forwarding state.
147 */
148 if (link->network->ipv6_accept_ra < 0)
149 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
150 return !link_ipv6_forward_enabled(link);
151 else if (link->network->ipv6_accept_ra > 0)
152 /* accept RA even if ip_forward is enabled */
153 return true;
154 else
155 /* ignore RA */
156 return false;
157}
158
1f0d9695 159static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
d68e2e59
LP
160
161 if (!socket_ipv6_is_supported())
162 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
163
49092e22 164 if (link->flags & IFF_LOOPBACK)
1f0d9695 165 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
49092e22
SS
166
167 if (!link->network)
1f0d9695 168 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
49092e22
SS
169
170 return link->network->ipv6_privacy_extensions;
171}
172
84de38c5
TG
173void link_update_operstate(Link *link) {
174 LinkOperationalState operstate;
175 assert(link);
176
177 if (link->kernel_operstate == IF_OPER_DORMANT)
178 operstate = LINK_OPERSTATE_DORMANT;
179 else if (link_has_carrier(link)) {
180 Address *address;
181 uint8_t scope = RT_SCOPE_NOWHERE;
182 Iterator i;
183
184 /* if we have carrier, check what addresses we have */
185 SET_FOREACH(address, link->addresses, i) {
186 if (!address_is_ready(address))
187 continue;
188
189 if (address->scope < scope)
190 scope = address->scope;
191 }
192
193 /* for operstate we also take foreign addresses into account */
194 SET_FOREACH(address, link->addresses_foreign, i) {
195 if (!address_is_ready(address))
196 continue;
197
198 if (address->scope < scope)
199 scope = address->scope;
200 }
201
202 if (scope < RT_SCOPE_SITE)
203 /* universally accessible addresses found */
204 operstate = LINK_OPERSTATE_ROUTABLE;
205 else if (scope < RT_SCOPE_HOST)
206 /* only link or site local addresses found */
207 operstate = LINK_OPERSTATE_DEGRADED;
208 else
209 /* no useful addresses found */
210 operstate = LINK_OPERSTATE_CARRIER;
211 } else if (link->flags & IFF_UP)
212 operstate = LINK_OPERSTATE_NO_CARRIER;
213 else
214 operstate = LINK_OPERSTATE_OFF;
215
216 if (link->operstate != operstate) {
217 link->operstate = operstate;
218 link_send_changed(link, "OperationalState", NULL);
219 link_dirty(link);
220 manager_dirty(link->manager);
221 }
222}
223
51d18171
TG
224#define FLAG_STRING(string, flag, old, new) \
225 (((old ^ new) & flag) \
226 ? ((old & flag) ? (" -" string) : (" +" string)) \
227 : "")
228
1c4baffc 229static int link_update_flags(Link *link, sd_netlink_message *m) {
51d18171
TG
230 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
231 uint8_t operstate;
232 int r;
233
234 assert(link);
235
236 r = sd_rtnl_message_link_get_flags(m, &flags);
6a7a4e4d
LP
237 if (r < 0)
238 return log_link_warning_errno(link, r, "Could not get link flags: %m");
51d18171 239
1c4baffc 240 r = sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &operstate);
51d18171
TG
241 if (r < 0)
242 /* if we got a message without operstate, take it to mean
243 the state was unchanged */
244 operstate = link->kernel_operstate;
245
246 if ((link->flags == flags) && (link->kernel_operstate == operstate))
247 return 0;
248
249 if (link->flags != flags) {
6a7a4e4d 250 log_link_debug(link, "Flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
51d18171
TG
251 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
252 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
253 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
254 FLAG_STRING("UP", IFF_UP, link->flags, flags),
255 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
256 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
257 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
258 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
259 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
260 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
261 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
262 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
263 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
264 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
265 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
266 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
267 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
268 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
269 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
270
271 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
272 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
273 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
274 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
275 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
276 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
277 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
278 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
279
280 /* link flags are currently at most 18 bits, let's align to
281 * printing 20 */
282 if (unknown_flags_added)
79008bdd 283 log_link_debug(link,
6a7a4e4d 284 "Unknown link flags gained: %#.5x (ignoring)",
51d18171
TG
285 unknown_flags_added);
286
287 if (unknown_flags_removed)
79008bdd 288 log_link_debug(link,
6a7a4e4d 289 "Unknown link flags lost: %#.5x (ignoring)",
51d18171
TG
290 unknown_flags_removed);
291 }
292
293 link->flags = flags;
294 link->kernel_operstate = operstate;
295
84de38c5 296 link_update_operstate(link);
51d18171
TG
297
298 return 0;
299}
300
1c4baffc 301static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
14b746f7 302 _cleanup_link_unref_ Link *link = NULL;
505f8da7 303 uint16_t type;
ca4e095a 304 const char *ifname;
505f8da7 305 int r, ifindex;
f579559b 306
0c2f9b84 307 assert(manager);
505f8da7 308 assert(message);
f579559b
TG
309 assert(ret);
310
1c4baffc 311 r = sd_netlink_message_get_type(message, &type);
505f8da7
TG
312 if (r < 0)
313 return r;
314 else if (type != RTM_NEWLINK)
315 return -EINVAL;
316
317 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
318 if (r < 0)
319 return r;
320 else if (ifindex <= 0)
321 return -EINVAL;
322
1c4baffc 323 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
505f8da7
TG
324 if (r < 0)
325 return r;
326
f579559b
TG
327 link = new0(Link, 1);
328 if (!link)
329 return -ENOMEM;
330
14b746f7 331 link->n_ref = 1;
5a3eb5a7 332 link->manager = manager;
8434fd5c 333 link->state = LINK_STATE_PENDING;
be3a09b7 334 link->rtnl_extended_attrs = true;
505f8da7
TG
335 link->ifindex = ifindex;
336 link->ifname = strdup(ifname);
337 if (!link->ifname)
338 return -ENOMEM;
f579559b 339
1c4baffc 340 r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
512922f8 341 if (r < 0)
79008bdd 342 log_link_debug(link, "MAC address not found for new device, continuing without");
512922f8 343
3c9b8860
TG
344 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
345 link->ifindex);
fe8db0c5 346 if (r < 0)
315db1a8 347 return -ENOMEM;
fe8db0c5 348
3c9b8860
TG
349 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
350 link->ifindex);
68a8723c
TG
351 if (r < 0)
352 return -ENOMEM;
353
49699bac
SS
354 r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
355 link->ifindex);
356 if (r < 0)
357 return -ENOMEM;
358
359
d5099efc 360 r = hashmap_ensure_allocated(&manager->links, NULL);
ae06ab10
TG
361 if (r < 0)
362 return r;
363
364 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
f579559b
TG
365 if (r < 0)
366 return r;
367
51d18171
TG
368 r = link_update_flags(link, message);
369 if (r < 0)
370 return r;
371
f579559b
TG
372 *ret = link;
373 link = NULL;
374
375 return 0;
376}
377
14b746f7 378static void link_free(Link *link) {
428fd0a7 379 Address *address;
0d4ad91d
AR
380 Iterator i;
381 Link *carrier;
428fd0a7 382
f579559b
TG
383 if (!link)
384 return;
385
cf1d700d
TG
386 while (!set_isempty(link->addresses))
387 address_free(set_first(link->addresses));
388
adda1ed9
TG
389 while (!set_isempty(link->addresses_foreign))
390 address_free(set_first(link->addresses_foreign));
391
4701725c
HV
392 link->addresses = set_free(link->addresses);
393
394 link->addresses_foreign = set_free(link->addresses_foreign);
adda1ed9 395
11bf3cce
LP
396 while ((address = link->pool_addresses)) {
397 LIST_REMOVE(addresses, link->pool_addresses, address);
398 address_free(address);
399 }
400
bfcdba8d 401 sd_dhcp_server_unref(link->dhcp_server);
e5b04c8d 402 sd_dhcp_client_unref(link->dhcp_client);
a6cc569e 403 sd_dhcp_lease_unref(link->dhcp_lease);
f5be5601 404
68a8723c
TG
405 free(link->lease_file);
406
07e10d1a
TG
407 sd_lldp_free(link->lldp);
408
49699bac
SS
409 free(link->lldp_file);
410
56cd007a 411 sd_ipv4ll_unref(link->ipv4ll);
4138fb2c 412 sd_dhcp6_client_unref(link->dhcp6_client);
de1e9928 413 sd_ndisc_unref(link->ndisc_router_discovery);
4138fb2c 414
28aeb07f 415 if (link->manager)
ae06ab10 416 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
f579559b 417
c166a070 418 free(link->ifname);
68a8723c 419
84de38c5 420 (void)unlink(link->state_file);
fe8db0c5 421 free(link->state_file);
c166a070 422
b5db00e5
UTL
423 udev_device_unref(link->udev_device);
424
0d4ad91d
AR
425 HASHMAP_FOREACH (carrier, link->bound_to_links, i)
426 hashmap_remove(link->bound_to_links, INT_TO_PTR(carrier->ifindex));
427 hashmap_free(link->bound_to_links);
428
429 HASHMAP_FOREACH (carrier, link->bound_by_links, i)
430 hashmap_remove(link->bound_by_links, INT_TO_PTR(carrier->ifindex));
431 hashmap_free(link->bound_by_links);
432
f579559b
TG
433 free(link);
434}
435
14b746f7 436Link *link_unref(Link *link) {
957325b7
TG
437 if (!link)
438 return NULL;
439
440 assert(link->n_ref > 0);
441
442 link->n_ref --;
443
444 if (link->n_ref > 0)
445 return NULL;
446
447 link_free(link);
14b746f7
TG
448
449 return NULL;
450}
451
452Link *link_ref(Link *link) {
957325b7
TG
453 if (!link)
454 return NULL;
455
456 assert(link->n_ref > 0);
457
458 link->n_ref ++;
14b746f7
TG
459
460 return link;
461}
462
11a7f229
TG
463int link_get(Manager *m, int ifindex, Link **ret) {
464 Link *link;
11a7f229
TG
465
466 assert(m);
11a7f229
TG
467 assert(ifindex);
468 assert(ret);
469
ae06ab10 470 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
11a7f229
TG
471 if (!link)
472 return -ENODEV;
473
474 *ret = link;
475
476 return 0;
477}
478
e331e246
TG
479static void link_set_state(Link *link, LinkState state) {
480 assert(link);
481
482 if (link->state == state)
483 return;
484
485 link->state = state;
486
487 link_send_changed(link, "AdministrativeState", NULL);
488
489 return;
490}
491
57bd6899
TG
492static void link_enter_unmanaged(Link *link) {
493 assert(link);
494
6a7a4e4d 495 log_link_debug(link, "Unmanaged");
57bd6899 496
e331e246 497 link_set_state(link, LINK_STATE_UNMANAGED);
57bd6899 498
84de38c5 499 link_dirty(link);
57bd6899
TG
500}
501
111bb8f9
TG
502static int link_stop_clients(Link *link) {
503 int r = 0, k;
504
505 assert(link);
506 assert(link->manager);
507 assert(link->manager->event);
508
ba179154 509 if (link->dhcp_client) {
111bb8f9 510 k = sd_dhcp_client_stop(link->dhcp_client);
6a7a4e4d
LP
511 if (k < 0)
512 r = log_link_warning_errno(link, r, "Could not stop DHCPv4 client: %m");
111bb8f9
TG
513 }
514
ba179154 515 if (link->ipv4ll) {
111bb8f9 516 k = sd_ipv4ll_stop(link->ipv4ll);
6a7a4e4d
LP
517 if (k < 0)
518 r = log_link_warning_errno(link, r, "Could not stop IPv4 link-local: %m");
dd43110f
TG
519 }
520
f5a8c43f
TG
521 if (link->dhcp6_client) {
522 k = sd_dhcp6_client_stop(link->dhcp6_client);
523 if (k < 0)
524 r = log_link_warning_errno(link, r, "Could not stop DHCPv6 client: %m");
525 }
4138fb2c 526
f5a8c43f 527 if (link->ndisc_router_discovery) {
de1e9928 528 k = sd_ndisc_stop(link->ndisc_router_discovery);
6a7a4e4d 529 if (k < 0)
ceabaf0f 530 r = log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery: %m");
4138fb2c
PF
531 }
532
ce43e484 533 if (link->lldp) {
ce43e484 534 k = sd_lldp_stop(link->lldp);
6a7a4e4d
LP
535 if (k < 0)
536 r = log_link_warning_errno(link, r, "Could not stop LLDP: %m");
ce43e484
SS
537 }
538
111bb8f9
TG
539 return r;
540}
541
b22d8a00 542void link_enter_failed(Link *link) {
ef1ba606 543 assert(link);
f882c247 544
370e9930 545 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2139694e
TG
546 return;
547
6a7a4e4d 548 log_link_warning(link, "Failed");
449f7554 549
e331e246 550 link_set_state(link, LINK_STATE_FAILED);
fe8db0c5 551
111bb8f9
TG
552 link_stop_clients(link);
553
84de38c5 554 link_dirty(link);
f882c247
TG
555}
556
4f434938
LP
557static Address* link_find_dhcp_server_address(Link *link) {
558 Address *address;
559
560 assert(link);
561 assert(link->network);
562
d4cdbea5 563 /* The first statically configured address if there is any */
4f434938
LP
564 LIST_FOREACH(addresses, address, link->network->static_addresses) {
565
566 if (address->family != AF_INET)
567 continue;
568
af93291c 569 if (in_addr_is_null(address->family, &address->in_addr))
4f434938
LP
570 continue;
571
572 return address;
573 }
574
575 /* If that didn't work, find a suitable address we got from the pool */
576 LIST_FOREACH(addresses, address, link->pool_addresses) {
577 if (address->family != AF_INET)
578 continue;
579
580 return address;
581 }
582
583 return NULL;
584}
585
dd43110f 586static int link_enter_configured(Link *link) {
dd43110f
TG
587 assert(link);
588 assert(link->network);
589 assert(link->state == LINK_STATE_SETTING_ROUTES);
590
6a7a4e4d 591 log_link_info(link, "Configured");
dd43110f 592
e331e246 593 link_set_state(link, LINK_STATE_CONFIGURED);
dd43110f 594
84de38c5 595 link_dirty(link);
dd43110f
TG
596
597 return 0;
598}
599
8012cd39
TG
600void link_check_ready(Link *link) {
601 Address *a;
602 Iterator i;
603
3c9b8860 604 assert(link);
adda1ed9
TG
605
606 if (!link->network)
607 return;
3c9b8860
TG
608
609 if (!link->static_configured)
610 return;
611
78c958f8 612 if (link_ipv4ll_enabled(link))
3c9b8860
TG
613 if (!link->ipv4ll_address ||
614 !link->ipv4ll_route)
615 return;
616
e7ab854c
TG
617 if (link_ipv6ll_enabled(link))
618 if (!link->ipv6ll_address)
619 return;
620
3ada37a2
PF
621 if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
622 !link->dhcp4_configured) ||
623 (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
624 !link->dhcp6_configured) ||
625 (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
626 !link->dhcp4_configured && !link->dhcp6_configured))
18d29550
PF
627 return;
628
3b015d40
TG
629 if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
630 return;
631
8012cd39
TG
632 SET_FOREACH(a, link->addresses, i)
633 if (!address_is_ready(a))
634 return;
635
9fdaa992
TG
636 if (link->state != LINK_STATE_CONFIGURED)
637 link_enter_configured(link);
3c9b8860
TG
638
639 return;
640}
641
1c4baffc 642static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 643 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
644 int r;
645
3c9b8860 646 assert(link->link_messages > 0);
370e9930
TG
647 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
648 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
649 LINK_STATE_LINGER));
f882c247 650
3c9b8860 651 link->link_messages --;
f882c247 652
77a008c0 653 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
654 return 1;
655
1c4baffc 656 r = sd_netlink_message_get_errno(m);
c166a070 657 if (r < 0 && r != -EEXIST)
a2fae7bb 658 log_link_warning_errno(link, r, "Could not set route: %m");
f882c247 659
3c9b8860 660 if (link->link_messages == 0) {
6a7a4e4d 661 log_link_debug(link, "Routes set");
3c9b8860 662 link->static_configured = true;
8012cd39 663 link_check_ready(link);
dd3efc09 664 }
f882c247
TG
665
666 return 1;
667}
668
669static int link_enter_set_routes(Link *link) {
a6cc569e 670 Route *rt;
f882c247
TG
671 int r;
672
673 assert(link);
674 assert(link->network);
ef1ba606 675 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 676
e331e246 677 link_set_state(link, LINK_STATE_SETTING_ROUTES);
f882c247 678
3d3d4255 679 LIST_FOREACH(routes, rt, link->network->static_routes) {
a6cc569e 680 r = route_configure(rt, link, &route_handler);
dd3efc09 681 if (r < 0) {
6a7a4e4d 682 log_link_warning_errno(link, r, "Could not set routes: %m");
3c9b8860 683 link_enter_failed(link);
a6cc569e
TG
684 return r;
685 }
686
3c9b8860 687 link->link_messages ++;
8ddbeaa2 688 }
f5be5601 689
3c9b8860
TG
690 if (link->link_messages == 0) {
691 link->static_configured = true;
8012cd39 692 link_check_ready(link);
431ca2ce 693 } else
6a7a4e4d 694 log_link_debug(link, "Setting routes");
f882c247
TG
695
696 return 0;
697}
698
91b5f997 699int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 700 _cleanup_link_unref_ Link *link = userdata;
5c1d3fc9
UTL
701 int r;
702
703 assert(m);
704 assert(link);
705 assert(link->ifname);
706
5da8149f 707 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
5c1d3fc9
UTL
708 return 1;
709
1c4baffc 710 r = sd_netlink_message_get_errno(m);
b90b025a 711 if (r < 0 && r != -ESRCH)
a2fae7bb 712 log_link_warning_errno(link, r, "Could not drop route: %m");
5c1d3fc9 713
5bdd314c 714 return 1;
5c1d3fc9
UTL
715}
716
1c4baffc 717static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 718 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
719 int r;
720
4958aee4 721 assert(rtnl);
f5be5601
TG
722 assert(m);
723 assert(link);
724 assert(link->ifname);
3c9b8860 725 assert(link->link_messages > 0);
370e9930
TG
726 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
727 LINK_STATE_FAILED, LINK_STATE_LINGER));
f882c247 728
3c9b8860 729 link->link_messages --;
f882c247 730
5da8149f 731 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
732 return 1;
733
1c4baffc 734 r = sd_netlink_message_get_errno(m);
c166a070 735 if (r < 0 && r != -EEXIST)
a2fae7bb 736 log_link_warning_errno(link, r, "could not set address: %m");
45af44d4 737 else if (r >= 0)
200a0868 738 manager_rtnl_process_address(rtnl, m, link->manager);
f882c247 739
3c9b8860 740 if (link->link_messages == 0) {
6a7a4e4d 741 log_link_debug(link, "Addresses set");
ef1ba606 742 link_enter_set_routes(link);
dd3efc09 743 }
f882c247
TG
744
745 return 1;
746}
747
4f5f911e
LP
748static int link_push_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
749 _cleanup_free_ struct in_addr *addresses = NULL;
750 size_t n_addresses = 0, n_allocated = 0;
751 char **a;
752
753 log_debug("Copying DNS server information from %s", link->ifname);
754
755 if (!link->network)
756 return 0;
757
758 STRV_FOREACH(a, link->network->dns) {
759 struct in_addr ia;
760
761 /* Only look for IPv4 addresses */
762 if (inet_pton(AF_INET, *a, &ia) <= 0)
763 continue;
764
765 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
766 return log_oom();
767
768 addresses[n_addresses++] = ia;
769 }
770
771 if (link->network->dhcp_dns &&
772 link->dhcp_lease) {
773 const struct in_addr *da = NULL;
774 int n;
775
776 n = sd_dhcp_lease_get_dns(link->dhcp_lease, &da);
777 if (n > 0) {
778
779 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
780 return log_oom();
781
782 memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
783 n_addresses += n;
784 }
785 }
786
787 if (n_addresses <= 0)
788 return 0;
789
790 return sd_dhcp_server_set_dns(s, addresses, n_addresses);
791}
792
793static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
794 _cleanup_free_ struct in_addr *addresses = NULL;
795 size_t n_addresses = 0, n_allocated = 0;
796 char **a;
797
798 if (!link->network)
799 return 0;
800
801 log_debug("Copying NTP server information from %s", link->ifname);
802
803 STRV_FOREACH(a, link->network->ntp) {
804 struct in_addr ia;
805
806 /* Only look for IPv4 addresses */
807 if (inet_pton(AF_INET, *a, &ia) <= 0)
808 continue;
809
810 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
811 return log_oom();
812
813 addresses[n_addresses++] = ia;
814 }
815
816 if (link->network->dhcp_ntp &&
817 link->dhcp_lease) {
818 const struct in_addr *da = NULL;
819 int n;
820
821 n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
822 if (n > 0) {
823
824 if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
825 return log_oom();
826
827 memcpy(addresses + n_addresses, da, n * sizeof(struct in_addr));
828 n_addresses += n;
829 }
830 }
831
832 if (n_addresses <= 0)
833 return 0;
834
835 return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
836}
837
f882c247 838static int link_enter_set_addresses(Link *link) {
a6cc569e 839 Address *ad;
f882c247
TG
840 int r;
841
842 assert(link);
843 assert(link->network);
f5be5601 844 assert(link->state != _LINK_STATE_INVALID);
f882c247 845
e331e246 846 link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
f882c247 847
3d3d4255 848 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
66669078 849 r = address_configure(ad, link, &address_handler, false);
dd3efc09 850 if (r < 0) {
5a8bcb67 851 log_link_warning_errno(link, r, "Could not set addresses: %m");
f5be5601
TG
852 link_enter_failed(link);
853 return r;
854 }
855
3c9b8860 856 link->link_messages ++;
f882c247
TG
857 }
858
d4cdbea5
TG
859 /* now that we can figure out a default address for the dhcp server,
860 start it */
861 if (link_dhcp4_server_enabled(link)) {
d4cdbea5 862 Address *address;
4f5f911e
LP
863 Link *uplink = NULL;
864 bool acquired_uplink = false;
d4cdbea5
TG
865
866 address = link_find_dhcp_server_address(link);
867 if (!address) {
6a7a4e4d 868 log_link_warning(link, "Failed to find suitable address for DHCPv4 server instance.");
d4cdbea5
TG
869 link_enter_failed(link);
870 return 0;
871 }
872
61986155 873 /* use the server address' subnet as the pool */
9b3a67c5
TG
874 r = sd_dhcp_server_configure_pool(link->dhcp_server, &address->in_addr.in, address->prefixlen,
875 link->network->dhcp_server_pool_offset, link->network->dhcp_server_pool_size);
d4cdbea5
TG
876 if (r < 0)
877 return r;
878
879 /* TODO:
880 r = sd_dhcp_server_set_router(link->dhcp_server,
881 &main_address->in_addr.in);
882 if (r < 0)
883 return r;
d4cdbea5
TG
884 */
885
586ac6f7
LP
886 if (link->network->dhcp_server_max_lease_time_usec > 0) {
887 r = sd_dhcp_server_set_max_lease_time(
888 link->dhcp_server,
889 DIV_ROUND_UP(link->network->dhcp_server_max_lease_time_usec, USEC_PER_SEC));
890 if (r < 0)
891 return r;
892 }
893
894 if (link->network->dhcp_server_default_lease_time_usec > 0) {
895 r = sd_dhcp_server_set_default_lease_time(
896 link->dhcp_server,
897 DIV_ROUND_UP(link->network->dhcp_server_default_lease_time_usec, USEC_PER_SEC));
898 if (r < 0)
899 return r;
900 }
901
1a04db0f
LP
902 if (link->network->dhcp_server_emit_dns) {
903
4f5f911e 904 if (link->network->n_dhcp_server_dns > 0)
1a04db0f 905 r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns);
4f5f911e
LP
906 else {
907 uplink = manager_find_uplink(link->manager, link);
908 acquired_uplink = true;
909
910 if (!uplink) {
911 log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
912 r = 0;
913 } else
914 r = link_push_dns_to_dhcp_server(uplink, link->dhcp_server);
915 }
916 if (r < 0)
917 log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
1a04db0f
LP
918 }
919
920
921 if (link->network->dhcp_server_emit_ntp) {
922
4f5f911e 923 if (link->network->n_dhcp_server_ntp > 0)
1a04db0f 924 r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp);
4f5f911e
LP
925 else {
926 if (!acquired_uplink)
927 uplink = manager_find_uplink(link->manager, link);
928
929 if (!uplink) {
930 log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
931 r = 0;
932 } else
933 r = link_push_ntp_to_dhcp_server(uplink, link->dhcp_server);
934
935 }
936 if (r < 0)
937 log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
1a04db0f
LP
938 }
939
8eb9058d
LP
940 if (link->network->dhcp_server_emit_timezone) {
941 _cleanup_free_ char *buffer = NULL;
0ab8a1b6 942 const char *tz = NULL;
8eb9058d
LP
943
944 if (link->network->dhcp_server_timezone)
945 tz = link->network->dhcp_server_timezone;
946 else {
947 r = get_timezone(&buffer);
948 if (r < 0)
949 log_warning_errno(r, "Failed to determine timezone: %m");
950 else
951 tz = buffer;
952 }
953
954 if (tz) {
955 r = sd_dhcp_server_set_timezone(link->dhcp_server, tz);
956 if (r < 0)
957 return r;
958 }
959 }
960
d4cdbea5
TG
961 r = sd_dhcp_server_start(link->dhcp_server);
962 if (r < 0) {
6a7a4e4d 963 log_link_warning_errno(link, r, "Could not start DHCPv4 server instance: %m");
d4cdbea5
TG
964
965 link_enter_failed(link);
966
967 return 0;
968 }
969
6a7a4e4d 970 log_link_debug(link, "Offering DHCPv4 leases");
d4cdbea5
TG
971 }
972
6a7a4e4d 973 if (link->link_messages == 0)
431ca2ce 974 link_enter_set_routes(link);
6a7a4e4d
LP
975 else
976 log_link_debug(link, "Setting addresses");
431ca2ce 977
f882c247
TG
978 return 0;
979}
980
91b5f997 981int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 982 _cleanup_link_unref_ Link *link = userdata;
ff254138
TG
983 int r;
984
985 assert(m);
986 assert(link);
987 assert(link->ifname);
988
5da8149f 989 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ff254138
TG
990 return 1;
991
1c4baffc 992 r = sd_netlink_message_get_errno(m);
b90b025a 993 if (r < 0 && r != -EADDRNOTAVAIL)
a2fae7bb 994 log_link_warning_errno(link, r, "Could not drop address: %m");
ff254138 995
5bdd314c 996 return 1;
ff254138
TG
997}
998
a245ced0 999static int link_set_bridge_fdb(Link *const link) {
b98b483b
AR
1000 FdbEntry *fdb_entry;
1001 int r = 0;
1002
1003 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
ea6ec096 1004 r = fdb_entry_configure(link, fdb_entry);
b98b483b 1005 if(r < 0) {
6a7a4e4d 1006 log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
b98b483b
AR
1007 break;
1008 }
1009 }
1010
1011 return r;
1012}
1013
1c4baffc 1014static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
e1853b00
SS
1015 _cleanup_link_unref_ Link *link = userdata;
1016 int r;
1017
6a7a4e4d 1018 log_link_debug(link, "Set link");
e1853b00 1019
1c4baffc 1020 r = sd_netlink_message_get_errno(m);
e1853b00 1021 if (r < 0 && r != -EEXIST) {
f2341e0a 1022 log_link_error_errno(link, r, "Could not join netdev: %m");
e1853b00
SS
1023 link_enter_failed(link);
1024 return 1;
1025 }
1026
1027 return 0;
1028}
1029
19070062 1030static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
5da8149f 1031 _cleanup_link_unref_ Link *link = userdata;
21b80ad1 1032 const sd_bus_error *e;
1346b1f0 1033
19070062 1034 assert(m);
b226d99b
TG
1035 assert(link);
1036
5da8149f 1037 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
370e9930 1038 return 1;
370e9930 1039
21b80ad1
LP
1040 e = sd_bus_message_get_error(m);
1041 if (e)
1042 log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
1346b1f0
TG
1043
1044 return 1;
1045}
1046
3c9b8860 1047int link_set_hostname(Link *link, const char *hostname) {
21b80ad1 1048 int r;
1346b1f0 1049
b226d99b
TG
1050 assert(link);
1051 assert(link->manager);
1346b1f0 1052
dce391e7 1053 log_link_debug(link, "Setting transient hostname: '%s'", strna(hostname));
1346b1f0 1054
3c9b8860
TG
1055 if (!link->manager->bus) {
1056 /* TODO: replace by assert when we can rely on kdbus */
6a7a4e4d 1057 log_link_info(link, "Not connected to system bus, ignoring transient hostname.");
bcbca829
TG
1058 return 0;
1059 }
1060
9c34154a 1061 r = sd_bus_call_method_async(
b226d99b 1062 link->manager->bus,
9c34154a 1063 NULL,
1346b1f0
TG
1064 "org.freedesktop.hostname1",
1065 "/org/freedesktop/hostname1",
1066 "org.freedesktop.hostname1",
9c34154a
UTL
1067 "SetHostname",
1068 set_hostname_handler,
1069 link,
1070 "sb",
1071 hostname,
1072 false);
1346b1f0 1073
6a7a4e4d
LP
1074 if (r < 0)
1075 return log_link_error_errno(link, r, "Could not set transient hostname: %m");
b226d99b
TG
1076
1077 link_ref(link);
1346b1f0 1078
5da8149f 1079 return 0;
1346b1f0
TG
1080}
1081
21b80ad1
LP
1082static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1083 _cleanup_link_unref_ Link *link = userdata;
1084 const sd_bus_error *e;
1085
1086 assert(m);
1087 assert(link);
1088
1089 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1090 return 1;
1091
1092 e = sd_bus_message_get_error(m);
1093 if (e)
1094 log_link_warning_errno(link, sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
1095
1096 return 1;
1097}
1098
64d6c229 1099int link_set_timezone(Link *link, const char *tz) {
21b80ad1
LP
1100 int r;
1101
1102 assert(link);
1103 assert(link->manager);
64d6c229 1104 assert(tz);
21b80ad1 1105
64d6c229 1106 log_link_debug(link, "Setting system timezone: '%s'", tz);
21b80ad1
LP
1107
1108 if (!link->manager->bus) {
1109 log_link_info(link, "Not connected to system bus, ignoring timezone.");
1110 return 0;
1111 }
1112
1113 r = sd_bus_call_method_async(
1114 link->manager->bus,
1115 NULL,
1116 "org.freedesktop.timedate1",
1117 "/org/freedesktop/timedate1",
1118 "org.freedesktop.timedate1",
1119 "SetTimezone",
1120 set_timezone_handler,
1121 link,
1122 "sb",
64d6c229 1123 tz,
21b80ad1
LP
1124 false);
1125 if (r < 0)
1126 return log_link_error_errno(link, r, "Could not set timezone: %m");
1127
1128 link_ref(link);
1129
1130 return 0;
1131}
1132
1c4baffc 1133static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1134 _cleanup_link_unref_ Link *link = userdata;
4f882b2a
TG
1135 int r;
1136
1137 assert(m);
1138 assert(link);
1139 assert(link->ifname);
1140
5da8149f 1141 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
4f882b2a
TG
1142 return 1;
1143
1c4baffc 1144 r = sd_netlink_message_get_errno(m);
c9ccc19f 1145 if (r < 0)
a2fae7bb 1146 log_link_warning_errno(link, r, "Could not set MTU: %m");
4f882b2a
TG
1147
1148 return 1;
1149}
1150
3c9b8860 1151int link_set_mtu(Link *link, uint32_t mtu) {
1c4baffc 1152 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
4f882b2a
TG
1153 int r;
1154
1155 assert(link);
1156 assert(link->manager);
1157 assert(link->manager->rtnl);
1158
6a7a4e4d 1159 log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
4f882b2a 1160
6a7a4e4d
LP
1161 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1162 if (r < 0)
1163 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
4f882b2a 1164
1c4baffc 1165 r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
6a7a4e4d
LP
1166 if (r < 0)
1167 return log_link_error_errno(link, r, "Could not append MTU: %m");
4f882b2a 1168
1c4baffc 1169 r = sd_netlink_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
6a7a4e4d
LP
1170 if (r < 0)
1171 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
4f882b2a 1172
ae941762 1173 link_ref(link);
b226d99b 1174
4f882b2a
TG
1175 return 0;
1176}
1177
e1853b00 1178static int link_set_bridge(Link *link) {
1c4baffc 1179 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
e1853b00
SS
1180 int r;
1181
1182 assert(link);
1183 assert(link->network);
1184
6a7a4e4d
LP
1185 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1186 if (r < 0)
1187 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
e1853b00
SS
1188
1189 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
6a7a4e4d
LP
1190 if (r < 0)
1191 return log_link_error_errno(link, r, "Could not set message family: %m");
e1853b00 1192
1c4baffc 1193 r = sd_netlink_message_open_container(req, IFLA_PROTINFO);
6a7a4e4d
LP
1194 if (r < 0)
1195 return log_link_error_errno(link, r, "Could not append IFLA_PROTINFO attribute: %m");
e1853b00 1196
84c34096 1197 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_GUARD, !link->network->use_bpdu);
eb7ff4dd
SS
1198 if (r < 0)
1199 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_GUARD attribute: %m");
1200
1201 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MODE, link->network->hairpin);
1202 if (r < 0)
1203 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MODE attribute: %m");
1204
1205 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_FAST_LEAVE, link->network->fast_leave);
1206 if (r < 0)
1207 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_FAST_LEAVE attribute: %m");
1208
23da66bb 1209 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, !link->network->allow_port_to_be_root);
eb7ff4dd
SS
1210 if (r < 0)
1211 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
1212
1213 r = sd_netlink_message_append_u8(req, IFLA_BRPORT_UNICAST_FLOOD, link->network->unicast_flood);
1214 if (r < 0)
1215 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_UNICAST_FLOOD attribute: %m");
1216
e1853b00 1217 if(link->network->cost != 0) {
1c4baffc 1218 r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
6a7a4e4d
LP
1219 if (r < 0)
1220 return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
e1853b00
SS
1221 }
1222
1c4baffc 1223 r = sd_netlink_message_close_container(req);
6a7a4e4d
LP
1224 if (r < 0)
1225 return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
e1853b00 1226
1c4baffc 1227 r = sd_netlink_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
6a7a4e4d
LP
1228 if (r < 0)
1229 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
e1853b00
SS
1230
1231 link_ref(link);
1232
1233 return r;
1234}
1235
49699bac
SS
1236static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
1237 Link *link = userdata;
1238 int r;
1239
1240 assert(link);
1241 assert(link->network);
1242 assert(link->manager);
1243
9ef61f2e
DH
1244 switch (event) {
1245 case SD_LLDP_EVENT_UPDATE_INFO:
1246 r = sd_lldp_save(link->lldp, link->lldp_file);
1247 if (r < 0)
1248 log_link_warning_errno(link, r, "Could not save LLDP: %m");
49699bac 1249
9ef61f2e
DH
1250 break;
1251 default:
1252 break;
1253 }
49699bac
SS
1254}
1255
e7ab854c
TG
1256static int link_acquire_ipv6_conf(Link *link) {
1257 int r;
1258
1259 assert(link);
1260
1261 if (link_dhcp6_enabled(link)) {
1262 assert(link->dhcp6_client);
1263
1264 log_link_debug(link, "Acquiring DHCPv6 lease");
1265
1266 r = sd_dhcp6_client_start(link->dhcp6_client);
63348d13 1267 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1268 return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
1269 }
1270
1271 if (link_ipv6_accept_ra_enabled(link)) {
1272 assert(link->ndisc_router_discovery);
1273
1274 log_link_debug(link, "Discovering IPv6 routers");
1275
1276 r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
63348d13 1277 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1278 return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
1279 }
1280
1281 return 0;
1282}
1283
ff254138
TG
1284static int link_acquire_conf(Link *link) {
1285 int r;
1286
1287 assert(link);
1288 assert(link->network);
ff254138
TG
1289 assert(link->manager);
1290 assert(link->manager->event);
1291
78c958f8 1292 if (link_ipv4ll_enabled(link)) {
eb34d4af 1293 assert(link->ipv4ll);
ff254138 1294
6a7a4e4d 1295 log_link_debug(link, "Acquiring IPv4 link-local address");
5c1d3fc9
UTL
1296
1297 r = sd_ipv4ll_start(link->ipv4ll);
6a7a4e4d
LP
1298 if (r < 0)
1299 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
5c1d3fc9
UTL
1300 }
1301
78c958f8 1302 if (link_dhcp4_enabled(link)) {
eb34d4af 1303 assert(link->dhcp_client);
ff254138 1304
6a7a4e4d 1305 log_link_debug(link, "Acquiring DHCPv4 lease");
ab47d620 1306
5c1d3fc9 1307 r = sd_dhcp_client_start(link->dhcp_client);
6a7a4e4d
LP
1308 if (r < 0)
1309 return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
5c1d3fc9 1310 }
ff254138 1311
ce43e484
SS
1312 if (link_lldp_enabled(link)) {
1313 assert(link->lldp);
1314
1315 log_link_debug(link, "Starting LLDP");
1316
1317 r = sd_lldp_start(link->lldp);
6a7a4e4d
LP
1318 if (r < 0)
1319 return log_link_warning_errno(link, r, "Could not start LLDP: %m");
ce43e484
SS
1320 }
1321
ff254138
TG
1322 return 0;
1323}
1324
a61bb41c 1325bool link_has_carrier(Link *link) {
deb2e523
TG
1326 /* see Documentation/networking/operstates.txt in the kernel sources */
1327
a61bb41c 1328 if (link->kernel_operstate == IF_OPER_UP)
deb2e523
TG
1329 return true;
1330
a61bb41c 1331 if (link->kernel_operstate == IF_OPER_UNKNOWN)
deb2e523 1332 /* operstate may not be implemented, so fall back to flags */
a61bb41c 1333 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
deb2e523
TG
1334 return true;
1335
1336 return false;
1337}
1338
1c4baffc 1339static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1340 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
1341 int r;
1342
1746cf2a
TG
1343 assert(link);
1344
5da8149f 1345 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
1346 return 1;
1347
1c4baffc 1348 r = sd_netlink_message_get_errno(m);
6a7a4e4d
LP
1349 if (r < 0)
1350 /* we warn but don't fail the link, as it may be
1351 brought up later */
a2fae7bb 1352 log_link_warning_errno(link, r, "Could not bring up interface: %m");
45ad2c13 1353
f882c247
TG
1354 return 1;
1355}
1356
1357static int link_up(Link *link) {
1c4baffc 1358 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
5c3072ea 1359 uint8_t ipv6ll_mode;
f579559b
TG
1360 int r;
1361
f882c247 1362 assert(link);
c106cc36 1363 assert(link->network);
f882c247
TG
1364 assert(link->manager);
1365 assert(link->manager->rtnl);
1366
6a7a4e4d 1367 log_link_debug(link, "Bringing link up");
449f7554 1368
6a7a4e4d
LP
1369 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1370 if (r < 0)
1371 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
f579559b 1372
5d4795f3 1373 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
6a7a4e4d
LP
1374 if (r < 0)
1375 return log_link_error_errno(link, r, "Could not set link flags: %m");
fc25d7f8 1376
c106cc36 1377 if (link->network->mac) {
1c4baffc 1378 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
6a7a4e4d
LP
1379 if (r < 0)
1380 return log_link_error_errno(link, r, "Could not set MAC address: %m");
c106cc36
TG
1381 }
1382
1383 if (link->network->mtu) {
1c4baffc 1384 r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
6a7a4e4d
LP
1385 if (r < 0)
1386 return log_link_error_errno(link, r, "Could not set MTU: %m");
c106cc36
TG
1387 }
1388
1c4baffc 1389 r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
6a7a4e4d
LP
1390 if (r < 0)
1391 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
d0d6a4cd 1392
01d28f81
TG
1393 if (socket_ipv6_is_supported()) {
1394 /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
1c4baffc 1395 r = sd_netlink_message_open_container(req, AF_INET6);
01d28f81
TG
1396 if (r < 0)
1397 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
d0d6a4cd 1398
01d28f81 1399 ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
1c4baffc 1400 r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
01d28f81
TG
1401 if (r < 0)
1402 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
d0d6a4cd 1403
01d28f81 1404 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1c4baffc 1405 r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
01d28f81
TG
1406 if (r < 0)
1407 return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
1408 }
1409
1c4baffc 1410 r = sd_netlink_message_close_container(req);
6a7a4e4d 1411 if (r < 0)
01d28f81 1412 return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
7f77697a 1413 }
d0d6a4cd 1414
1c4baffc 1415 r = sd_netlink_message_close_container(req);
6a7a4e4d
LP
1416 if (r < 0)
1417 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
d0d6a4cd 1418
1c4baffc 1419 r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
6a7a4e4d
LP
1420 if (r < 0)
1421 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
f579559b 1422
b226d99b
TG
1423 link_ref(link);
1424
f882c247
TG
1425 return 0;
1426}
1427
1c4baffc 1428static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
0d4ad91d
AR
1429 _cleanup_link_unref_ Link *link = userdata;
1430 int r;
1431
1432 assert(link);
1433
1434 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1435 return 1;
1436
1c4baffc 1437 r = sd_netlink_message_get_errno(m);
0d4ad91d 1438 if (r < 0)
a2fae7bb 1439 log_link_warning_errno(link, r, "Could not bring down interface: %m");
0d4ad91d
AR
1440
1441 return 1;
1442}
1443
1444static int link_down(Link *link) {
1c4baffc 1445 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
0d4ad91d
AR
1446 int r;
1447
1448 assert(link);
1449 assert(link->manager);
1450 assert(link->manager->rtnl);
1451
6a7a4e4d 1452 log_link_debug(link, "Bringing link down");
0d4ad91d
AR
1453
1454 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1455 RTM_SETLINK, link->ifindex);
6a7a4e4d
LP
1456 if (r < 0)
1457 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
0d4ad91d
AR
1458
1459 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
6a7a4e4d
LP
1460 if (r < 0)
1461 return log_link_error_errno(link, r, "Could not set link flags: %m");
0d4ad91d 1462
1c4baffc 1463 r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
6a7a4e4d
LP
1464 if (r < 0)
1465 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
0d4ad91d
AR
1466
1467 link_ref(link);
1468
1469 return 0;
1470}
1471
1472static int link_handle_bound_to_list(Link *link) {
1473 Link *l;
1474 Iterator i;
1475 int r;
1476 bool required_up = false;
1477 bool link_is_up = false;
1478
1479 assert(link);
1480
1481 if (hashmap_isempty(link->bound_to_links))
1482 return 0;
1483
1484 if (link->flags & IFF_UP)
1485 link_is_up = true;
1486
1487 HASHMAP_FOREACH (l, link->bound_to_links, i)
1488 if (link_has_carrier(l)) {
1489 required_up = true;
1490 break;
1491 }
1492
1493 if (!required_up && link_is_up) {
1494 r = link_down(link);
1495 if (r < 0)
1496 return r;
1497 } else if (required_up && !link_is_up) {
1498 r = link_up(link);
1499 if (r < 0)
1500 return r;
1501 }
1502
1503 return 0;
1504}
1505
1506static int link_handle_bound_by_list(Link *link) {
1507 Iterator i;
1508 Link *l;
1509 int r;
1510
1511 assert(link);
1512
1513 if (hashmap_isempty(link->bound_by_links))
1514 return 0;
1515
1516 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1517 r = link_handle_bound_to_list(l);
1518 if (r < 0)
1519 return r;
1520 }
1521
1522 return 0;
1523}
1524
1525static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1526 int r;
1527
1528 assert(link);
1529 assert(carrier);
1530
1531 if (link == carrier)
1532 return 0;
1533
1534 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1535 return 0;
1536
1537 r = hashmap_ensure_allocated(h, NULL);
1538 if (r < 0)
1539 return r;
1540
1541 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1542 if (r < 0)
1543 return r;
1544
1545 return 0;
1546}
1547
1548static int link_new_bound_by_list(Link *link) {
1549 Manager *m;
1550 Link *carrier;
1551 Iterator i;
1552 int r;
1553 bool list_updated = false;
1554
1555 assert(link);
1556 assert(link->manager);
1557
1558 m = link->manager;
1559
1560 HASHMAP_FOREACH (carrier, m->links, i) {
1561 if (!carrier->network)
1562 continue;
1563
1564 if (strv_isempty(carrier->network->bind_carrier))
1565 continue;
1566
1567 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1568 r = link_put_carrier(link, carrier, &link->bound_by_links);
1569 if (r < 0)
1570 return r;
1571
1572 list_updated = true;
1573 }
1574 }
1575
1576 if (list_updated)
84de38c5 1577 link_dirty(link);
0d4ad91d
AR
1578
1579 HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
1580 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1581 if (r < 0)
1582 return r;
1583
84de38c5 1584 link_dirty(carrier);
0d4ad91d
AR
1585 }
1586
1587 return 0;
1588}
1589
1590static int link_new_bound_to_list(Link *link) {
1591 Manager *m;
1592 Link *carrier;
1593 Iterator i;
1594 int r;
1595 bool list_updated = false;
1596
1597 assert(link);
1598 assert(link->manager);
1599
1600 if (!link->network)
1601 return 0;
1602
1603 if (strv_isempty(link->network->bind_carrier))
1604 return 0;
1605
1606 m = link->manager;
1607
1608 HASHMAP_FOREACH (carrier, m->links, i) {
1609 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1610 r = link_put_carrier(link, carrier, &link->bound_to_links);
1611 if (r < 0)
1612 return r;
1613
1614 list_updated = true;
1615 }
1616 }
1617
1618 if (list_updated)
84de38c5 1619 link_dirty(link);
0d4ad91d
AR
1620
1621 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1622 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1623 if (r < 0)
1624 return r;
1625
84de38c5 1626 link_dirty(carrier);
0d4ad91d
AR
1627 }
1628
1629 return 0;
1630}
1631
1632static int link_new_carrier_maps(Link *link) {
1633 int r;
1634
1635 r = link_new_bound_by_list(link);
1636 if (r < 0)
1637 return r;
1638
1639 r = link_handle_bound_by_list(link);
1640 if (r < 0)
1641 return r;
1642
1643 r = link_new_bound_to_list(link);
1644 if (r < 0)
1645 return r;
1646
1647 r = link_handle_bound_to_list(link);
1648 if (r < 0)
1649 return r;
1650
1651 return 0;
1652}
1653
1654static void link_free_bound_to_list(Link *link) {
1655 Link *bound_to;
1656 Iterator i;
1657
1658 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1659 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1660
1661 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
84de38c5 1662 link_dirty(bound_to);
0d4ad91d
AR
1663 }
1664
1665 return;
1666}
1667
1668static void link_free_bound_by_list(Link *link) {
1669 Link *bound_by;
1670 Iterator i;
1671
1672 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1673 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1674
1675 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
84de38c5 1676 link_dirty(bound_by);
0d4ad91d
AR
1677 link_handle_bound_to_list(bound_by);
1678 }
1679 }
1680
1681 return;
1682}
1683
1684static void link_free_carrier_maps(Link *link) {
1685 bool list_updated = false;
1686
1687 assert(link);
1688
1689 if (!hashmap_isempty(link->bound_to_links)) {
1690 link_free_bound_to_list(link);
1691 list_updated = true;
1692 }
1693
1694 if (!hashmap_isempty(link->bound_by_links)) {
1695 link_free_bound_by_list(link);
1696 list_updated = true;
1697 }
1698
1699 if (list_updated)
84de38c5 1700 link_dirty(link);
0d4ad91d
AR
1701
1702 return;
1703}
1704
1705void link_drop(Link *link) {
1706 if (!link || link->state == LINK_STATE_LINGER)
1707 return;
1708
1709 link_set_state(link, LINK_STATE_LINGER);
1710
1711 link_free_carrier_maps(link);
1712
6a7a4e4d 1713 log_link_debug(link, "Link removed");
0d4ad91d 1714
84de38c5 1715 (void)unlink(link->state_file);
0d4ad91d
AR
1716 link_unref(link);
1717
1718 return;
1719}
1720
3f265037 1721static int link_joined(Link *link) {
f882c247
TG
1722 int r;
1723
ef1ba606 1724 assert(link);
f5be5601 1725 assert(link->network);
dd3efc09 1726
0d4ad91d
AR
1727 if (!hashmap_isempty(link->bound_to_links)) {
1728 r = link_handle_bound_to_list(link);
1729 if (r < 0)
1730 return r;
1731 } else if (!(link->flags & IFF_UP)) {
505f8da7
TG
1732 r = link_up(link);
1733 if (r < 0) {
1734 link_enter_failed(link);
1735 return r;
1736 }
ef1ba606 1737 }
f882c247 1738
e1853b00
SS
1739 if(link->network->bridge) {
1740 r = link_set_bridge(link);
6a7a4e4d
LP
1741 if (r < 0)
1742 log_link_error_errno(link, r, "Could not set bridge message: %m");
e1853b00
SS
1743 }
1744
fb6730c4 1745 return link_enter_set_addresses(link);
02b59d57
TG
1746}
1747
62e2d5bb 1748static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1749 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1750 int r;
1751
1746cf2a 1752 assert(link);
ef1ba606 1753 assert(link->network);
02b59d57 1754
52433f6b
TG
1755 link->enslaving --;
1756
5da8149f 1757 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1758 return 1;
1759
1c4baffc 1760 r = sd_netlink_message_get_errno(m);
856f962c 1761 if (r < 0 && r != -EEXIST) {
a2fae7bb 1762 log_link_error_errno(link, r, "Could not join netdev: %m");
ef1ba606
TG
1763 link_enter_failed(link);
1764 return 1;
ba179154 1765 } else
6a7a4e4d 1766 log_link_debug(link, "Joined netdev");
02b59d57 1767
856f962c 1768 if (link->enslaving <= 0)
3f265037 1769 link_joined(link);
02b59d57
TG
1770
1771 return 1;
1772}
1773
3f265037 1774static int link_enter_join_netdev(Link *link) {
6a0a2f86 1775 NetDev *netdev;
672682a6 1776 Iterator i;
02b59d57
TG
1777 int r;
1778
1779 assert(link);
1780 assert(link->network);
8434fd5c 1781 assert(link->state == LINK_STATE_PENDING);
02b59d57 1782
e331e246 1783 link_set_state(link, LINK_STATE_ENSLAVING);
02b59d57 1784
84de38c5 1785 link_dirty(link);
fe8db0c5 1786
7951dea2
SS
1787 if (!link->network->bridge &&
1788 !link->network->bond &&
6a0a2f86 1789 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1790 return link_joined(link);
02b59d57 1791
d9c67ea1 1792 if (link->network->bond) {
f2341e0a
LP
1793 log_struct(LOG_DEBUG,
1794 LOG_LINK_INTERFACE(link),
1795 LOG_NETDEV_INTERFACE(link->network->bond),
1796 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
1797 NULL);
1798
1799 r = netdev_join(link->network->bond, link, netdev_join_handler);
52433f6b 1800 if (r < 0) {
f2341e0a
LP
1801 log_struct_errno(LOG_WARNING, r,
1802 LOG_LINK_INTERFACE(link),
1803 LOG_NETDEV_INTERFACE(link->network->bond),
1804 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
1805 NULL);
1806
52433f6b
TG
1807 link_enter_failed(link);
1808 return r;
1809 }
1810
0ad6148e
MO
1811 link->enslaving ++;
1812 }
1813
d9c67ea1 1814 if (link->network->bridge) {
f2341e0a
LP
1815 log_struct(LOG_DEBUG,
1816 LOG_LINK_INTERFACE(link),
1817 LOG_NETDEV_INTERFACE(link->network->bridge),
1818 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
1819 NULL);
1820
1821 r = netdev_join(link->network->bridge, link, netdev_join_handler);
0ad6148e 1822 if (r < 0) {
f2341e0a
LP
1823 log_struct_errno(LOG_WARNING, r,
1824 LOG_LINK_INTERFACE(link),
1825 LOG_NETDEV_INTERFACE(link->network->bridge),
1826 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
1827 NULL),
0ad6148e
MO
1828 link_enter_failed(link);
1829 return r;
1830 }
1831
52433f6b
TG
1832 link->enslaving ++;
1833 }
1834
6a0a2f86 1835 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
7951dea2 1836
f2341e0a
LP
1837 log_struct(LOG_DEBUG,
1838 LOG_LINK_INTERFACE(link),
1839 LOG_NETDEV_INTERFACE(netdev),
1840 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
1841 NULL);
1842
1843 r = netdev_join(netdev, link, netdev_join_handler);
7951dea2 1844 if (r < 0) {
f2341e0a
LP
1845 log_struct_errno(LOG_WARNING, r,
1846 LOG_LINK_INTERFACE(link),
1847 LOG_NETDEV_INTERFACE(netdev),
1848 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
1849 NULL);
326cb406
SS
1850 link_enter_failed(link);
1851 return r;
1852 }
1853
326cb406
SS
1854 link->enslaving ++;
1855 }
1856
ef1ba606
TG
1857 return 0;
1858}
1859
769d324c 1860static int link_set_ipv4_forward(Link *link) {
5a8bcb67
LP
1861 int r;
1862
765afd5c 1863 if (!link_ipv4_forward_enabled(link))
15dee3f0
LP
1864 return 0;
1865
765afd5c
LP
1866 /* We propagate the forwarding flag from one interface to the
1867 * global setting one way. This means: as long as at least one
1868 * interface was configured at any time that had IP forwarding
1869 * enabled the setting will stay on for good. We do this
1870 * primarily to keep IPv4 and IPv6 packet forwarding behaviour
1871 * somewhat in sync (see below). */
15dee3f0 1872
765afd5c 1873 r = write_string_file("/proc/sys/net/ipv4/ip_forward", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 1874 if (r < 0)
765afd5c 1875 log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
43c6d5ab 1876
769d324c
LP
1877 return 0;
1878}
1879
1880static int link_set_ipv6_forward(Link *link) {
769d324c
LP
1881 int r;
1882
765afd5c 1883 if (!link_ipv6_forward_enabled(link))
8add5f79
NO
1884 return 0;
1885
765afd5c
LP
1886 /* On Linux, the IPv6 stack does not not know a per-interface
1887 * packet forwarding setting: either packet forwarding is on
1888 * for all, or off for all. We hence don't bother with a
1889 * per-interface setting, but simply propagate the interface
1890 * flag, if it is set, to the global flag, one-way. Note that
1891 * while IPv4 would allow a per-interface flag, we expose the
1892 * same behaviour there and also propagate the setting from
1893 * one to all, to keep things simple (see above). */
15dee3f0 1894
765afd5c 1895 r = write_string_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 1896 if (r < 0)
765afd5c 1897 log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
5a8bcb67
LP
1898
1899 return 0;
1900}
1901
49092e22 1902static int link_set_ipv6_privacy_extensions(Link *link) {
1f0d9695
LP
1903 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1904 IPv6PrivacyExtensions s;
49092e22
SS
1905 const char *p = NULL;
1906 int r;
1907
1f0d9695 1908 s = link_ipv6_privacy_extensions(link);
66a6bd68 1909 if (s < 0)
49092e22
SS
1910 return 0;
1911
1912 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
66a6bd68 1913 xsprintf(buf, "%u", (unsigned) link->network->ipv6_privacy_extensions);
49092e22 1914
eb3da901
LP
1915 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1916 if (r < 0)
49092e22
SS
1917 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
1918
1919 return 0;
1920}
1921
4f2e437a 1922static int link_set_ipv6_accept_ra(Link *link) {
3b015d40 1923 const char *p = NULL;
4f2e437a
SS
1924 int r;
1925
1926 /* Make this a NOP if IPv6 is not available */
1927 if (!socket_ipv6_is_supported())
1928 return 0;
1929
1930 if (link->flags & IFF_LOOPBACK)
1931 return 0;
1932
d68e2e59
LP
1933 if (!link->network)
1934 return 0;
1935
4f2e437a 1936 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
4f2e437a 1937
66a6bd68 1938 /* We handle router advertisments ourselves, tell the kernel to GTFO */
eb3da901
LP
1939 r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1940 if (r < 0)
3b015d40 1941 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
4f2e437a
SS
1942
1943 return 0;
1944}
1945
8749cbcd 1946static int link_set_ipv6_dad_transmits(Link *link) {
66a6bd68 1947 char buf[DECIMAL_STR_MAX(int) + 1];
8749cbcd
SS
1948 const char *p = NULL;
1949 int r;
1950
1951 /* Make this a NOP if IPv6 is not available */
1952 if (!socket_ipv6_is_supported())
1953 return 0;
1954
1955 if (link->flags & IFF_LOOPBACK)
1956 return 0;
1957
d68e2e59
LP
1958 if (!link->network)
1959 return 0;
1960
8749cbcd
SS
1961 if (link->network->ipv6_dad_transmits < 0)
1962 return 0;
1963
1964 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
66a6bd68 1965 xsprintf(buf, "%i", link->network->ipv6_dad_transmits);
8749cbcd 1966
eb3da901
LP
1967 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1968 if (r < 0)
8749cbcd 1969 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
8749cbcd
SS
1970
1971 return 0;
1972}
1973
b69c3180 1974static int link_set_ipv6_hop_limit(Link *link) {
66a6bd68 1975 char buf[DECIMAL_STR_MAX(int) + 1];
b69c3180
SS
1976 const char *p = NULL;
1977 int r;
1978
1979 /* Make this a NOP if IPv6 is not available */
1980 if (!socket_ipv6_is_supported())
1981 return 0;
1982
1983 if (link->flags & IFF_LOOPBACK)
1984 return 0;
1985
d68e2e59
LP
1986 if (!link->network)
1987 return 0;
1988
b69c3180
SS
1989 if (link->network->ipv6_hop_limit < 0)
1990 return 0;
1991
1992 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
66a6bd68 1993 xsprintf(buf, "%i", link->network->ipv6_hop_limit);
b69c3180 1994
eb3da901
LP
1995 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1996 if (r < 0)
b69c3180 1997 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
b69c3180
SS
1998
1999 return 0;
2000}
2001
5e5b137a
TG
2002static int link_drop_foreign_config(Link *link) {
2003 Address *address;
2004 Route *route;
2005 Iterator i;
2006 int r;
2007
2008 SET_FOREACH(address, link->addresses_foreign, i) {
2009 /* we consider IPv6LL addresses to be managed by the kernel */
2010 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2011 continue;
2012
2013 r = address_remove(address, link, link_address_remove_handler);
2014 if (r < 0)
2015 return r;
2016 }
2017
2018 SET_FOREACH(route, link->routes_foreign, i) {
2019 /* do not touch routes managed by the kernel */
2020 if (route->protocol == RTPROT_KERNEL)
2021 continue;
2022
2023 r = route_remove(route, link, link_address_remove_handler);
2024 if (r < 0)
2025 return r;
2026 }
2027
2028 return 0;
2029}
2030
a748b692 2031static int link_configure(Link *link) {
02b59d57
TG
2032 int r;
2033
ef1ba606 2034 assert(link);
b22d8a00 2035 assert(link->network);
8434fd5c 2036 assert(link->state == LINK_STATE_PENDING);
a748b692 2037
5e5b137a
TG
2038 r = link_drop_foreign_config(link);
2039 if (r < 0)
2040 return r;
2041
b98b483b
AR
2042 r = link_set_bridge_fdb(link);
2043 if (r < 0)
2044 return r;
2045
769d324c
LP
2046 r = link_set_ipv4_forward(link);
2047 if (r < 0)
2048 return r;
2049
2050 r = link_set_ipv6_forward(link);
5a8bcb67
LP
2051 if (r < 0)
2052 return r;
2053
49092e22
SS
2054 r = link_set_ipv6_privacy_extensions(link);
2055 if (r < 0)
2056 return r;
2057
4f2e437a
SS
2058 r = link_set_ipv6_accept_ra(link);
2059 if (r < 0)
2060 return r;
2061
8749cbcd
SS
2062 r = link_set_ipv6_dad_transmits(link);
2063 if (r < 0)
2064 return r;
b69c3180
SS
2065
2066 r = link_set_ipv6_hop_limit(link);
2067 if (r < 0)
2068 return r;
8749cbcd 2069
78c958f8 2070 if (link_ipv4ll_enabled(link)) {
b22d8a00 2071 r = ipv4ll_configure(link);
eb34d4af
TG
2072 if (r < 0)
2073 return r;
2074 }
2075
78c958f8 2076 if (link_dhcp4_enabled(link)) {
3c9b8860 2077 r = dhcp4_configure(link);
eb34d4af
TG
2078 if (r < 0)
2079 return r;
eb34d4af
TG
2080 }
2081
78c958f8 2082 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
2083 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2084 if (r < 0)
2085 return r;
2086
2087 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2088 if (r < 0)
2089 return r;
dd43110f
TG
2090 }
2091
62379e88
TG
2092 if (link_dhcp6_enabled(link) ||
2093 link_ipv6_accept_ra_enabled(link)) {
f5a8c43f
TG
2094 r = dhcp6_configure(link);
2095 if (r < 0)
2096 return r;
2097 }
2098
2099 if (link_ipv6_accept_ra_enabled(link)) {
de1e9928 2100 r = ndisc_configure(link);
4138fb2c
PF
2101 if (r < 0)
2102 return r;
2103 }
2104
ce43e484
SS
2105 if (link_lldp_enabled(link)) {
2106 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
2107 if (r < 0)
2108 return r;
2109
2110 r = sd_lldp_attach_event(link->lldp, NULL, 0);
2111 if (r < 0)
2112 return r;
49699bac
SS
2113
2114 r = sd_lldp_set_callback(link->lldp,
2115 lldp_handler, link);
2116 if (r < 0)
2117 return r;
ce43e484
SS
2118 }
2119
a61bb41c 2120 if (link_has_carrier(link)) {
1e9be60b
TG
2121 r = link_acquire_conf(link);
2122 if (r < 0)
2123 return r;
e7ab854c
TG
2124
2125 if (link->ipv6ll_address) {
2126 r = link_acquire_ipv6_conf(link);
2127 if (r < 0)
2128 return r;
2129 }
cc544d5f 2130 }
1e9be60b 2131
3f265037 2132 return link_enter_join_netdev(link);
505f8da7
TG
2133}
2134
1c4baffc 2135static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860 2136 void *userdata) {
5da8149f 2137 _cleanup_link_unref_ Link *link = userdata;
505f8da7 2138 Network *network;
505f8da7
TG
2139 int r;
2140
2141 assert(link);
2142 assert(link->ifname);
2143 assert(link->manager);
2144
8434fd5c 2145 if (link->state != LINK_STATE_PENDING)
5da8149f 2146 return 1;
505f8da7 2147
6a7a4e4d 2148 log_link_debug(link, "Link state is up-to-date");
505f8da7 2149
0d4ad91d
AR
2150 r = link_new_bound_by_list(link);
2151 if (r < 0)
2152 return r;
2153
2154 r = link_handle_bound_by_list(link);
2155 if (r < 0)
2156 return r;
2157
c4a03a56
TG
2158 if (!link->network) {
2159 r = network_get(link->manager, link->udev_device, link->ifname,
2160 &link->mac, &network);
2161 if (r == -ENOENT) {
2162 link_enter_unmanaged(link);
2163 return 1;
2164 } else if (r < 0)
2165 return r;
505f8da7 2166
c4a03a56
TG
2167 if (link->flags & IFF_LOOPBACK) {
2168 if (network->link_local != ADDRESS_FAMILY_NO)
2169 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
78c958f8 2170
c4a03a56
TG
2171 if (network->dhcp != ADDRESS_FAMILY_NO)
2172 log_link_debug(link, "Ignoring DHCP clients for loopback link");
78c958f8 2173
c4a03a56
TG
2174 if (network->dhcp_server)
2175 log_link_debug(link, "Ignoring DHCP server for loopback link");
2176 }
bd2efe92 2177
c4a03a56
TG
2178 r = network_apply(link->manager, network, link);
2179 if (r < 0)
2180 return r;
2181 }
505f8da7 2182
0d4ad91d
AR
2183 r = link_new_bound_to_list(link);
2184 if (r < 0)
2185 return r;
2186
a748b692
TG
2187 r = link_configure(link);
2188 if (r < 0)
2189 return r;
2190
5da8149f 2191 return 1;
505f8da7
TG
2192}
2193
4f561e8e 2194int link_initialized(Link *link, struct udev_device *device) {
1c4baffc 2195 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
4f561e8e
TG
2196 int r;
2197
2198 assert(link);
2199 assert(link->manager);
2200 assert(link->manager->rtnl);
2201 assert(device);
2202
8434fd5c 2203 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
2204 return 0;
2205
679b3605
TG
2206 if (link->udev_device)
2207 return 0;
2208
79008bdd 2209 log_link_debug(link, "udev initialized link");
4f561e8e
TG
2210
2211 link->udev_device = udev_device_ref(device);
2212
3c9b8860
TG
2213 /* udev has initialized the link, but we don't know if we have yet
2214 * processed the NEWLINK messages with the latest state. Do a GETLINK,
2215 * when it returns we know that the pending NEWLINKs have already been
2216 * processed and that we are up-to-date */
4f561e8e 2217
3c9b8860
TG
2218 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2219 link->ifindex);
4f561e8e
TG
2220 if (r < 0)
2221 return r;
2222
1c4baffc 2223 r = sd_netlink_call_async(link->manager->rtnl, req,
3c9b8860 2224 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
2225 if (r < 0)
2226 return r;
2227
5da8149f
TG
2228 link_ref(link);
2229
4f561e8e
TG
2230 return 0;
2231}
2232
c4a03a56 2233static int link_load(Link *link) {
0bc70f1d
TG
2234 _cleanup_free_ char *network_file = NULL,
2235 *addresses = NULL,
f703cc2c 2236 *routes = NULL,
0bc70f1d
TG
2237 *dhcp4_address = NULL,
2238 *ipv4ll_address = NULL;
2239 union in_addr_union address;
f703cc2c 2240 union in_addr_union route_dst;
c598ac76 2241 const char *p;
c4a03a56
TG
2242 int r;
2243
2244 assert(link);
2245
2246 r = parse_env_file(link->state_file, NEWLINE,
2247 "NETWORK_FILE", &network_file,
2248 "ADDRESSES", &addresses,
f703cc2c 2249 "ROUTES", &routes,
0bc70f1d
TG
2250 "DHCP4_ADDRESS", &dhcp4_address,
2251 "IPV4LL_ADDRESS", &ipv4ll_address,
c4a03a56
TG
2252 NULL);
2253 if (r < 0 && r != -ENOENT)
2254 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2255
2256 if (network_file) {
2257 Network *network;
2258 char *suffix;
2259
2260 /* drop suffix */
2261 suffix = strrchr(network_file, '.');
2262 if (!suffix) {
2263 log_link_debug(link, "Failed to get network name from %s", network_file);
2264 goto network_file_fail;
2265 }
2266 *suffix = '\0';
2267
2268 r = network_get_by_name(link->manager, basename(network_file), &network);
2269 if (r < 0) {
2270 log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2271 goto network_file_fail;
2272 }
2273
2274 r = network_apply(link->manager, network, link);
2275 if (r < 0)
2276 return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2277 }
2278
2279network_file_fail:
2280
2281 if (addresses) {
c598ac76 2282 p = addresses;
c4a03a56 2283
c598ac76
TG
2284 for (;;) {
2285 _cleanup_free_ char *address_str = NULL;
c4a03a56
TG
2286 char *prefixlen_str;
2287 int family;
2288 unsigned char prefixlen;
c4a03a56 2289
c598ac76
TG
2290 r = extract_first_word(&p, &address_str, NULL, 0);
2291 if (r < 0) {
2292 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2293 continue;
2294 } if (r == 0)
2295 break;
2296
2297 prefixlen_str = strchr(address_str, '/');
c4a03a56 2298 if (!prefixlen_str) {
c598ac76 2299 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
c4a03a56
TG
2300 continue;
2301 }
2302
2303 *prefixlen_str ++ = '\0';
2304
2305 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
2306 if (r != 1) {
2307 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
2308 continue;
2309 }
2310
c598ac76 2311 r = in_addr_from_string_auto(address_str, &family, &address);
c4a03a56 2312 if (r < 0) {
c598ac76 2313 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
c4a03a56
TG
2314 continue;
2315 }
2316
2317 r = address_add(link, family, &address, prefixlen, NULL);
2318 if (r < 0)
2319 return log_link_error_errno(link, r, "Failed to add address: %m");
2320 }
2321 }
2322
f703cc2c 2323 if (routes) {
c598ac76 2324 for (;;) {
f833694d 2325 Route *route;
c598ac76 2326 _cleanup_free_ char *route_str = NULL;
f833694d
TG
2327 _cleanup_event_source_unref_ sd_event_source *expire = NULL;
2328 usec_t lifetime;
f703cc2c
TG
2329 char *prefixlen_str;
2330 int family;
2331 unsigned char prefixlen, tos, table;
2332 uint32_t priority;
2333
c598ac76
TG
2334 r = extract_first_word(&p, &route_str, NULL, 0);
2335 if (r < 0) {
2336 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
2337 continue;
2338 } if (r == 0)
2339 break;
2340
2341 prefixlen_str = strchr(route_str, '/');
f703cc2c 2342 if (!prefixlen_str) {
c598ac76 2343 log_link_debug(link, "Failed to parse route %s", route_str);
f703cc2c
TG
2344 continue;
2345 }
2346
2347 *prefixlen_str ++ = '\0';
2348
f833694d
TG
2349 r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
2350 if (r != 5) {
2351 log_link_debug(link,
2352 "Failed to parse destination prefix length, tos, priority, table or expiration %s",
2353 prefixlen_str);
f703cc2c
TG
2354 continue;
2355 }
2356
c598ac76 2357 r = in_addr_from_string_auto(route_str, &family, &route_dst);
f703cc2c 2358 if (r < 0) {
c598ac76 2359 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
f703cc2c
TG
2360 continue;
2361 }
2362
f833694d 2363 r = route_add(link, family, &route_dst, prefixlen, tos, priority, table, &route);
f703cc2c
TG
2364 if (r < 0)
2365 return log_link_error_errno(link, r, "Failed to add route: %m");
f833694d
TG
2366
2367 if (lifetime != USEC_INFINITY) {
2368 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
2369 0, route_expire_handler, route);
2370 if (r < 0)
2371 log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
2372 }
2373
2374 route->lifetime = lifetime;
2375 sd_event_source_unref(route->expire);
2376 route->expire = expire;
2377 expire = NULL;
f703cc2c
TG
2378 }
2379 }
2380
0bc70f1d
TG
2381 if (dhcp4_address) {
2382 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
2383 if (r < 0) {
2384 log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address);
2385 goto dhcp4_address_fail;
2386 }
2387
2388 r = sd_dhcp_client_new(&link->dhcp_client);
2389 if (r < 0)
2390 return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m");
2391
2392 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
2393 if (r < 0)
2394 return log_link_error_errno(link, r, "Falied to set inital DHCPv4 address %s: %m", dhcp4_address);
2395 }
2396
2397dhcp4_address_fail:
2398
2399 if (ipv4ll_address) {
2400 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
2401 if (r < 0) {
2402 log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address);
2403 goto ipv4ll_address_fail;
2404 }
2405
2406 r = sd_ipv4ll_new(&link->ipv4ll);
2407 if (r < 0)
2408 return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m");
2409
2410 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
2411 if (r < 0)
2412 return log_link_error_errno(link, r, "Falied to set inital IPv4LL address %s: %m", ipv4ll_address);
2413 }
2414
2415ipv4ll_address_fail:
2416
c4a03a56
TG
2417 return 0;
2418}
2419
1c4baffc 2420int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
505f8da7
TG
2421 Link *link;
2422 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2423 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2424 int r;
2425
2426 assert(m);
fbbeb65a 2427 assert(m->rtnl);
505f8da7
TG
2428 assert(message);
2429 assert(ret);
2430
2431 r = link_new(m, message, ret);
2432 if (r < 0)
2433 return r;
2434
2435 link = *ret;
2436
6a7a4e4d 2437 log_link_debug(link, "Link %d added", link->ifindex);
505f8da7 2438
c4a03a56
TG
2439 r = link_load(link);
2440 if (r < 0)
2441 return r;
2442
75f86906 2443 if (detect_container() <= 0) {
505f8da7 2444 /* not in a container, udev will be around */
ae06ab10 2445 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7 2446 device = udev_device_new_from_device_id(m->udev, ifindex_str);
5c416fc4
TG
2447 if (!device) {
2448 r = log_link_warning_errno(link, errno, "Could not find udev device: %m");
2449 goto failed;
2450 }
505f8da7 2451
3c4cb064 2452 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 2453 /* not yet ready */
79008bdd 2454 log_link_debug(link, "link pending udev initialization...");
505f8da7 2455 return 0;
3c4cb064 2456 }
505f8da7 2457
4f561e8e
TG
2458 r = link_initialized(link, device);
2459 if (r < 0)
5c416fc4 2460 goto failed;
4f561e8e 2461 } else {
5da8149f
TG
2462 /* we are calling a callback directly, so must take a ref */
2463 link_ref(link);
2464
4f561e8e
TG
2465 r = link_initialized_and_synced(m->rtnl, NULL, link);
2466 if (r < 0)
5c416fc4 2467 goto failed;
4f561e8e 2468 }
505f8da7 2469
a748b692 2470 return 0;
5c416fc4
TG
2471failed:
2472 link_enter_failed(link);
2473 return r;
a748b692
TG
2474}
2475
e7ab854c
TG
2476int link_ipv6ll_gained(Link *link) {
2477 int r;
2478
2479 assert(link);
2480
2481 log_link_info(link, "Gained IPv6LL");
2482
2483 link->ipv6ll_address = true;
2484 link_check_ready(link);
2485
a56a2048 2486 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
e7ab854c
TG
2487 r = link_acquire_ipv6_conf(link);
2488 if (r < 0) {
2489 link_enter_failed(link);
2490 return r;
2491 }
2492 }
2493
2494 return 0;
2495}
2496
9c0a72f9
TG
2497static int link_carrier_gained(Link *link) {
2498 int r;
2499
2500 assert(link);
2501
a56a2048 2502 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
9c0a72f9
TG
2503 r = link_acquire_conf(link);
2504 if (r < 0) {
2505 link_enter_failed(link);
2506 return r;
2507 }
2508 }
2509
0d4ad91d
AR
2510 r = link_handle_bound_by_list(link);
2511 if (r < 0)
2512 return r;
2513
9c0a72f9
TG
2514 return 0;
2515}
2516
2517static int link_carrier_lost(Link *link) {
2518 int r;
2519
2520 assert(link);
2521
2522 r = link_stop_clients(link);
2523 if (r < 0) {
2524 link_enter_failed(link);
2525 return r;
2526 }
2527
0d4ad91d
AR
2528 r = link_handle_bound_by_list(link);
2529 if (r < 0)
2530 return r;
2531
9c0a72f9
TG
2532 return 0;
2533}
2534
2535int link_carrier_reset(Link *link) {
2536 int r;
2537
2538 assert(link);
2539
2540 if (link_has_carrier(link)) {
2541 r = link_carrier_lost(link);
2542 if (r < 0)
2543 return r;
2544
2545 r = link_carrier_gained(link);
2546 if (r < 0)
2547 return r;
2548
6a7a4e4d 2549 log_link_info(link, "Reset carrier");
9c0a72f9
TG
2550 }
2551
2552 return 0;
2553}
2554
2555
1c4baffc 2556int link_update(Link *link, sd_netlink_message *m) {
c49b33ac 2557 struct ether_addr mac;
ca4e095a 2558 const char *ifname;
afe7fd56 2559 uint32_t mtu;
a61bb41c 2560 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
2561 int r;
2562
dd3efc09 2563 assert(link);
b8941f74 2564 assert(link->ifname);
22936833
TG
2565 assert(m);
2566
7619683b
TG
2567 if (link->state == LINK_STATE_LINGER) {
2568 link_ref(link);
6a7a4e4d 2569 log_link_info(link, "Link readded");
e331e246 2570 link_set_state(link, LINK_STATE_ENSLAVING);
0d4ad91d
AR
2571
2572 r = link_new_carrier_maps(link);
2573 if (r < 0)
2574 return r;
7619683b
TG
2575 }
2576
1c4baffc 2577 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
b8941f74 2578 if (r >= 0 && !streq(ifname, link->ifname)) {
6a7a4e4d 2579 log_link_info(link, "Renamed to %s", ifname);
b8941f74 2580
0d4ad91d
AR
2581 link_free_carrier_maps(link);
2582
2fc09a9c
DM
2583 r = free_and_strdup(&link->ifname, ifname);
2584 if (r < 0)
2585 return r;
0d4ad91d
AR
2586
2587 r = link_new_carrier_maps(link);
2588 if (r < 0)
2589 return r;
b8941f74
TG
2590 }
2591
1c4baffc 2592 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
afe7fd56
TG
2593 if (r >= 0 && mtu > 0) {
2594 link->mtu = mtu;
2595 if (!link->original_mtu) {
2596 link->original_mtu = mtu;
6a7a4e4d 2597 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
afe7fd56
TG
2598 }
2599
2600 if (link->dhcp_client) {
3c9b8860
TG
2601 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2602 link->mtu);
afe7fd56 2603 if (r < 0) {
6a7a4e4d 2604 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
afe7fd56
TG
2605 return r;
2606 }
2607 }
9842de0d 2608 }
69629de9 2609
e9189a1f
TG
2610 /* The kernel may broadcast NEWLINK messages without the MAC address
2611 set, simply ignore them. */
1c4baffc 2612 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 2613 if (r >= 0) {
3c9b8860
TG
2614 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2615 ETH_ALEN)) {
c49b33ac 2616
3c9b8860
TG
2617 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2618 ETH_ALEN);
c49b33ac 2619
79008bdd 2620 log_link_debug(link, "MAC address: "
20861203
TG
2621 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2622 mac.ether_addr_octet[0],
2623 mac.ether_addr_octet[1],
2624 mac.ether_addr_octet[2],
2625 mac.ether_addr_octet[3],
2626 mac.ether_addr_octet[4],
2627 mac.ether_addr_octet[5]);
c49b33ac 2628
20861203
TG
2629 if (link->ipv4ll) {
2630 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
6a7a4e4d
LP
2631 if (r < 0)
2632 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
c49b33ac 2633 }
c49b33ac 2634
20861203 2635 if (link->dhcp_client) {
3c9b8860 2636 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
2637 (const uint8_t *) &link->mac,
2638 sizeof (link->mac),
2639 ARPHRD_ETHER);
6a7a4e4d
LP
2640 if (r < 0)
2641 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
c49b33ac 2642 }
4138fb2c
PF
2643
2644 if (link->dhcp6_client) {
2645 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
2646 (const uint8_t *) &link->mac,
2647 sizeof (link->mac),
2648 ARPHRD_ETHER);
6a7a4e4d
LP
2649 if (r < 0)
2650 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
4138fb2c 2651 }
c49b33ac 2652 }
4f882b2a
TG
2653 }
2654
a61bb41c
TG
2655 had_carrier = link_has_carrier(link);
2656
2657 r = link_update_flags(link, m);
2658 if (r < 0)
2659 return r;
2660
2661 carrier_gained = !had_carrier && link_has_carrier(link);
2662 carrier_lost = had_carrier && !link_has_carrier(link);
2663
2664 if (carrier_gained) {
6a7a4e4d 2665 log_link_info(link, "Gained carrier");
a61bb41c 2666
9c0a72f9
TG
2667 r = link_carrier_gained(link);
2668 if (r < 0)
2669 return r;
a61bb41c 2670 } else if (carrier_lost) {
6a7a4e4d 2671 log_link_info(link, "Lost carrier");
a61bb41c 2672
9c0a72f9
TG
2673 r = link_carrier_lost(link);
2674 if (r < 0)
a61bb41c 2675 return r;
9c0a72f9 2676
a61bb41c
TG
2677 }
2678
2679 return 0;
dd3efc09 2680}
fe8db0c5
TG
2681
2682int link_save(Link *link) {
68a8723c 2683 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 2684 _cleanup_fclose_ FILE *f = NULL;
e375dcde 2685 const char *admin_state, *oper_state;
e7780c8d 2686 Address *a;
c1eb9872 2687 Route *route;
e7780c8d 2688 Iterator i;
fe8db0c5
TG
2689 int r;
2690
2691 assert(link);
2692 assert(link->state_file);
68a8723c 2693 assert(link->lease_file);
bbf7c048
TG
2694 assert(link->manager);
2695
370e9930
TG
2696 if (link->state == LINK_STATE_LINGER) {
2697 unlink(link->state_file);
2698 return 0;
2699 }
2700
deb2e523
TG
2701 admin_state = link_state_to_string(link->state);
2702 assert(admin_state);
2703
e375dcde
TG
2704 oper_state = link_operstate_to_string(link->operstate);
2705 assert(oper_state);
deb2e523 2706
fe8db0c5
TG
2707 r = fopen_temporary(link->state_file, &f, &temp_path);
2708 if (r < 0)
6a7a4e4d 2709 goto fail;
fe8db0c5
TG
2710
2711 fchmod(fileno(f), 0644);
2712
2713 fprintf(f,
2714 "# This is private data. Do not parse.\n"
deb2e523 2715 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
2716 "OPER_STATE=%s\n",
2717 admin_state, oper_state);
fe8db0c5 2718
bcb7a07e 2719 if (link->network) {
ea352b40
LP
2720 char **address, **domain;
2721 bool space;
07bdc70d
PF
2722 sd_dhcp6_lease *dhcp6_lease = NULL;
2723
2724 if (link->dhcp6_client) {
4058d339
TG
2725 r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
2726 if (r < 0 && r != -ENOMSG)
07bdc70d
PF
2727 log_link_debug(link, "No DHCPv6 lease");
2728 }
b0e39c82 2729
adc5b2e2
TG
2730 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2731
b0e39c82 2732 fputs("DNS=", f);
ea352b40
LP
2733 space = false;
2734 STRV_FOREACH(address, link->network->dns) {
2735 if (space)
2736 fputc(' ', f);
2737 fputs(*address, f);
2738 space = true;
2739 }
d5314fff 2740
b0e39c82
TG
2741 if (link->network->dhcp_dns &&
2742 link->dhcp_lease) {
2743 const struct in_addr *addresses;
2744
2745 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2746 if (r > 0) {
ea352b40
LP
2747 if (space)
2748 fputc(' ', f);
b0e39c82 2749 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2750 space = true;
2751 }
2752 }
2753
2754 if (link->network->dhcp_dns && dhcp6_lease) {
2755 struct in6_addr *in6_addrs;
2756
2757 r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
2758 if (r > 0) {
2759 if (space)
2760 fputc(' ', f);
2761 serialize_in6_addrs(f, in6_addrs, r);
b0e39c82
TG
2762 }
2763 }
2764
2ce40956 2765 fputc('\n', f);
b0e39c82 2766
2ce40956 2767 fputs("NTP=", f);
ea352b40
LP
2768 space = false;
2769 STRV_FOREACH(address, link->network->ntp) {
2770 if (space)
2771 fputc(' ', f);
2772 fputs(*address, f);
2773 space = true;
2774 }
d5314fff 2775
b0e39c82
TG
2776 if (link->network->dhcp_ntp &&
2777 link->dhcp_lease) {
2778 const struct in_addr *addresses;
2779
2780 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2781 if (r > 0) {
ea352b40
LP
2782 if (space)
2783 fputc(' ', f);
b0e39c82 2784 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2785 space = true;
2786 }
2787 }
2788
2789 if (link->network->dhcp_ntp && dhcp6_lease) {
2790 struct in6_addr *in6_addrs;
2791 char **hosts;
2792 char **hostname;
2793
2794 r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
2795 &in6_addrs);
2796 if (r > 0) {
2797 if (space)
2798 fputc(' ', f);
2799 serialize_in6_addrs(f, in6_addrs, r);
2800 space = true;
2801 }
2802
2803 r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
2804 if (r > 0) {
2805 STRV_FOREACH(hostname, hosts) {
2806 if (space)
2807 fputc(' ', f);
2808 fputs(*hostname, f);
2809 space = true;
2810 }
b0e39c82
TG
2811 }
2812 }
2813
2ce40956 2814 fputc('\n', f);
bd8f6538 2815
2ce40956 2816 fputs("DOMAINS=", f);
ea352b40
LP
2817 space = false;
2818 STRV_FOREACH(domain, link->network->domains) {
2819 if (space)
2820 fputc(' ', f);
2821 fputs(*domain, f);
2822 space = true;
2823 }
d5314fff 2824
ad0734e8 2825 if (link->network->dhcp_domains &&
9b4d1882
TG
2826 link->dhcp_lease) {
2827 const char *domainname;
2828
2829 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 2830 if (r >= 0) {
ea352b40
LP
2831 if (space)
2832 fputc(' ', f);
6192b846 2833 fputs(domainname, f);
07bdc70d
PF
2834 space = true;
2835 }
2836 }
2837
2838 if (link->network->dhcp_domains && dhcp6_lease) {
2839 char **domains;
2840
2841 r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
2842 if (r >= 0) {
2843 STRV_FOREACH(domain, domains) {
2844 if (space)
2845 fputc(' ', f);
2846 fputs(*domain, f);
2847 space = true;
2848 }
6192b846 2849 }
9b4d1882
TG
2850 }
2851
2ce40956 2852 fputc('\n', f);
6192b846 2853
67272d15
TG
2854 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2855 yes_no(link->network->wildcard_domain));
2856
3c9b8860 2857 fprintf(f, "LLMNR=%s\n",
a7e5da6e 2858 resolve_support_to_string(link->network->llmnr));
e7780c8d 2859
2ce40956 2860 fputs("ADDRESSES=", f);
e7780c8d
TG
2861 space = false;
2862 SET_FOREACH(a, link->addresses, i) {
2863 _cleanup_free_ char *address_str = NULL;
2864
2865 r = in_addr_to_string(a->family, &a->in_addr, &address_str);
2866 if (r < 0)
2867 goto fail;
2868
e7780c8d
TG
2869 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
2870 space = true;
2871 }
2872
2ce40956 2873 fputc('\n', f);
c1eb9872
TG
2874
2875 fputs("ROUTES=", f);
2876 space = false;
2877 SET_FOREACH(route, link->routes, i) {
2878 _cleanup_free_ char *route_str = NULL;
2879
2880 r = in_addr_to_string(route->family, &route->dst, &route_str);
2881 if (r < 0)
2882 goto fail;
2883
f833694d
TG
2884 fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
2885 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
c1eb9872
TG
2886 space = true;
2887 }
2888
2889 fputc('\n', f);
bcb7a07e 2890 }
7374f9d8 2891
0d4ad91d
AR
2892 if (!hashmap_isempty(link->bound_to_links)) {
2893 Link *carrier;
0d4ad91d
AR
2894 bool space = false;
2895
2896 fputs("CARRIER_BOUND_TO=", f);
2897 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2898 if (space)
2899 fputc(' ', f);
2900 fputs(carrier->ifname, f);
2901 space = true;
2902 }
2903
2ce40956 2904 fputc('\n', f);
0d4ad91d
AR
2905 }
2906
2907 if (!hashmap_isempty(link->bound_by_links)) {
2908 Link *carrier;
0d4ad91d
AR
2909 bool space = false;
2910
2911 fputs("CARRIER_BOUND_BY=", f);
0d4ad91d
AR
2912 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2913 if (space)
2914 fputc(' ', f);
2915 fputs(carrier->ifname, f);
2916 space = true;
2917 }
2918
2ce40956 2919 fputc('\n', f);
0d4ad91d
AR
2920 }
2921
8eb9058d 2922 if (link->dhcp_lease) {
0bc70f1d 2923 struct in_addr address;
8eb9058d
LP
2924 const char *tz = NULL;
2925
0bc70f1d
TG
2926 assert(link->network);
2927
8eb9058d
LP
2928 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
2929 if (r >= 0)
2930 fprintf(f, "TIMEZONE=%s\n", tz);
8eb9058d 2931
0bc70f1d
TG
2932 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
2933 if (r >= 0) {
2934 fputs("DHCP4_ADDRESS=", f);
2935 serialize_in_addrs(f, &address, 1);
2936 fputc('\n', f);
2937 }
d9876a52 2938
bd91b83e 2939 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2940 if (r < 0)
c2d6bd61 2941 goto fail;
fe8db0c5 2942
7374f9d8 2943 fprintf(f,
b0e39c82
TG
2944 "DHCP_LEASE=%s\n",
2945 link->lease_file);
deb2e523 2946 } else
68a8723c 2947 unlink(link->lease_file);
fe8db0c5 2948
0bc70f1d
TG
2949 if (link->ipv4ll) {
2950 struct in_addr address;
2951
2952 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
2953 if (r >= 0) {
2954 fputs("IPV4LL_ADDRESS=", f);
2955 serialize_in_addrs(f, &address, 1);
2956 fputc('\n', f);
2957 }
2958 }
2959
49699bac
SS
2960 if (link->lldp) {
2961 assert(link->network);
2962
2963 r = sd_lldp_save(link->lldp, link->lldp_file);
2964 if (r < 0)
2965 goto fail;
2966
2967 fprintf(f,
2968 "LLDP_FILE=%s\n",
2969 link->lldp_file);
2970 } else
2971 unlink(link->lldp_file);
2972
c2d6bd61
LP
2973 r = fflush_and_check(f);
2974 if (r < 0)
2975 goto fail;
fe8db0c5 2976
c2d6bd61 2977 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2978 r = -errno;
c2d6bd61 2979 goto fail;
fe8db0c5
TG
2980 }
2981
c2d6bd61 2982 return 0;
dacd6cee 2983
c2d6bd61 2984fail:
6a7a4e4d 2985 (void) unlink(link->state_file);
6a7a4e4d
LP
2986 if (temp_path)
2987 (void) unlink(temp_path);
2988
dacd6cee 2989 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
fe8db0c5
TG
2990}
2991
84de38c5
TG
2992/* The serialized state in /run is no longer up-to-date. */
2993void link_dirty(Link *link) {
2994 int r;
2995
2996 assert(link);
2997
2998 r = set_ensure_allocated(&link->manager->dirty_links, NULL);
2999 if (r < 0)
3000 /* allocation errors are ignored */
3001 return;
3002
3003 r = set_put(link->manager->dirty_links, link);
3004 if (r < 0)
3005 /* allocation errors are ignored */
3006 return;
3007
3008 link_ref(link);
3009}
3010
3011/* The serialized state in /run is up-to-date */
3012void link_clean(Link *link) {
3013 assert(link);
3014 assert(link->manager);
3015
3016 set_remove(link->manager->dirty_links, link);
3017 link_unref(link);
3018}
3019
fe8db0c5 3020static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 3021 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
3022 [LINK_STATE_ENSLAVING] = "configuring",
3023 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
3024 [LINK_STATE_SETTING_ROUTES] = "configuring",
3025 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 3026 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 3027 [LINK_STATE_FAILED] = "failed",
370e9930 3028 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
3029};
3030
3031DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
3032
3033static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
3034 [LINK_OPERSTATE_OFF] = "off",
3035 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
3036 [LINK_OPERSTATE_DORMANT] = "dormant",
3037 [LINK_OPERSTATE_CARRIER] = "carrier",
3038 [LINK_OPERSTATE_DEGRADED] = "degraded",
3039 [LINK_OPERSTATE_ROUTABLE] = "routable",
3040};
3041
3042DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);