]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
Merge pull request #2049 from evverx/journal-test-dont-run-on-incomplete-setup
[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 617 if (link_ipv6ll_enabled(link))
c601ebf7 618 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
e7ab854c
TG
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
fe307276
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);
c601ebf7 1263 assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
e7ab854c
TG
1264
1265 log_link_debug(link, "Acquiring DHCPv6 lease");
1266
c601ebf7
TG
1267 r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address);
1268 if (r < 0 && r != -EBUSY)
1269 return log_link_warning_errno(link, r, "Could not set IPv6LL address in DHCP client: %m");
1270
e7ab854c 1271 r = sd_dhcp6_client_start(link->dhcp6_client);
63348d13 1272 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1273 return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
1274 }
1275
1276 if (link_ipv6_accept_ra_enabled(link)) {
1277 assert(link->ndisc_router_discovery);
1278
1279 log_link_debug(link, "Discovering IPv6 routers");
1280
1281 r = sd_ndisc_router_discovery_start(link->ndisc_router_discovery);
63348d13 1282 if (r < 0 && r != -EBUSY)
e7ab854c
TG
1283 return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
1284 }
1285
1286 return 0;
1287}
1288
ff254138
TG
1289static int link_acquire_conf(Link *link) {
1290 int r;
1291
1292 assert(link);
1293 assert(link->network);
ff254138
TG
1294 assert(link->manager);
1295 assert(link->manager->event);
1296
78c958f8 1297 if (link_ipv4ll_enabled(link)) {
eb34d4af 1298 assert(link->ipv4ll);
ff254138 1299
6a7a4e4d 1300 log_link_debug(link, "Acquiring IPv4 link-local address");
5c1d3fc9
UTL
1301
1302 r = sd_ipv4ll_start(link->ipv4ll);
6a7a4e4d
LP
1303 if (r < 0)
1304 return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
5c1d3fc9
UTL
1305 }
1306
78c958f8 1307 if (link_dhcp4_enabled(link)) {
eb34d4af 1308 assert(link->dhcp_client);
ff254138 1309
6a7a4e4d 1310 log_link_debug(link, "Acquiring DHCPv4 lease");
ab47d620 1311
5c1d3fc9 1312 r = sd_dhcp_client_start(link->dhcp_client);
6a7a4e4d
LP
1313 if (r < 0)
1314 return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
5c1d3fc9 1315 }
ff254138 1316
ce43e484
SS
1317 if (link_lldp_enabled(link)) {
1318 assert(link->lldp);
1319
1320 log_link_debug(link, "Starting LLDP");
1321
1322 r = sd_lldp_start(link->lldp);
6a7a4e4d
LP
1323 if (r < 0)
1324 return log_link_warning_errno(link, r, "Could not start LLDP: %m");
ce43e484
SS
1325 }
1326
ff254138
TG
1327 return 0;
1328}
1329
a61bb41c 1330bool link_has_carrier(Link *link) {
deb2e523
TG
1331 /* see Documentation/networking/operstates.txt in the kernel sources */
1332
a61bb41c 1333 if (link->kernel_operstate == IF_OPER_UP)
deb2e523
TG
1334 return true;
1335
a61bb41c 1336 if (link->kernel_operstate == IF_OPER_UNKNOWN)
deb2e523 1337 /* operstate may not be implemented, so fall back to flags */
a61bb41c 1338 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
deb2e523
TG
1339 return true;
1340
1341 return false;
1342}
1343
1c4baffc 1344static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1345 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
1346 int r;
1347
1746cf2a
TG
1348 assert(link);
1349
5da8149f 1350 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
1351 return 1;
1352
1c4baffc 1353 r = sd_netlink_message_get_errno(m);
6a7a4e4d
LP
1354 if (r < 0)
1355 /* we warn but don't fail the link, as it may be
1356 brought up later */
a2fae7bb 1357 log_link_warning_errno(link, r, "Could not bring up interface: %m");
45ad2c13 1358
f882c247
TG
1359 return 1;
1360}
1361
1362static int link_up(Link *link) {
1c4baffc 1363 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
5c3072ea 1364 uint8_t ipv6ll_mode;
f579559b
TG
1365 int r;
1366
f882c247 1367 assert(link);
c106cc36 1368 assert(link->network);
f882c247
TG
1369 assert(link->manager);
1370 assert(link->manager->rtnl);
1371
6a7a4e4d 1372 log_link_debug(link, "Bringing link up");
449f7554 1373
6a7a4e4d
LP
1374 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
1375 if (r < 0)
1376 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
f579559b 1377
5d4795f3 1378 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
6a7a4e4d
LP
1379 if (r < 0)
1380 return log_link_error_errno(link, r, "Could not set link flags: %m");
fc25d7f8 1381
c106cc36 1382 if (link->network->mac) {
1c4baffc 1383 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
6a7a4e4d
LP
1384 if (r < 0)
1385 return log_link_error_errno(link, r, "Could not set MAC address: %m");
c106cc36
TG
1386 }
1387
1388 if (link->network->mtu) {
1c4baffc 1389 r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu);
6a7a4e4d
LP
1390 if (r < 0)
1391 return log_link_error_errno(link, r, "Could not set MTU: %m");
c106cc36
TG
1392 }
1393
1c4baffc 1394 r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
6a7a4e4d
LP
1395 if (r < 0)
1396 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
d0d6a4cd 1397
01d28f81
TG
1398 if (socket_ipv6_is_supported()) {
1399 /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
1c4baffc 1400 r = sd_netlink_message_open_container(req, AF_INET6);
01d28f81
TG
1401 if (r < 0)
1402 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
d0d6a4cd 1403
01d28f81 1404 ipv6ll_mode = link_ipv6ll_enabled(link) ? IN6_ADDR_GEN_MODE_EUI64 : IN6_ADDR_GEN_MODE_NONE;
1c4baffc 1405 r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
01d28f81
TG
1406 if (r < 0)
1407 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
d0d6a4cd 1408
01d28f81 1409 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1c4baffc 1410 r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
01d28f81
TG
1411 if (r < 0)
1412 return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
1413 }
1414
1c4baffc 1415 r = sd_netlink_message_close_container(req);
6a7a4e4d 1416 if (r < 0)
01d28f81 1417 return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
7f77697a 1418 }
d0d6a4cd 1419
1c4baffc 1420 r = sd_netlink_message_close_container(req);
6a7a4e4d
LP
1421 if (r < 0)
1422 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
d0d6a4cd 1423
1c4baffc 1424 r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
6a7a4e4d
LP
1425 if (r < 0)
1426 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
f579559b 1427
b226d99b
TG
1428 link_ref(link);
1429
f882c247
TG
1430 return 0;
1431}
1432
1c4baffc 1433static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
0d4ad91d
AR
1434 _cleanup_link_unref_ Link *link = userdata;
1435 int r;
1436
1437 assert(link);
1438
1439 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1440 return 1;
1441
1c4baffc 1442 r = sd_netlink_message_get_errno(m);
0d4ad91d 1443 if (r < 0)
a2fae7bb 1444 log_link_warning_errno(link, r, "Could not bring down interface: %m");
0d4ad91d
AR
1445
1446 return 1;
1447}
1448
1449static int link_down(Link *link) {
1c4baffc 1450 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
0d4ad91d
AR
1451 int r;
1452
1453 assert(link);
1454 assert(link->manager);
1455 assert(link->manager->rtnl);
1456
6a7a4e4d 1457 log_link_debug(link, "Bringing link down");
0d4ad91d
AR
1458
1459 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1460 RTM_SETLINK, link->ifindex);
6a7a4e4d
LP
1461 if (r < 0)
1462 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
0d4ad91d
AR
1463
1464 r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
6a7a4e4d
LP
1465 if (r < 0)
1466 return log_link_error_errno(link, r, "Could not set link flags: %m");
0d4ad91d 1467
1c4baffc 1468 r = sd_netlink_call_async(link->manager->rtnl, req, link_down_handler, link, 0, NULL);
6a7a4e4d
LP
1469 if (r < 0)
1470 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
0d4ad91d
AR
1471
1472 link_ref(link);
1473
1474 return 0;
1475}
1476
1477static int link_handle_bound_to_list(Link *link) {
1478 Link *l;
1479 Iterator i;
1480 int r;
1481 bool required_up = false;
1482 bool link_is_up = false;
1483
1484 assert(link);
1485
1486 if (hashmap_isempty(link->bound_to_links))
1487 return 0;
1488
1489 if (link->flags & IFF_UP)
1490 link_is_up = true;
1491
1492 HASHMAP_FOREACH (l, link->bound_to_links, i)
1493 if (link_has_carrier(l)) {
1494 required_up = true;
1495 break;
1496 }
1497
1498 if (!required_up && link_is_up) {
1499 r = link_down(link);
1500 if (r < 0)
1501 return r;
1502 } else if (required_up && !link_is_up) {
1503 r = link_up(link);
1504 if (r < 0)
1505 return r;
1506 }
1507
1508 return 0;
1509}
1510
1511static int link_handle_bound_by_list(Link *link) {
1512 Iterator i;
1513 Link *l;
1514 int r;
1515
1516 assert(link);
1517
1518 if (hashmap_isempty(link->bound_by_links))
1519 return 0;
1520
1521 HASHMAP_FOREACH (l, link->bound_by_links, i) {
1522 r = link_handle_bound_to_list(l);
1523 if (r < 0)
1524 return r;
1525 }
1526
1527 return 0;
1528}
1529
1530static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
1531 int r;
1532
1533 assert(link);
1534 assert(carrier);
1535
1536 if (link == carrier)
1537 return 0;
1538
1539 if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
1540 return 0;
1541
1542 r = hashmap_ensure_allocated(h, NULL);
1543 if (r < 0)
1544 return r;
1545
1546 r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
1547 if (r < 0)
1548 return r;
1549
1550 return 0;
1551}
1552
1553static int link_new_bound_by_list(Link *link) {
1554 Manager *m;
1555 Link *carrier;
1556 Iterator i;
1557 int r;
1558 bool list_updated = false;
1559
1560 assert(link);
1561 assert(link->manager);
1562
1563 m = link->manager;
1564
1565 HASHMAP_FOREACH (carrier, m->links, i) {
1566 if (!carrier->network)
1567 continue;
1568
1569 if (strv_isempty(carrier->network->bind_carrier))
1570 continue;
1571
1572 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
1573 r = link_put_carrier(link, carrier, &link->bound_by_links);
1574 if (r < 0)
1575 return r;
1576
1577 list_updated = true;
1578 }
1579 }
1580
1581 if (list_updated)
84de38c5 1582 link_dirty(link);
0d4ad91d
AR
1583
1584 HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
1585 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
1586 if (r < 0)
1587 return r;
1588
84de38c5 1589 link_dirty(carrier);
0d4ad91d
AR
1590 }
1591
1592 return 0;
1593}
1594
1595static int link_new_bound_to_list(Link *link) {
1596 Manager *m;
1597 Link *carrier;
1598 Iterator i;
1599 int r;
1600 bool list_updated = false;
1601
1602 assert(link);
1603 assert(link->manager);
1604
1605 if (!link->network)
1606 return 0;
1607
1608 if (strv_isempty(link->network->bind_carrier))
1609 return 0;
1610
1611 m = link->manager;
1612
1613 HASHMAP_FOREACH (carrier, m->links, i) {
1614 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
1615 r = link_put_carrier(link, carrier, &link->bound_to_links);
1616 if (r < 0)
1617 return r;
1618
1619 list_updated = true;
1620 }
1621 }
1622
1623 if (list_updated)
84de38c5 1624 link_dirty(link);
0d4ad91d
AR
1625
1626 HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
1627 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
1628 if (r < 0)
1629 return r;
1630
84de38c5 1631 link_dirty(carrier);
0d4ad91d
AR
1632 }
1633
1634 return 0;
1635}
1636
1637static int link_new_carrier_maps(Link *link) {
1638 int r;
1639
1640 r = link_new_bound_by_list(link);
1641 if (r < 0)
1642 return r;
1643
1644 r = link_handle_bound_by_list(link);
1645 if (r < 0)
1646 return r;
1647
1648 r = link_new_bound_to_list(link);
1649 if (r < 0)
1650 return r;
1651
1652 r = link_handle_bound_to_list(link);
1653 if (r < 0)
1654 return r;
1655
1656 return 0;
1657}
1658
1659static void link_free_bound_to_list(Link *link) {
1660 Link *bound_to;
1661 Iterator i;
1662
1663 HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
1664 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
1665
1666 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
84de38c5 1667 link_dirty(bound_to);
0d4ad91d
AR
1668 }
1669
1670 return;
1671}
1672
1673static void link_free_bound_by_list(Link *link) {
1674 Link *bound_by;
1675 Iterator i;
1676
1677 HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
1678 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
1679
1680 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
84de38c5 1681 link_dirty(bound_by);
0d4ad91d
AR
1682 link_handle_bound_to_list(bound_by);
1683 }
1684 }
1685
1686 return;
1687}
1688
1689static void link_free_carrier_maps(Link *link) {
1690 bool list_updated = false;
1691
1692 assert(link);
1693
1694 if (!hashmap_isempty(link->bound_to_links)) {
1695 link_free_bound_to_list(link);
1696 list_updated = true;
1697 }
1698
1699 if (!hashmap_isempty(link->bound_by_links)) {
1700 link_free_bound_by_list(link);
1701 list_updated = true;
1702 }
1703
1704 if (list_updated)
84de38c5 1705 link_dirty(link);
0d4ad91d
AR
1706
1707 return;
1708}
1709
1710void link_drop(Link *link) {
1711 if (!link || link->state == LINK_STATE_LINGER)
1712 return;
1713
1714 link_set_state(link, LINK_STATE_LINGER);
1715
1716 link_free_carrier_maps(link);
1717
6a7a4e4d 1718 log_link_debug(link, "Link removed");
0d4ad91d 1719
84de38c5 1720 (void)unlink(link->state_file);
0d4ad91d
AR
1721 link_unref(link);
1722
1723 return;
1724}
1725
3f265037 1726static int link_joined(Link *link) {
f882c247
TG
1727 int r;
1728
ef1ba606 1729 assert(link);
f5be5601 1730 assert(link->network);
dd3efc09 1731
0d4ad91d
AR
1732 if (!hashmap_isempty(link->bound_to_links)) {
1733 r = link_handle_bound_to_list(link);
1734 if (r < 0)
1735 return r;
1736 } else if (!(link->flags & IFF_UP)) {
505f8da7
TG
1737 r = link_up(link);
1738 if (r < 0) {
1739 link_enter_failed(link);
1740 return r;
1741 }
ef1ba606 1742 }
f882c247 1743
e1853b00
SS
1744 if(link->network->bridge) {
1745 r = link_set_bridge(link);
6a7a4e4d
LP
1746 if (r < 0)
1747 log_link_error_errno(link, r, "Could not set bridge message: %m");
e1853b00
SS
1748 }
1749
fb6730c4 1750 return link_enter_set_addresses(link);
02b59d57
TG
1751}
1752
62e2d5bb 1753static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
5da8149f 1754 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1755 int r;
1756
1746cf2a 1757 assert(link);
ef1ba606 1758 assert(link->network);
02b59d57 1759
52433f6b
TG
1760 link->enslaving --;
1761
5da8149f 1762 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1763 return 1;
1764
1c4baffc 1765 r = sd_netlink_message_get_errno(m);
856f962c 1766 if (r < 0 && r != -EEXIST) {
a2fae7bb 1767 log_link_error_errno(link, r, "Could not join netdev: %m");
ef1ba606
TG
1768 link_enter_failed(link);
1769 return 1;
ba179154 1770 } else
6a7a4e4d 1771 log_link_debug(link, "Joined netdev");
02b59d57 1772
856f962c 1773 if (link->enslaving <= 0)
3f265037 1774 link_joined(link);
02b59d57
TG
1775
1776 return 1;
1777}
1778
3f265037 1779static int link_enter_join_netdev(Link *link) {
6a0a2f86 1780 NetDev *netdev;
672682a6 1781 Iterator i;
02b59d57
TG
1782 int r;
1783
1784 assert(link);
1785 assert(link->network);
8434fd5c 1786 assert(link->state == LINK_STATE_PENDING);
02b59d57 1787
e331e246 1788 link_set_state(link, LINK_STATE_ENSLAVING);
02b59d57 1789
84de38c5 1790 link_dirty(link);
fe8db0c5 1791
7951dea2
SS
1792 if (!link->network->bridge &&
1793 !link->network->bond &&
6a0a2f86 1794 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1795 return link_joined(link);
02b59d57 1796
d9c67ea1 1797 if (link->network->bond) {
f2341e0a
LP
1798 log_struct(LOG_DEBUG,
1799 LOG_LINK_INTERFACE(link),
1800 LOG_NETDEV_INTERFACE(link->network->bond),
1801 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname),
1802 NULL);
1803
1804 r = netdev_join(link->network->bond, link, netdev_join_handler);
52433f6b 1805 if (r < 0) {
f2341e0a
LP
1806 log_struct_errno(LOG_WARNING, r,
1807 LOG_LINK_INTERFACE(link),
1808 LOG_NETDEV_INTERFACE(link->network->bond),
1809 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname),
1810 NULL);
1811
52433f6b
TG
1812 link_enter_failed(link);
1813 return r;
1814 }
1815
0ad6148e
MO
1816 link->enslaving ++;
1817 }
1818
d9c67ea1 1819 if (link->network->bridge) {
f2341e0a
LP
1820 log_struct(LOG_DEBUG,
1821 LOG_LINK_INTERFACE(link),
1822 LOG_NETDEV_INTERFACE(link->network->bridge),
1823 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname),
1824 NULL);
1825
1826 r = netdev_join(link->network->bridge, link, netdev_join_handler);
0ad6148e 1827 if (r < 0) {
f2341e0a
LP
1828 log_struct_errno(LOG_WARNING, r,
1829 LOG_LINK_INTERFACE(link),
1830 LOG_NETDEV_INTERFACE(link->network->bridge),
1831 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname),
1832 NULL),
0ad6148e
MO
1833 link_enter_failed(link);
1834 return r;
1835 }
1836
52433f6b
TG
1837 link->enslaving ++;
1838 }
1839
6a0a2f86 1840 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
7951dea2 1841
f2341e0a
LP
1842 log_struct(LOG_DEBUG,
1843 LOG_LINK_INTERFACE(link),
1844 LOG_NETDEV_INTERFACE(netdev),
1845 LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname),
1846 NULL);
1847
1848 r = netdev_join(netdev, link, netdev_join_handler);
7951dea2 1849 if (r < 0) {
f2341e0a
LP
1850 log_struct_errno(LOG_WARNING, r,
1851 LOG_LINK_INTERFACE(link),
1852 LOG_NETDEV_INTERFACE(netdev),
1853 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname),
1854 NULL);
326cb406
SS
1855 link_enter_failed(link);
1856 return r;
1857 }
1858
326cb406
SS
1859 link->enslaving ++;
1860 }
1861
ef1ba606
TG
1862 return 0;
1863}
1864
769d324c 1865static int link_set_ipv4_forward(Link *link) {
5a8bcb67
LP
1866 int r;
1867
765afd5c 1868 if (!link_ipv4_forward_enabled(link))
15dee3f0
LP
1869 return 0;
1870
765afd5c
LP
1871 /* We propagate the forwarding flag from one interface to the
1872 * global setting one way. This means: as long as at least one
1873 * interface was configured at any time that had IP forwarding
1874 * enabled the setting will stay on for good. We do this
1875 * primarily to keep IPv4 and IPv6 packet forwarding behaviour
1876 * somewhat in sync (see below). */
15dee3f0 1877
765afd5c 1878 r = write_string_file("/proc/sys/net/ipv4/ip_forward", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 1879 if (r < 0)
765afd5c 1880 log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
43c6d5ab 1881
769d324c
LP
1882 return 0;
1883}
1884
1885static int link_set_ipv6_forward(Link *link) {
769d324c
LP
1886 int r;
1887
765afd5c 1888 if (!link_ipv6_forward_enabled(link))
8add5f79
NO
1889 return 0;
1890
765afd5c
LP
1891 /* On Linux, the IPv6 stack does not not know a per-interface
1892 * packet forwarding setting: either packet forwarding is on
1893 * for all, or off for all. We hence don't bother with a
1894 * per-interface setting, but simply propagate the interface
1895 * flag, if it is set, to the global flag, one-way. Note that
1896 * while IPv4 would allow a per-interface flag, we expose the
1897 * same behaviour there and also propagate the setting from
1898 * one to all, to keep things simple (see above). */
15dee3f0 1899
765afd5c 1900 r = write_string_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 1901 if (r < 0)
765afd5c 1902 log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
5a8bcb67
LP
1903
1904 return 0;
1905}
1906
49092e22 1907static int link_set_ipv6_privacy_extensions(Link *link) {
1f0d9695
LP
1908 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1909 IPv6PrivacyExtensions s;
49092e22
SS
1910 const char *p = NULL;
1911 int r;
1912
1f0d9695 1913 s = link_ipv6_privacy_extensions(link);
66a6bd68 1914 if (s < 0)
49092e22
SS
1915 return 0;
1916
1917 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
66a6bd68 1918 xsprintf(buf, "%u", (unsigned) link->network->ipv6_privacy_extensions);
49092e22 1919
eb3da901
LP
1920 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1921 if (r < 0)
49092e22
SS
1922 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
1923
1924 return 0;
1925}
1926
4f2e437a 1927static int link_set_ipv6_accept_ra(Link *link) {
3b015d40 1928 const char *p = NULL;
4f2e437a
SS
1929 int r;
1930
1931 /* Make this a NOP if IPv6 is not available */
1932 if (!socket_ipv6_is_supported())
1933 return 0;
1934
1935 if (link->flags & IFF_LOOPBACK)
1936 return 0;
1937
d68e2e59
LP
1938 if (!link->network)
1939 return 0;
1940
4f2e437a 1941 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
4f2e437a 1942
fe307276
TG
1943 /* We handle router advertisments ourselves, tell the kernel to GTFO */
1944 r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
eb3da901 1945 if (r < 0)
fe307276 1946 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
4f2e437a
SS
1947
1948 return 0;
1949}
1950
8749cbcd 1951static int link_set_ipv6_dad_transmits(Link *link) {
66a6bd68 1952 char buf[DECIMAL_STR_MAX(int) + 1];
8749cbcd
SS
1953 const char *p = NULL;
1954 int r;
1955
1956 /* Make this a NOP if IPv6 is not available */
1957 if (!socket_ipv6_is_supported())
1958 return 0;
1959
1960 if (link->flags & IFF_LOOPBACK)
1961 return 0;
1962
d68e2e59
LP
1963 if (!link->network)
1964 return 0;
1965
8749cbcd
SS
1966 if (link->network->ipv6_dad_transmits < 0)
1967 return 0;
1968
1969 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
66a6bd68 1970 xsprintf(buf, "%i", link->network->ipv6_dad_transmits);
8749cbcd 1971
eb3da901
LP
1972 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1973 if (r < 0)
8749cbcd 1974 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
8749cbcd
SS
1975
1976 return 0;
1977}
1978
b69c3180 1979static int link_set_ipv6_hop_limit(Link *link) {
66a6bd68 1980 char buf[DECIMAL_STR_MAX(int) + 1];
b69c3180
SS
1981 const char *p = NULL;
1982 int r;
1983
1984 /* Make this a NOP if IPv6 is not available */
1985 if (!socket_ipv6_is_supported())
1986 return 0;
1987
1988 if (link->flags & IFF_LOOPBACK)
1989 return 0;
1990
d68e2e59
LP
1991 if (!link->network)
1992 return 0;
1993
b69c3180
SS
1994 if (link->network->ipv6_hop_limit < 0)
1995 return 0;
1996
1997 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
66a6bd68 1998 xsprintf(buf, "%i", link->network->ipv6_hop_limit);
b69c3180 1999
eb3da901
LP
2000 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
2001 if (r < 0)
b69c3180 2002 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
b69c3180
SS
2003
2004 return 0;
2005}
2006
5e5b137a
TG
2007static int link_drop_foreign_config(Link *link) {
2008 Address *address;
2009 Route *route;
2010 Iterator i;
2011 int r;
2012
2013 SET_FOREACH(address, link->addresses_foreign, i) {
fe307276 2014 /* we consider IPv6LL addresses to be managed by the kernel */
5e5b137a
TG
2015 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
2016 continue;
2017
2018 r = address_remove(address, link, link_address_remove_handler);
2019 if (r < 0)
2020 return r;
2021 }
2022
2023 SET_FOREACH(route, link->routes_foreign, i) {
fe307276 2024 /* do not touch routes managed by the kernel */
5e5b137a
TG
2025 if (route->protocol == RTPROT_KERNEL)
2026 continue;
2027
2028 r = route_remove(route, link, link_address_remove_handler);
2029 if (r < 0)
2030 return r;
2031 }
2032
2033 return 0;
2034}
2035
a748b692 2036static int link_configure(Link *link) {
02b59d57
TG
2037 int r;
2038
ef1ba606 2039 assert(link);
b22d8a00 2040 assert(link->network);
8434fd5c 2041 assert(link->state == LINK_STATE_PENDING);
a748b692 2042
e5d44b34
CH
2043 /* Drop foreign config, but ignore loopback device.
2044 * We do not want to remove loopback address. */
2045 if (!(link->flags & IFF_LOOPBACK)) {
2046 r = link_drop_foreign_config(link);
2047 if (r < 0)
2048 return r;
2049 }
5e5b137a 2050
b98b483b
AR
2051 r = link_set_bridge_fdb(link);
2052 if (r < 0)
2053 return r;
2054
769d324c
LP
2055 r = link_set_ipv4_forward(link);
2056 if (r < 0)
2057 return r;
2058
2059 r = link_set_ipv6_forward(link);
5a8bcb67
LP
2060 if (r < 0)
2061 return r;
2062
49092e22
SS
2063 r = link_set_ipv6_privacy_extensions(link);
2064 if (r < 0)
2065 return r;
2066
4f2e437a
SS
2067 r = link_set_ipv6_accept_ra(link);
2068 if (r < 0)
2069 return r;
2070
8749cbcd
SS
2071 r = link_set_ipv6_dad_transmits(link);
2072 if (r < 0)
2073 return r;
b69c3180
SS
2074
2075 r = link_set_ipv6_hop_limit(link);
2076 if (r < 0)
2077 return r;
8749cbcd 2078
78c958f8 2079 if (link_ipv4ll_enabled(link)) {
b22d8a00 2080 r = ipv4ll_configure(link);
eb34d4af
TG
2081 if (r < 0)
2082 return r;
2083 }
2084
78c958f8 2085 if (link_dhcp4_enabled(link)) {
3c9b8860 2086 r = dhcp4_configure(link);
eb34d4af
TG
2087 if (r < 0)
2088 return r;
eb34d4af
TG
2089 }
2090
78c958f8 2091 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
2092 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2093 if (r < 0)
2094 return r;
2095
2096 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2097 if (r < 0)
2098 return r;
dd43110f
TG
2099 }
2100
62379e88
TG
2101 if (link_dhcp6_enabled(link) ||
2102 link_ipv6_accept_ra_enabled(link)) {
f5a8c43f
TG
2103 r = dhcp6_configure(link);
2104 if (r < 0)
2105 return r;
2106 }
2107
2108 if (link_ipv6_accept_ra_enabled(link)) {
de1e9928 2109 r = ndisc_configure(link);
4138fb2c
PF
2110 if (r < 0)
2111 return r;
2112 }
2113
ce43e484
SS
2114 if (link_lldp_enabled(link)) {
2115 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
2116 if (r < 0)
2117 return r;
2118
2119 r = sd_lldp_attach_event(link->lldp, NULL, 0);
2120 if (r < 0)
2121 return r;
49699bac
SS
2122
2123 r = sd_lldp_set_callback(link->lldp,
2124 lldp_handler, link);
2125 if (r < 0)
2126 return r;
ce43e484
SS
2127 }
2128
a61bb41c 2129 if (link_has_carrier(link)) {
1e9be60b
TG
2130 r = link_acquire_conf(link);
2131 if (r < 0)
2132 return r;
e7ab854c 2133
c601ebf7 2134 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) == 0) {
e7ab854c
TG
2135 r = link_acquire_ipv6_conf(link);
2136 if (r < 0)
2137 return r;
2138 }
cc544d5f 2139 }
1e9be60b 2140
3f265037 2141 return link_enter_join_netdev(link);
505f8da7
TG
2142}
2143
1c4baffc 2144static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860 2145 void *userdata) {
5da8149f 2146 _cleanup_link_unref_ Link *link = userdata;
505f8da7 2147 Network *network;
505f8da7
TG
2148 int r;
2149
2150 assert(link);
2151 assert(link->ifname);
2152 assert(link->manager);
2153
8434fd5c 2154 if (link->state != LINK_STATE_PENDING)
5da8149f 2155 return 1;
505f8da7 2156
6a7a4e4d 2157 log_link_debug(link, "Link state is up-to-date");
505f8da7 2158
0d4ad91d
AR
2159 r = link_new_bound_by_list(link);
2160 if (r < 0)
2161 return r;
2162
2163 r = link_handle_bound_by_list(link);
2164 if (r < 0)
2165 return r;
2166
c4a03a56
TG
2167 if (!link->network) {
2168 r = network_get(link->manager, link->udev_device, link->ifname,
2169 &link->mac, &network);
2170 if (r == -ENOENT) {
2171 link_enter_unmanaged(link);
2172 return 1;
2173 } else if (r < 0)
2174 return r;
505f8da7 2175
c4a03a56
TG
2176 if (link->flags & IFF_LOOPBACK) {
2177 if (network->link_local != ADDRESS_FAMILY_NO)
2178 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
78c958f8 2179
c4a03a56
TG
2180 if (network->dhcp != ADDRESS_FAMILY_NO)
2181 log_link_debug(link, "Ignoring DHCP clients for loopback link");
78c958f8 2182
c4a03a56
TG
2183 if (network->dhcp_server)
2184 log_link_debug(link, "Ignoring DHCP server for loopback link");
2185 }
bd2efe92 2186
c4a03a56
TG
2187 r = network_apply(link->manager, network, link);
2188 if (r < 0)
2189 return r;
2190 }
505f8da7 2191
0d4ad91d
AR
2192 r = link_new_bound_to_list(link);
2193 if (r < 0)
2194 return r;
2195
a748b692
TG
2196 r = link_configure(link);
2197 if (r < 0)
2198 return r;
2199
5da8149f 2200 return 1;
505f8da7
TG
2201}
2202
4f561e8e 2203int link_initialized(Link *link, struct udev_device *device) {
1c4baffc 2204 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
4f561e8e
TG
2205 int r;
2206
2207 assert(link);
2208 assert(link->manager);
2209 assert(link->manager->rtnl);
2210 assert(device);
2211
8434fd5c 2212 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
2213 return 0;
2214
679b3605
TG
2215 if (link->udev_device)
2216 return 0;
2217
79008bdd 2218 log_link_debug(link, "udev initialized link");
4f561e8e
TG
2219
2220 link->udev_device = udev_device_ref(device);
2221
3c9b8860
TG
2222 /* udev has initialized the link, but we don't know if we have yet
2223 * processed the NEWLINK messages with the latest state. Do a GETLINK,
2224 * when it returns we know that the pending NEWLINKs have already been
2225 * processed and that we are up-to-date */
4f561e8e 2226
3c9b8860
TG
2227 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2228 link->ifindex);
4f561e8e
TG
2229 if (r < 0)
2230 return r;
2231
1c4baffc 2232 r = sd_netlink_call_async(link->manager->rtnl, req,
3c9b8860 2233 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
2234 if (r < 0)
2235 return r;
2236
5da8149f
TG
2237 link_ref(link);
2238
4f561e8e
TG
2239 return 0;
2240}
2241
c4a03a56 2242static int link_load(Link *link) {
0bc70f1d
TG
2243 _cleanup_free_ char *network_file = NULL,
2244 *addresses = NULL,
f703cc2c 2245 *routes = NULL,
0bc70f1d
TG
2246 *dhcp4_address = NULL,
2247 *ipv4ll_address = NULL;
2248 union in_addr_union address;
f703cc2c 2249 union in_addr_union route_dst;
c598ac76 2250 const char *p;
c4a03a56
TG
2251 int r;
2252
2253 assert(link);
2254
2255 r = parse_env_file(link->state_file, NEWLINE,
2256 "NETWORK_FILE", &network_file,
2257 "ADDRESSES", &addresses,
f703cc2c 2258 "ROUTES", &routes,
0bc70f1d
TG
2259 "DHCP4_ADDRESS", &dhcp4_address,
2260 "IPV4LL_ADDRESS", &ipv4ll_address,
c4a03a56
TG
2261 NULL);
2262 if (r < 0 && r != -ENOENT)
2263 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2264
2265 if (network_file) {
2266 Network *network;
2267 char *suffix;
2268
2269 /* drop suffix */
2270 suffix = strrchr(network_file, '.');
2271 if (!suffix) {
2272 log_link_debug(link, "Failed to get network name from %s", network_file);
2273 goto network_file_fail;
2274 }
2275 *suffix = '\0';
2276
2277 r = network_get_by_name(link->manager, basename(network_file), &network);
2278 if (r < 0) {
2279 log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2280 goto network_file_fail;
2281 }
2282
2283 r = network_apply(link->manager, network, link);
2284 if (r < 0)
2285 return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2286 }
2287
2288network_file_fail:
2289
2290 if (addresses) {
c598ac76 2291 p = addresses;
c4a03a56 2292
c598ac76
TG
2293 for (;;) {
2294 _cleanup_free_ char *address_str = NULL;
c4a03a56
TG
2295 char *prefixlen_str;
2296 int family;
2297 unsigned char prefixlen;
c4a03a56 2298
c598ac76
TG
2299 r = extract_first_word(&p, &address_str, NULL, 0);
2300 if (r < 0) {
2301 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2302 continue;
928bc597
TA
2303 }
2304 if (r == 0)
c598ac76
TG
2305 break;
2306
2307 prefixlen_str = strchr(address_str, '/');
c4a03a56 2308 if (!prefixlen_str) {
c598ac76 2309 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
c4a03a56
TG
2310 continue;
2311 }
2312
2313 *prefixlen_str ++ = '\0';
2314
2315 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
2316 if (r != 1) {
2317 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
2318 continue;
2319 }
2320
c598ac76 2321 r = in_addr_from_string_auto(address_str, &family, &address);
c4a03a56 2322 if (r < 0) {
c598ac76 2323 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
c4a03a56
TG
2324 continue;
2325 }
2326
2327 r = address_add(link, family, &address, prefixlen, NULL);
2328 if (r < 0)
2329 return log_link_error_errno(link, r, "Failed to add address: %m");
2330 }
2331 }
2332
f703cc2c 2333 if (routes) {
74544b4e
TA
2334 p = routes;
2335
c598ac76 2336 for (;;) {
f833694d 2337 Route *route;
c598ac76 2338 _cleanup_free_ char *route_str = NULL;
f833694d
TG
2339 _cleanup_event_source_unref_ sd_event_source *expire = NULL;
2340 usec_t lifetime;
f703cc2c
TG
2341 char *prefixlen_str;
2342 int family;
2343 unsigned char prefixlen, tos, table;
2344 uint32_t priority;
2345
c598ac76
TG
2346 r = extract_first_word(&p, &route_str, NULL, 0);
2347 if (r < 0) {
2348 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
2349 continue;
928bc597
TA
2350 }
2351 if (r == 0)
c598ac76
TG
2352 break;
2353
2354 prefixlen_str = strchr(route_str, '/');
f703cc2c 2355 if (!prefixlen_str) {
c598ac76 2356 log_link_debug(link, "Failed to parse route %s", route_str);
f703cc2c
TG
2357 continue;
2358 }
2359
2360 *prefixlen_str ++ = '\0';
2361
f833694d
TG
2362 r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
2363 if (r != 5) {
2364 log_link_debug(link,
2365 "Failed to parse destination prefix length, tos, priority, table or expiration %s",
2366 prefixlen_str);
f703cc2c
TG
2367 continue;
2368 }
2369
c598ac76 2370 r = in_addr_from_string_auto(route_str, &family, &route_dst);
f703cc2c 2371 if (r < 0) {
c598ac76 2372 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
f703cc2c
TG
2373 continue;
2374 }
2375
f833694d 2376 r = route_add(link, family, &route_dst, prefixlen, tos, priority, table, &route);
f703cc2c
TG
2377 if (r < 0)
2378 return log_link_error_errno(link, r, "Failed to add route: %m");
f833694d
TG
2379
2380 if (lifetime != USEC_INFINITY) {
2381 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
2382 0, route_expire_handler, route);
2383 if (r < 0)
2384 log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
2385 }
2386
2387 route->lifetime = lifetime;
2388 sd_event_source_unref(route->expire);
2389 route->expire = expire;
2390 expire = NULL;
f703cc2c
TG
2391 }
2392 }
2393
0bc70f1d
TG
2394 if (dhcp4_address) {
2395 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
2396 if (r < 0) {
2397 log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address);
2398 goto dhcp4_address_fail;
2399 }
2400
2401 r = sd_dhcp_client_new(&link->dhcp_client);
2402 if (r < 0)
2403 return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m");
2404
2405 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
2406 if (r < 0)
2407 return log_link_error_errno(link, r, "Falied to set inital DHCPv4 address %s: %m", dhcp4_address);
2408 }
2409
2410dhcp4_address_fail:
2411
2412 if (ipv4ll_address) {
2413 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
2414 if (r < 0) {
2415 log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address);
2416 goto ipv4ll_address_fail;
2417 }
2418
2419 r = sd_ipv4ll_new(&link->ipv4ll);
2420 if (r < 0)
2421 return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m");
2422
2423 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
2424 if (r < 0)
2425 return log_link_error_errno(link, r, "Falied to set inital IPv4LL address %s: %m", ipv4ll_address);
2426 }
2427
2428ipv4ll_address_fail:
2429
c4a03a56
TG
2430 return 0;
2431}
2432
1c4baffc 2433int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
505f8da7
TG
2434 Link *link;
2435 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2436 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2437 int r;
2438
2439 assert(m);
fbbeb65a 2440 assert(m->rtnl);
505f8da7
TG
2441 assert(message);
2442 assert(ret);
2443
2444 r = link_new(m, message, ret);
2445 if (r < 0)
2446 return r;
2447
2448 link = *ret;
2449
6a7a4e4d 2450 log_link_debug(link, "Link %d added", link->ifindex);
505f8da7 2451
c4a03a56
TG
2452 r = link_load(link);
2453 if (r < 0)
2454 return r;
2455
75f86906 2456 if (detect_container() <= 0) {
505f8da7 2457 /* not in a container, udev will be around */
ae06ab10 2458 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7 2459 device = udev_device_new_from_device_id(m->udev, ifindex_str);
5c416fc4
TG
2460 if (!device) {
2461 r = log_link_warning_errno(link, errno, "Could not find udev device: %m");
2462 goto failed;
2463 }
505f8da7 2464
3c4cb064 2465 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 2466 /* not yet ready */
79008bdd 2467 log_link_debug(link, "link pending udev initialization...");
505f8da7 2468 return 0;
3c4cb064 2469 }
505f8da7 2470
4f561e8e
TG
2471 r = link_initialized(link, device);
2472 if (r < 0)
5c416fc4 2473 goto failed;
4f561e8e 2474 } else {
5da8149f
TG
2475 /* we are calling a callback directly, so must take a ref */
2476 link_ref(link);
2477
4f561e8e
TG
2478 r = link_initialized_and_synced(m->rtnl, NULL, link);
2479 if (r < 0)
5c416fc4 2480 goto failed;
4f561e8e 2481 }
505f8da7 2482
a748b692 2483 return 0;
5c416fc4
TG
2484failed:
2485 link_enter_failed(link);
2486 return r;
a748b692
TG
2487}
2488
c601ebf7 2489int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
e7ab854c
TG
2490 int r;
2491
2492 assert(link);
2493
2494 log_link_info(link, "Gained IPv6LL");
2495
c601ebf7 2496 link->ipv6ll_address = *address;
e7ab854c
TG
2497 link_check_ready(link);
2498
a56a2048 2499 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
e7ab854c
TG
2500 r = link_acquire_ipv6_conf(link);
2501 if (r < 0) {
2502 link_enter_failed(link);
2503 return r;
2504 }
2505 }
2506
2507 return 0;
2508}
2509
9c0a72f9
TG
2510static int link_carrier_gained(Link *link) {
2511 int r;
2512
2513 assert(link);
2514
a56a2048 2515 if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_PENDING, LINK_STATE_UNMANAGED, LINK_STATE_FAILED)) {
9c0a72f9
TG
2516 r = link_acquire_conf(link);
2517 if (r < 0) {
2518 link_enter_failed(link);
2519 return r;
2520 }
2521 }
2522
0d4ad91d
AR
2523 r = link_handle_bound_by_list(link);
2524 if (r < 0)
2525 return r;
2526
9c0a72f9
TG
2527 return 0;
2528}
2529
2530static int link_carrier_lost(Link *link) {
2531 int r;
2532
2533 assert(link);
2534
2535 r = link_stop_clients(link);
2536 if (r < 0) {
2537 link_enter_failed(link);
2538 return r;
2539 }
2540
0d4ad91d
AR
2541 r = link_handle_bound_by_list(link);
2542 if (r < 0)
2543 return r;
2544
9c0a72f9
TG
2545 return 0;
2546}
2547
2548int link_carrier_reset(Link *link) {
2549 int r;
2550
2551 assert(link);
2552
2553 if (link_has_carrier(link)) {
2554 r = link_carrier_lost(link);
2555 if (r < 0)
2556 return r;
2557
2558 r = link_carrier_gained(link);
2559 if (r < 0)
2560 return r;
2561
6a7a4e4d 2562 log_link_info(link, "Reset carrier");
9c0a72f9
TG
2563 }
2564
2565 return 0;
2566}
2567
2568
1c4baffc 2569int link_update(Link *link, sd_netlink_message *m) {
c49b33ac 2570 struct ether_addr mac;
ca4e095a 2571 const char *ifname;
afe7fd56 2572 uint32_t mtu;
a61bb41c 2573 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
2574 int r;
2575
dd3efc09 2576 assert(link);
b8941f74 2577 assert(link->ifname);
22936833
TG
2578 assert(m);
2579
7619683b
TG
2580 if (link->state == LINK_STATE_LINGER) {
2581 link_ref(link);
6a7a4e4d 2582 log_link_info(link, "Link readded");
e331e246 2583 link_set_state(link, LINK_STATE_ENSLAVING);
0d4ad91d
AR
2584
2585 r = link_new_carrier_maps(link);
2586 if (r < 0)
2587 return r;
7619683b
TG
2588 }
2589
1c4baffc 2590 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
b8941f74 2591 if (r >= 0 && !streq(ifname, link->ifname)) {
6a7a4e4d 2592 log_link_info(link, "Renamed to %s", ifname);
b8941f74 2593
0d4ad91d
AR
2594 link_free_carrier_maps(link);
2595
2fc09a9c
DM
2596 r = free_and_strdup(&link->ifname, ifname);
2597 if (r < 0)
2598 return r;
0d4ad91d
AR
2599
2600 r = link_new_carrier_maps(link);
2601 if (r < 0)
2602 return r;
b8941f74
TG
2603 }
2604
1c4baffc 2605 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
afe7fd56
TG
2606 if (r >= 0 && mtu > 0) {
2607 link->mtu = mtu;
2608 if (!link->original_mtu) {
2609 link->original_mtu = mtu;
6a7a4e4d 2610 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
afe7fd56
TG
2611 }
2612
2613 if (link->dhcp_client) {
3c9b8860
TG
2614 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2615 link->mtu);
afe7fd56 2616 if (r < 0) {
6a7a4e4d 2617 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
afe7fd56
TG
2618 return r;
2619 }
2620 }
9842de0d 2621 }
69629de9 2622
e9189a1f
TG
2623 /* The kernel may broadcast NEWLINK messages without the MAC address
2624 set, simply ignore them. */
1c4baffc 2625 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 2626 if (r >= 0) {
3c9b8860
TG
2627 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2628 ETH_ALEN)) {
c49b33ac 2629
3c9b8860
TG
2630 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2631 ETH_ALEN);
c49b33ac 2632
79008bdd 2633 log_link_debug(link, "MAC address: "
20861203
TG
2634 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2635 mac.ether_addr_octet[0],
2636 mac.ether_addr_octet[1],
2637 mac.ether_addr_octet[2],
2638 mac.ether_addr_octet[3],
2639 mac.ether_addr_octet[4],
2640 mac.ether_addr_octet[5]);
c49b33ac 2641
20861203
TG
2642 if (link->ipv4ll) {
2643 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
6a7a4e4d
LP
2644 if (r < 0)
2645 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
c49b33ac 2646 }
c49b33ac 2647
20861203 2648 if (link->dhcp_client) {
3c9b8860 2649 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
2650 (const uint8_t *) &link->mac,
2651 sizeof (link->mac),
2652 ARPHRD_ETHER);
6a7a4e4d
LP
2653 if (r < 0)
2654 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
c49b33ac 2655 }
4138fb2c
PF
2656
2657 if (link->dhcp6_client) {
2658 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
2659 (const uint8_t *) &link->mac,
2660 sizeof (link->mac),
2661 ARPHRD_ETHER);
6a7a4e4d
LP
2662 if (r < 0)
2663 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
4138fb2c 2664 }
c49b33ac 2665 }
4f882b2a
TG
2666 }
2667
a61bb41c
TG
2668 had_carrier = link_has_carrier(link);
2669
2670 r = link_update_flags(link, m);
2671 if (r < 0)
2672 return r;
2673
2674 carrier_gained = !had_carrier && link_has_carrier(link);
2675 carrier_lost = had_carrier && !link_has_carrier(link);
2676
2677 if (carrier_gained) {
6a7a4e4d 2678 log_link_info(link, "Gained carrier");
a61bb41c 2679
9c0a72f9
TG
2680 r = link_carrier_gained(link);
2681 if (r < 0)
2682 return r;
a61bb41c 2683 } else if (carrier_lost) {
6a7a4e4d 2684 log_link_info(link, "Lost carrier");
a61bb41c 2685
9c0a72f9
TG
2686 r = link_carrier_lost(link);
2687 if (r < 0)
a61bb41c 2688 return r;
9c0a72f9 2689
a61bb41c
TG
2690 }
2691
2692 return 0;
dd3efc09 2693}
fe8db0c5
TG
2694
2695int link_save(Link *link) {
68a8723c 2696 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 2697 _cleanup_fclose_ FILE *f = NULL;
e375dcde 2698 const char *admin_state, *oper_state;
e7780c8d 2699 Address *a;
c1eb9872 2700 Route *route;
e7780c8d 2701 Iterator i;
fe8db0c5
TG
2702 int r;
2703
2704 assert(link);
2705 assert(link->state_file);
68a8723c 2706 assert(link->lease_file);
bbf7c048
TG
2707 assert(link->manager);
2708
370e9930
TG
2709 if (link->state == LINK_STATE_LINGER) {
2710 unlink(link->state_file);
2711 return 0;
2712 }
2713
deb2e523
TG
2714 admin_state = link_state_to_string(link->state);
2715 assert(admin_state);
2716
e375dcde
TG
2717 oper_state = link_operstate_to_string(link->operstate);
2718 assert(oper_state);
deb2e523 2719
fe8db0c5
TG
2720 r = fopen_temporary(link->state_file, &f, &temp_path);
2721 if (r < 0)
6a7a4e4d 2722 goto fail;
fe8db0c5
TG
2723
2724 fchmod(fileno(f), 0644);
2725
2726 fprintf(f,
2727 "# This is private data. Do not parse.\n"
deb2e523 2728 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
2729 "OPER_STATE=%s\n",
2730 admin_state, oper_state);
fe8db0c5 2731
bcb7a07e 2732 if (link->network) {
ea352b40
LP
2733 char **address, **domain;
2734 bool space;
07bdc70d
PF
2735 sd_dhcp6_lease *dhcp6_lease = NULL;
2736
2737 if (link->dhcp6_client) {
4058d339
TG
2738 r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
2739 if (r < 0 && r != -ENOMSG)
07bdc70d
PF
2740 log_link_debug(link, "No DHCPv6 lease");
2741 }
b0e39c82 2742
adc5b2e2
TG
2743 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2744
b0e39c82 2745 fputs("DNS=", f);
ea352b40
LP
2746 space = false;
2747 STRV_FOREACH(address, link->network->dns) {
2748 if (space)
2749 fputc(' ', f);
2750 fputs(*address, f);
2751 space = true;
2752 }
d5314fff 2753
b0e39c82
TG
2754 if (link->network->dhcp_dns &&
2755 link->dhcp_lease) {
2756 const struct in_addr *addresses;
2757
2758 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2759 if (r > 0) {
ea352b40
LP
2760 if (space)
2761 fputc(' ', f);
b0e39c82 2762 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2763 space = true;
2764 }
2765 }
2766
2767 if (link->network->dhcp_dns && dhcp6_lease) {
2768 struct in6_addr *in6_addrs;
2769
2770 r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
2771 if (r > 0) {
2772 if (space)
2773 fputc(' ', f);
2774 serialize_in6_addrs(f, in6_addrs, r);
b0e39c82
TG
2775 }
2776 }
2777
2ce40956 2778 fputc('\n', f);
b0e39c82 2779
2ce40956 2780 fputs("NTP=", f);
ea352b40
LP
2781 space = false;
2782 STRV_FOREACH(address, link->network->ntp) {
2783 if (space)
2784 fputc(' ', f);
2785 fputs(*address, f);
2786 space = true;
2787 }
d5314fff 2788
b0e39c82
TG
2789 if (link->network->dhcp_ntp &&
2790 link->dhcp_lease) {
2791 const struct in_addr *addresses;
2792
2793 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2794 if (r > 0) {
ea352b40
LP
2795 if (space)
2796 fputc(' ', f);
b0e39c82 2797 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2798 space = true;
2799 }
2800 }
2801
2802 if (link->network->dhcp_ntp && dhcp6_lease) {
2803 struct in6_addr *in6_addrs;
2804 char **hosts;
2805 char **hostname;
2806
2807 r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
2808 &in6_addrs);
2809 if (r > 0) {
2810 if (space)
2811 fputc(' ', f);
2812 serialize_in6_addrs(f, in6_addrs, r);
2813 space = true;
2814 }
2815
2816 r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
2817 if (r > 0) {
2818 STRV_FOREACH(hostname, hosts) {
2819 if (space)
2820 fputc(' ', f);
2821 fputs(*hostname, f);
2822 space = true;
2823 }
b0e39c82
TG
2824 }
2825 }
2826
2ce40956 2827 fputc('\n', f);
bd8f6538 2828
2ce40956 2829 fputs("DOMAINS=", f);
ea352b40
LP
2830 space = false;
2831 STRV_FOREACH(domain, link->network->domains) {
2832 if (space)
2833 fputc(' ', f);
2834 fputs(*domain, f);
2835 space = true;
2836 }
d5314fff 2837
ad0734e8 2838 if (link->network->dhcp_domains &&
9b4d1882
TG
2839 link->dhcp_lease) {
2840 const char *domainname;
2841
2842 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 2843 if (r >= 0) {
ea352b40
LP
2844 if (space)
2845 fputc(' ', f);
6192b846 2846 fputs(domainname, f);
07bdc70d
PF
2847 space = true;
2848 }
2849 }
2850
2851 if (link->network->dhcp_domains && dhcp6_lease) {
2852 char **domains;
2853
2854 r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
2855 if (r >= 0) {
2856 STRV_FOREACH(domain, domains) {
2857 if (space)
2858 fputc(' ', f);
2859 fputs(*domain, f);
2860 space = true;
2861 }
6192b846 2862 }
9b4d1882
TG
2863 }
2864
2ce40956 2865 fputc('\n', f);
6192b846 2866
67272d15
TG
2867 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2868 yes_no(link->network->wildcard_domain));
2869
3c9b8860 2870 fprintf(f, "LLMNR=%s\n",
a7e5da6e 2871 resolve_support_to_string(link->network->llmnr));
e7780c8d 2872
2ce40956 2873 fputs("ADDRESSES=", f);
e7780c8d
TG
2874 space = false;
2875 SET_FOREACH(a, link->addresses, i) {
2876 _cleanup_free_ char *address_str = NULL;
2877
2878 r = in_addr_to_string(a->family, &a->in_addr, &address_str);
2879 if (r < 0)
2880 goto fail;
2881
e7780c8d
TG
2882 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
2883 space = true;
2884 }
2885
2ce40956 2886 fputc('\n', f);
c1eb9872
TG
2887
2888 fputs("ROUTES=", f);
2889 space = false;
2890 SET_FOREACH(route, link->routes, i) {
2891 _cleanup_free_ char *route_str = NULL;
2892
2893 r = in_addr_to_string(route->family, &route->dst, &route_str);
2894 if (r < 0)
2895 goto fail;
2896
f833694d
TG
2897 fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
2898 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
c1eb9872
TG
2899 space = true;
2900 }
2901
2902 fputc('\n', f);
bcb7a07e 2903 }
7374f9d8 2904
0d4ad91d
AR
2905 if (!hashmap_isempty(link->bound_to_links)) {
2906 Link *carrier;
0d4ad91d
AR
2907 bool space = false;
2908
2909 fputs("CARRIER_BOUND_TO=", f);
2910 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2911 if (space)
2912 fputc(' ', f);
2913 fputs(carrier->ifname, f);
2914 space = true;
2915 }
2916
2ce40956 2917 fputc('\n', f);
0d4ad91d
AR
2918 }
2919
2920 if (!hashmap_isempty(link->bound_by_links)) {
2921 Link *carrier;
0d4ad91d
AR
2922 bool space = false;
2923
2924 fputs("CARRIER_BOUND_BY=", f);
0d4ad91d
AR
2925 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2926 if (space)
2927 fputc(' ', f);
2928 fputs(carrier->ifname, f);
2929 space = true;
2930 }
2931
2ce40956 2932 fputc('\n', f);
0d4ad91d
AR
2933 }
2934
8eb9058d 2935 if (link->dhcp_lease) {
0bc70f1d 2936 struct in_addr address;
8eb9058d
LP
2937 const char *tz = NULL;
2938
0bc70f1d
TG
2939 assert(link->network);
2940
8eb9058d
LP
2941 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
2942 if (r >= 0)
2943 fprintf(f, "TIMEZONE=%s\n", tz);
8eb9058d 2944
0bc70f1d
TG
2945 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
2946 if (r >= 0) {
2947 fputs("DHCP4_ADDRESS=", f);
2948 serialize_in_addrs(f, &address, 1);
2949 fputc('\n', f);
2950 }
d9876a52 2951
bd91b83e 2952 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2953 if (r < 0)
c2d6bd61 2954 goto fail;
fe8db0c5 2955
7374f9d8 2956 fprintf(f,
b0e39c82
TG
2957 "DHCP_LEASE=%s\n",
2958 link->lease_file);
deb2e523 2959 } else
68a8723c 2960 unlink(link->lease_file);
fe8db0c5 2961
0bc70f1d
TG
2962 if (link->ipv4ll) {
2963 struct in_addr address;
2964
2965 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
2966 if (r >= 0) {
2967 fputs("IPV4LL_ADDRESS=", f);
2968 serialize_in_addrs(f, &address, 1);
2969 fputc('\n', f);
2970 }
2971 }
2972
49699bac
SS
2973 if (link->lldp) {
2974 assert(link->network);
2975
2976 r = sd_lldp_save(link->lldp, link->lldp_file);
2977 if (r < 0)
2978 goto fail;
2979
2980 fprintf(f,
2981 "LLDP_FILE=%s\n",
2982 link->lldp_file);
2983 } else
2984 unlink(link->lldp_file);
2985
c2d6bd61
LP
2986 r = fflush_and_check(f);
2987 if (r < 0)
2988 goto fail;
fe8db0c5 2989
c2d6bd61 2990 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2991 r = -errno;
c2d6bd61 2992 goto fail;
fe8db0c5
TG
2993 }
2994
c2d6bd61 2995 return 0;
dacd6cee 2996
c2d6bd61 2997fail:
6a7a4e4d 2998 (void) unlink(link->state_file);
6a7a4e4d
LP
2999 if (temp_path)
3000 (void) unlink(temp_path);
3001
dacd6cee 3002 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
fe8db0c5
TG
3003}
3004
84de38c5
TG
3005/* The serialized state in /run is no longer up-to-date. */
3006void link_dirty(Link *link) {
3007 int r;
3008
3009 assert(link);
3010
3011 r = set_ensure_allocated(&link->manager->dirty_links, NULL);
3012 if (r < 0)
3013 /* allocation errors are ignored */
3014 return;
3015
3016 r = set_put(link->manager->dirty_links, link);
3017 if (r < 0)
3018 /* allocation errors are ignored */
3019 return;
3020
3021 link_ref(link);
3022}
3023
3024/* The serialized state in /run is up-to-date */
3025void link_clean(Link *link) {
3026 assert(link);
3027 assert(link->manager);
3028
3029 set_remove(link->manager->dirty_links, link);
3030 link_unref(link);
3031}
3032
fe8db0c5 3033static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 3034 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
3035 [LINK_STATE_ENSLAVING] = "configuring",
3036 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
3037 [LINK_STATE_SETTING_ROUTES] = "configuring",
3038 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 3039 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 3040 [LINK_STATE_FAILED] = "failed",
370e9930 3041 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
3042};
3043
3044DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
3045
3046static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
3047 [LINK_OPERSTATE_OFF] = "off",
3048 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
3049 [LINK_OPERSTATE_DORMANT] = "dormant",
3050 [LINK_OPERSTATE_CARRIER] = "carrier",
3051 [LINK_OPERSTATE_DEGRADED] = "degraded",
3052 [LINK_OPERSTATE_ROUTABLE] = "routable",
3053};
3054
3055DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);