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