]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
util-lib: optionally, when writing a string to a file, verify string on failure
[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
eb3da901
LP
1862 r = write_string_file(p, v, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1863 if (r < 0)
43c6d5ab
LP
1864 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
1865
769d324c
LP
1866 return 0;
1867}
1868
1869static int link_set_ipv6_forward(Link *link) {
15dee3f0 1870 const char *p = NULL, *v = NULL;
769d324c
LP
1871 int r;
1872
fe027299
LP
1873 /* Make this a NOP if IPv6 is not available */
1874 if (!socket_ipv6_is_supported())
1875 return 0;
1876
15dee3f0
LP
1877 if (link->flags & IFF_LOOPBACK)
1878 return 0;
1879
8add5f79
NO
1880 if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
1881 return 0;
1882
63c372cb 1883 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
15dee3f0
LP
1884 v = one_zero(link_ipv6_forward_enabled(link));
1885
eb3da901
LP
1886 r = write_string_file(p, v, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1887 if (r < 0)
769d324c 1888 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
5a8bcb67
LP
1889
1890 return 0;
1891}
1892
49092e22 1893static int link_set_ipv6_privacy_extensions(Link *link) {
1f0d9695
LP
1894 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1895 IPv6PrivacyExtensions s;
49092e22
SS
1896 const char *p = NULL;
1897 int r;
1898
1899 /* Make this a NOP if IPv6 is not available */
1900 if (!socket_ipv6_is_supported())
1901 return 0;
1902
1f0d9695
LP
1903 s = link_ipv6_privacy_extensions(link);
1904 if (s == _IPV6_PRIVACY_EXTENSIONS_INVALID)
49092e22
SS
1905 return 0;
1906
1907 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
1908 xsprintf(buf, "%u", link->network->ipv6_privacy_extensions);
1909
eb3da901
LP
1910 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1911 if (r < 0)
49092e22
SS
1912 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
1913
1914 return 0;
1915}
1916
4f2e437a 1917static int link_set_ipv6_accept_ra(Link *link) {
3b015d40 1918 const char *p = NULL;
4f2e437a
SS
1919 int r;
1920
1921 /* Make this a NOP if IPv6 is not available */
1922 if (!socket_ipv6_is_supported())
1923 return 0;
1924
1925 if (link->flags & IFF_LOOPBACK)
1926 return 0;
1927
4f2e437a 1928 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra");
4f2e437a 1929
3b015d40 1930 /* we handle router advertisments ourselves, tell the kernel to GTFO */
eb3da901
LP
1931 r = write_string_file(p, "0", WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1932 if (r < 0)
3b015d40 1933 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
4f2e437a
SS
1934
1935 return 0;
1936}
1937
8749cbcd
SS
1938static int link_set_ipv6_dad_transmits(Link *link) {
1939 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1940 const char *p = NULL;
1941 int r;
1942
1943 /* Make this a NOP if IPv6 is not available */
1944 if (!socket_ipv6_is_supported())
1945 return 0;
1946
1947 if (link->flags & IFF_LOOPBACK)
1948 return 0;
1949
1950 if (link->network->ipv6_dad_transmits < 0)
1951 return 0;
1952
1953 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/dad_transmits");
1954
1955 xsprintf(buf, "%u", link->network->ipv6_dad_transmits);
1956
eb3da901
LP
1957 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1958 if (r < 0)
8749cbcd 1959 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
8749cbcd
SS
1960
1961 return 0;
1962}
1963
b69c3180
SS
1964static int link_set_ipv6_hop_limit(Link *link) {
1965 char buf[DECIMAL_STR_MAX(unsigned) + 1];
1966 const char *p = NULL;
1967 int r;
1968
1969 /* Make this a NOP if IPv6 is not available */
1970 if (!socket_ipv6_is_supported())
1971 return 0;
1972
1973 if (link->flags & IFF_LOOPBACK)
1974 return 0;
1975
1976 if (link->network->ipv6_hop_limit < 0)
1977 return 0;
1978
1979 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit");
1980
1981 xsprintf(buf, "%u", link->network->ipv6_hop_limit);
1982
eb3da901
LP
1983 r = write_string_file(p, buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE);
1984 if (r < 0)
b69c3180 1985 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
b69c3180
SS
1986
1987 return 0;
1988}
1989
5e5b137a
TG
1990static int link_drop_foreign_config(Link *link) {
1991 Address *address;
1992 Route *route;
1993 Iterator i;
1994 int r;
1995
1996 SET_FOREACH(address, link->addresses_foreign, i) {
1997 /* we consider IPv6LL addresses to be managed by the kernel */
1998 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
1999 continue;
2000
2001 r = address_remove(address, link, link_address_remove_handler);
2002 if (r < 0)
2003 return r;
2004 }
2005
2006 SET_FOREACH(route, link->routes_foreign, i) {
2007 /* do not touch routes managed by the kernel */
2008 if (route->protocol == RTPROT_KERNEL)
2009 continue;
2010
2011 r = route_remove(route, link, link_address_remove_handler);
2012 if (r < 0)
2013 return r;
2014 }
2015
2016 return 0;
2017}
2018
a748b692 2019static int link_configure(Link *link) {
02b59d57
TG
2020 int r;
2021
ef1ba606 2022 assert(link);
b22d8a00 2023 assert(link->network);
8434fd5c 2024 assert(link->state == LINK_STATE_PENDING);
a748b692 2025
5e5b137a
TG
2026 r = link_drop_foreign_config(link);
2027 if (r < 0)
2028 return r;
2029
b98b483b
AR
2030 r = link_set_bridge_fdb(link);
2031 if (r < 0)
2032 return r;
2033
769d324c
LP
2034 r = link_set_ipv4_forward(link);
2035 if (r < 0)
2036 return r;
2037
2038 r = link_set_ipv6_forward(link);
5a8bcb67
LP
2039 if (r < 0)
2040 return r;
2041
49092e22
SS
2042 r = link_set_ipv6_privacy_extensions(link);
2043 if (r < 0)
2044 return r;
2045
4f2e437a
SS
2046 r = link_set_ipv6_accept_ra(link);
2047 if (r < 0)
2048 return r;
2049
8749cbcd
SS
2050 r = link_set_ipv6_dad_transmits(link);
2051 if (r < 0)
2052 return r;
b69c3180
SS
2053
2054 r = link_set_ipv6_hop_limit(link);
2055 if (r < 0)
2056 return r;
8749cbcd 2057
78c958f8 2058 if (link_ipv4ll_enabled(link)) {
b22d8a00 2059 r = ipv4ll_configure(link);
eb34d4af
TG
2060 if (r < 0)
2061 return r;
2062 }
2063
78c958f8 2064 if (link_dhcp4_enabled(link)) {
3c9b8860 2065 r = dhcp4_configure(link);
eb34d4af
TG
2066 if (r < 0)
2067 return r;
eb34d4af
TG
2068 }
2069
78c958f8 2070 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
2071 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
2072 if (r < 0)
2073 return r;
2074
2075 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
2076 if (r < 0)
2077 return r;
dd43110f
TG
2078 }
2079
78c958f8 2080 if (link_dhcp6_enabled(link)) {
f5a8c43f
TG
2081 r = dhcp6_configure(link);
2082 if (r < 0)
2083 return r;
2084 }
2085
2086 if (link_ipv6_accept_ra_enabled(link)) {
de1e9928 2087 r = ndisc_configure(link);
4138fb2c
PF
2088 if (r < 0)
2089 return r;
2090 }
2091
ce43e484
SS
2092 if (link_lldp_enabled(link)) {
2093 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
2094 if (r < 0)
2095 return r;
2096
2097 r = sd_lldp_attach_event(link->lldp, NULL, 0);
2098 if (r < 0)
2099 return r;
49699bac
SS
2100
2101 r = sd_lldp_set_callback(link->lldp,
2102 lldp_handler, link);
2103 if (r < 0)
2104 return r;
ce43e484
SS
2105 }
2106
a61bb41c 2107 if (link_has_carrier(link)) {
1e9be60b
TG
2108 r = link_acquire_conf(link);
2109 if (r < 0)
2110 return r;
e7ab854c
TG
2111
2112 if (link->ipv6ll_address) {
2113 r = link_acquire_ipv6_conf(link);
2114 if (r < 0)
2115 return r;
2116 }
cc544d5f 2117 }
1e9be60b 2118
3f265037 2119 return link_enter_join_netdev(link);
505f8da7
TG
2120}
2121
1c4baffc 2122static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
3c9b8860 2123 void *userdata) {
5da8149f 2124 _cleanup_link_unref_ Link *link = userdata;
505f8da7 2125 Network *network;
505f8da7
TG
2126 int r;
2127
2128 assert(link);
2129 assert(link->ifname);
2130 assert(link->manager);
2131
8434fd5c 2132 if (link->state != LINK_STATE_PENDING)
5da8149f 2133 return 1;
505f8da7 2134
6a7a4e4d 2135 log_link_debug(link, "Link state is up-to-date");
505f8da7 2136
0d4ad91d
AR
2137 r = link_new_bound_by_list(link);
2138 if (r < 0)
2139 return r;
2140
2141 r = link_handle_bound_by_list(link);
2142 if (r < 0)
2143 return r;
2144
c4a03a56
TG
2145 if (!link->network) {
2146 r = network_get(link->manager, link->udev_device, link->ifname,
2147 &link->mac, &network);
2148 if (r == -ENOENT) {
2149 link_enter_unmanaged(link);
2150 return 1;
2151 } else if (r < 0)
2152 return r;
505f8da7 2153
c4a03a56
TG
2154 if (link->flags & IFF_LOOPBACK) {
2155 if (network->link_local != ADDRESS_FAMILY_NO)
2156 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
78c958f8 2157
c4a03a56
TG
2158 if (network->dhcp != ADDRESS_FAMILY_NO)
2159 log_link_debug(link, "Ignoring DHCP clients for loopback link");
78c958f8 2160
c4a03a56
TG
2161 if (network->dhcp_server)
2162 log_link_debug(link, "Ignoring DHCP server for loopback link");
2163 }
bd2efe92 2164
c4a03a56
TG
2165 r = network_apply(link->manager, network, link);
2166 if (r < 0)
2167 return r;
2168 }
505f8da7 2169
0d4ad91d
AR
2170 r = link_new_bound_to_list(link);
2171 if (r < 0)
2172 return r;
2173
a748b692
TG
2174 r = link_configure(link);
2175 if (r < 0)
2176 return r;
2177
5da8149f 2178 return 1;
505f8da7
TG
2179}
2180
4f561e8e 2181int link_initialized(Link *link, struct udev_device *device) {
1c4baffc 2182 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL;
4f561e8e
TG
2183 int r;
2184
2185 assert(link);
2186 assert(link->manager);
2187 assert(link->manager->rtnl);
2188 assert(device);
2189
8434fd5c 2190 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
2191 return 0;
2192
679b3605
TG
2193 if (link->udev_device)
2194 return 0;
2195
79008bdd 2196 log_link_debug(link, "udev initialized link");
4f561e8e
TG
2197
2198 link->udev_device = udev_device_ref(device);
2199
3c9b8860
TG
2200 /* udev has initialized the link, but we don't know if we have yet
2201 * processed the NEWLINK messages with the latest state. Do a GETLINK,
2202 * when it returns we know that the pending NEWLINKs have already been
2203 * processed and that we are up-to-date */
4f561e8e 2204
3c9b8860
TG
2205 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
2206 link->ifindex);
4f561e8e
TG
2207 if (r < 0)
2208 return r;
2209
1c4baffc 2210 r = sd_netlink_call_async(link->manager->rtnl, req,
3c9b8860 2211 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
2212 if (r < 0)
2213 return r;
2214
5da8149f
TG
2215 link_ref(link);
2216
4f561e8e
TG
2217 return 0;
2218}
2219
c4a03a56 2220static int link_load(Link *link) {
0bc70f1d
TG
2221 _cleanup_free_ char *network_file = NULL,
2222 *addresses = NULL,
f703cc2c 2223 *routes = NULL,
0bc70f1d
TG
2224 *dhcp4_address = NULL,
2225 *ipv4ll_address = NULL;
2226 union in_addr_union address;
f703cc2c 2227 union in_addr_union route_dst;
c598ac76 2228 const char *p;
c4a03a56
TG
2229 int r;
2230
2231 assert(link);
2232
2233 r = parse_env_file(link->state_file, NEWLINE,
2234 "NETWORK_FILE", &network_file,
2235 "ADDRESSES", &addresses,
f703cc2c 2236 "ROUTES", &routes,
0bc70f1d
TG
2237 "DHCP4_ADDRESS", &dhcp4_address,
2238 "IPV4LL_ADDRESS", &ipv4ll_address,
c4a03a56
TG
2239 NULL);
2240 if (r < 0 && r != -ENOENT)
2241 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
2242
2243 if (network_file) {
2244 Network *network;
2245 char *suffix;
2246
2247 /* drop suffix */
2248 suffix = strrchr(network_file, '.');
2249 if (!suffix) {
2250 log_link_debug(link, "Failed to get network name from %s", network_file);
2251 goto network_file_fail;
2252 }
2253 *suffix = '\0';
2254
2255 r = network_get_by_name(link->manager, basename(network_file), &network);
2256 if (r < 0) {
2257 log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
2258 goto network_file_fail;
2259 }
2260
2261 r = network_apply(link->manager, network, link);
2262 if (r < 0)
2263 return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
2264 }
2265
2266network_file_fail:
2267
2268 if (addresses) {
c598ac76 2269 p = addresses;
c4a03a56 2270
c598ac76
TG
2271 for (;;) {
2272 _cleanup_free_ char *address_str = NULL;
c4a03a56
TG
2273 char *prefixlen_str;
2274 int family;
2275 unsigned char prefixlen;
c4a03a56 2276
c598ac76
TG
2277 r = extract_first_word(&p, &address_str, NULL, 0);
2278 if (r < 0) {
2279 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
2280 continue;
2281 } if (r == 0)
2282 break;
2283
2284 prefixlen_str = strchr(address_str, '/');
c4a03a56 2285 if (!prefixlen_str) {
c598ac76 2286 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
c4a03a56
TG
2287 continue;
2288 }
2289
2290 *prefixlen_str ++ = '\0';
2291
2292 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
2293 if (r != 1) {
2294 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
2295 continue;
2296 }
2297
c598ac76 2298 r = in_addr_from_string_auto(address_str, &family, &address);
c4a03a56 2299 if (r < 0) {
c598ac76 2300 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
c4a03a56
TG
2301 continue;
2302 }
2303
2304 r = address_add(link, family, &address, prefixlen, NULL);
2305 if (r < 0)
2306 return log_link_error_errno(link, r, "Failed to add address: %m");
2307 }
2308 }
2309
f703cc2c 2310 if (routes) {
c598ac76 2311 for (;;) {
f833694d 2312 Route *route;
c598ac76 2313 _cleanup_free_ char *route_str = NULL;
f833694d
TG
2314 _cleanup_event_source_unref_ sd_event_source *expire = NULL;
2315 usec_t lifetime;
f703cc2c
TG
2316 char *prefixlen_str;
2317 int family;
2318 unsigned char prefixlen, tos, table;
2319 uint32_t priority;
2320
c598ac76
TG
2321 r = extract_first_word(&p, &route_str, NULL, 0);
2322 if (r < 0) {
2323 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
2324 continue;
2325 } if (r == 0)
2326 break;
2327
2328 prefixlen_str = strchr(route_str, '/');
f703cc2c 2329 if (!prefixlen_str) {
c598ac76 2330 log_link_debug(link, "Failed to parse route %s", route_str);
f703cc2c
TG
2331 continue;
2332 }
2333
2334 *prefixlen_str ++ = '\0';
2335
f833694d
TG
2336 r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
2337 if (r != 5) {
2338 log_link_debug(link,
2339 "Failed to parse destination prefix length, tos, priority, table or expiration %s",
2340 prefixlen_str);
f703cc2c
TG
2341 continue;
2342 }
2343
c598ac76 2344 r = in_addr_from_string_auto(route_str, &family, &route_dst);
f703cc2c 2345 if (r < 0) {
c598ac76 2346 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
f703cc2c
TG
2347 continue;
2348 }
2349
f833694d 2350 r = route_add(link, family, &route_dst, prefixlen, tos, priority, table, &route);
f703cc2c
TG
2351 if (r < 0)
2352 return log_link_error_errno(link, r, "Failed to add route: %m");
f833694d
TG
2353
2354 if (lifetime != USEC_INFINITY) {
2355 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
2356 0, route_expire_handler, route);
2357 if (r < 0)
2358 log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
2359 }
2360
2361 route->lifetime = lifetime;
2362 sd_event_source_unref(route->expire);
2363 route->expire = expire;
2364 expire = NULL;
f703cc2c
TG
2365 }
2366 }
2367
0bc70f1d
TG
2368 if (dhcp4_address) {
2369 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
2370 if (r < 0) {
2371 log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address);
2372 goto dhcp4_address_fail;
2373 }
2374
2375 r = sd_dhcp_client_new(&link->dhcp_client);
2376 if (r < 0)
2377 return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m");
2378
2379 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
2380 if (r < 0)
2381 return log_link_error_errno(link, r, "Falied to set inital DHCPv4 address %s: %m", dhcp4_address);
2382 }
2383
2384dhcp4_address_fail:
2385
2386 if (ipv4ll_address) {
2387 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
2388 if (r < 0) {
2389 log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address);
2390 goto ipv4ll_address_fail;
2391 }
2392
2393 r = sd_ipv4ll_new(&link->ipv4ll);
2394 if (r < 0)
2395 return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m");
2396
2397 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
2398 if (r < 0)
2399 return log_link_error_errno(link, r, "Falied to set inital IPv4LL address %s: %m", ipv4ll_address);
2400 }
2401
2402ipv4ll_address_fail:
2403
c4a03a56
TG
2404 return 0;
2405}
2406
1c4baffc 2407int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
505f8da7
TG
2408 Link *link;
2409 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2410 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2411 int r;
2412
2413 assert(m);
fbbeb65a 2414 assert(m->rtnl);
505f8da7
TG
2415 assert(message);
2416 assert(ret);
2417
2418 r = link_new(m, message, ret);
2419 if (r < 0)
2420 return r;
2421
2422 link = *ret;
2423
6a7a4e4d 2424 log_link_debug(link, "Link %d added", link->ifindex);
505f8da7 2425
c4a03a56
TG
2426 r = link_load(link);
2427 if (r < 0)
2428 return r;
2429
75f86906 2430 if (detect_container() <= 0) {
505f8da7 2431 /* not in a container, udev will be around */
ae06ab10 2432 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7 2433 device = udev_device_new_from_device_id(m->udev, ifindex_str);
5c416fc4
TG
2434 if (!device) {
2435 r = log_link_warning_errno(link, errno, "Could not find udev device: %m");
2436 goto failed;
2437 }
505f8da7 2438
3c4cb064 2439 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 2440 /* not yet ready */
79008bdd 2441 log_link_debug(link, "link pending udev initialization...");
505f8da7 2442 return 0;
3c4cb064 2443 }
505f8da7 2444
4f561e8e
TG
2445 r = link_initialized(link, device);
2446 if (r < 0)
5c416fc4 2447 goto failed;
4f561e8e 2448 } else {
5da8149f
TG
2449 /* we are calling a callback directly, so must take a ref */
2450 link_ref(link);
2451
4f561e8e
TG
2452 r = link_initialized_and_synced(m->rtnl, NULL, link);
2453 if (r < 0)
5c416fc4 2454 goto failed;
4f561e8e 2455 }
505f8da7 2456
a748b692 2457 return 0;
5c416fc4
TG
2458failed:
2459 link_enter_failed(link);
2460 return r;
a748b692
TG
2461}
2462
e7ab854c
TG
2463int link_ipv6ll_gained(Link *link) {
2464 int r;
2465
2466 assert(link);
2467
2468 log_link_info(link, "Gained IPv6LL");
2469
2470 link->ipv6ll_address = true;
2471 link_check_ready(link);
2472
2473 if (link->network) {
2474 r = link_acquire_ipv6_conf(link);
2475 if (r < 0) {
2476 link_enter_failed(link);
2477 return r;
2478 }
2479 }
2480
2481 return 0;
2482}
2483
9c0a72f9
TG
2484static int link_carrier_gained(Link *link) {
2485 int r;
2486
2487 assert(link);
2488
2489 if (link->network) {
2490 r = link_acquire_conf(link);
2491 if (r < 0) {
2492 link_enter_failed(link);
2493 return r;
2494 }
2495 }
2496
0d4ad91d
AR
2497 r = link_handle_bound_by_list(link);
2498 if (r < 0)
2499 return r;
2500
9c0a72f9
TG
2501 return 0;
2502}
2503
2504static int link_carrier_lost(Link *link) {
2505 int r;
2506
2507 assert(link);
2508
2509 r = link_stop_clients(link);
2510 if (r < 0) {
2511 link_enter_failed(link);
2512 return r;
2513 }
2514
0d4ad91d
AR
2515 r = link_handle_bound_by_list(link);
2516 if (r < 0)
2517 return r;
2518
9c0a72f9
TG
2519 return 0;
2520}
2521
2522int link_carrier_reset(Link *link) {
2523 int r;
2524
2525 assert(link);
2526
2527 if (link_has_carrier(link)) {
2528 r = link_carrier_lost(link);
2529 if (r < 0)
2530 return r;
2531
2532 r = link_carrier_gained(link);
2533 if (r < 0)
2534 return r;
2535
6a7a4e4d 2536 log_link_info(link, "Reset carrier");
9c0a72f9
TG
2537 }
2538
2539 return 0;
2540}
2541
2542
1c4baffc 2543int link_update(Link *link, sd_netlink_message *m) {
c49b33ac 2544 struct ether_addr mac;
ca4e095a 2545 const char *ifname;
afe7fd56 2546 uint32_t mtu;
a61bb41c 2547 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
2548 int r;
2549
dd3efc09 2550 assert(link);
b8941f74 2551 assert(link->ifname);
22936833
TG
2552 assert(m);
2553
7619683b
TG
2554 if (link->state == LINK_STATE_LINGER) {
2555 link_ref(link);
6a7a4e4d 2556 log_link_info(link, "Link readded");
e331e246 2557 link_set_state(link, LINK_STATE_ENSLAVING);
0d4ad91d
AR
2558
2559 r = link_new_carrier_maps(link);
2560 if (r < 0)
2561 return r;
7619683b
TG
2562 }
2563
1c4baffc 2564 r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
b8941f74 2565 if (r >= 0 && !streq(ifname, link->ifname)) {
6a7a4e4d 2566 log_link_info(link, "Renamed to %s", ifname);
b8941f74 2567
0d4ad91d
AR
2568 link_free_carrier_maps(link);
2569
2fc09a9c
DM
2570 r = free_and_strdup(&link->ifname, ifname);
2571 if (r < 0)
2572 return r;
0d4ad91d
AR
2573
2574 r = link_new_carrier_maps(link);
2575 if (r < 0)
2576 return r;
b8941f74
TG
2577 }
2578
1c4baffc 2579 r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
afe7fd56
TG
2580 if (r >= 0 && mtu > 0) {
2581 link->mtu = mtu;
2582 if (!link->original_mtu) {
2583 link->original_mtu = mtu;
6a7a4e4d 2584 log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
afe7fd56
TG
2585 }
2586
2587 if (link->dhcp_client) {
3c9b8860
TG
2588 r = sd_dhcp_client_set_mtu(link->dhcp_client,
2589 link->mtu);
afe7fd56 2590 if (r < 0) {
6a7a4e4d 2591 log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
afe7fd56
TG
2592 return r;
2593 }
2594 }
9842de0d 2595 }
69629de9 2596
e9189a1f
TG
2597 /* The kernel may broadcast NEWLINK messages without the MAC address
2598 set, simply ignore them. */
1c4baffc 2599 r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 2600 if (r >= 0) {
3c9b8860
TG
2601 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
2602 ETH_ALEN)) {
c49b33ac 2603
3c9b8860
TG
2604 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
2605 ETH_ALEN);
c49b33ac 2606
79008bdd 2607 log_link_debug(link, "MAC address: "
20861203
TG
2608 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2609 mac.ether_addr_octet[0],
2610 mac.ether_addr_octet[1],
2611 mac.ether_addr_octet[2],
2612 mac.ether_addr_octet[3],
2613 mac.ether_addr_octet[4],
2614 mac.ether_addr_octet[5]);
c49b33ac 2615
20861203
TG
2616 if (link->ipv4ll) {
2617 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
6a7a4e4d
LP
2618 if (r < 0)
2619 return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
c49b33ac 2620 }
c49b33ac 2621
20861203 2622 if (link->dhcp_client) {
3c9b8860 2623 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
2624 (const uint8_t *) &link->mac,
2625 sizeof (link->mac),
2626 ARPHRD_ETHER);
6a7a4e4d
LP
2627 if (r < 0)
2628 return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
c49b33ac 2629 }
4138fb2c
PF
2630
2631 if (link->dhcp6_client) {
2632 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
2633 (const uint8_t *) &link->mac,
2634 sizeof (link->mac),
2635 ARPHRD_ETHER);
6a7a4e4d
LP
2636 if (r < 0)
2637 return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
4138fb2c 2638 }
c49b33ac 2639 }
4f882b2a
TG
2640 }
2641
a61bb41c
TG
2642 had_carrier = link_has_carrier(link);
2643
2644 r = link_update_flags(link, m);
2645 if (r < 0)
2646 return r;
2647
2648 carrier_gained = !had_carrier && link_has_carrier(link);
2649 carrier_lost = had_carrier && !link_has_carrier(link);
2650
2651 if (carrier_gained) {
6a7a4e4d 2652 log_link_info(link, "Gained carrier");
a61bb41c 2653
9c0a72f9
TG
2654 r = link_carrier_gained(link);
2655 if (r < 0)
2656 return r;
a61bb41c 2657 } else if (carrier_lost) {
6a7a4e4d 2658 log_link_info(link, "Lost carrier");
a61bb41c 2659
9c0a72f9
TG
2660 r = link_carrier_lost(link);
2661 if (r < 0)
a61bb41c 2662 return r;
9c0a72f9 2663
a61bb41c
TG
2664 }
2665
2666 return 0;
dd3efc09 2667}
fe8db0c5
TG
2668
2669int link_save(Link *link) {
68a8723c 2670 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 2671 _cleanup_fclose_ FILE *f = NULL;
e375dcde 2672 const char *admin_state, *oper_state;
e7780c8d 2673 Address *a;
c1eb9872 2674 Route *route;
e7780c8d 2675 Iterator i;
fe8db0c5
TG
2676 int r;
2677
2678 assert(link);
2679 assert(link->state_file);
68a8723c 2680 assert(link->lease_file);
bbf7c048
TG
2681 assert(link->manager);
2682
370e9930
TG
2683 if (link->state == LINK_STATE_LINGER) {
2684 unlink(link->state_file);
2685 return 0;
2686 }
2687
deb2e523
TG
2688 admin_state = link_state_to_string(link->state);
2689 assert(admin_state);
2690
e375dcde
TG
2691 oper_state = link_operstate_to_string(link->operstate);
2692 assert(oper_state);
deb2e523 2693
fe8db0c5
TG
2694 r = fopen_temporary(link->state_file, &f, &temp_path);
2695 if (r < 0)
6a7a4e4d 2696 goto fail;
fe8db0c5
TG
2697
2698 fchmod(fileno(f), 0644);
2699
2700 fprintf(f,
2701 "# This is private data. Do not parse.\n"
deb2e523 2702 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
2703 "OPER_STATE=%s\n",
2704 admin_state, oper_state);
fe8db0c5 2705
bcb7a07e 2706 if (link->network) {
ea352b40
LP
2707 char **address, **domain;
2708 bool space;
07bdc70d
PF
2709 sd_dhcp6_lease *dhcp6_lease = NULL;
2710
2711 if (link->dhcp6_client) {
4058d339
TG
2712 r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
2713 if (r < 0 && r != -ENOMSG)
07bdc70d
PF
2714 log_link_debug(link, "No DHCPv6 lease");
2715 }
b0e39c82 2716
adc5b2e2
TG
2717 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
2718
b0e39c82 2719 fputs("DNS=", f);
ea352b40
LP
2720 space = false;
2721 STRV_FOREACH(address, link->network->dns) {
2722 if (space)
2723 fputc(' ', f);
2724 fputs(*address, f);
2725 space = true;
2726 }
d5314fff 2727
b0e39c82
TG
2728 if (link->network->dhcp_dns &&
2729 link->dhcp_lease) {
2730 const struct in_addr *addresses;
2731
2732 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2733 if (r > 0) {
ea352b40
LP
2734 if (space)
2735 fputc(' ', f);
b0e39c82 2736 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2737 space = true;
2738 }
2739 }
2740
2741 if (link->network->dhcp_dns && dhcp6_lease) {
2742 struct in6_addr *in6_addrs;
2743
2744 r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
2745 if (r > 0) {
2746 if (space)
2747 fputc(' ', f);
2748 serialize_in6_addrs(f, in6_addrs, r);
b0e39c82
TG
2749 }
2750 }
2751
2ce40956 2752 fputc('\n', f);
b0e39c82 2753
2ce40956 2754 fputs("NTP=", f);
ea352b40
LP
2755 space = false;
2756 STRV_FOREACH(address, link->network->ntp) {
2757 if (space)
2758 fputc(' ', f);
2759 fputs(*address, f);
2760 space = true;
2761 }
d5314fff 2762
b0e39c82
TG
2763 if (link->network->dhcp_ntp &&
2764 link->dhcp_lease) {
2765 const struct in_addr *addresses;
2766
2767 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2768 if (r > 0) {
ea352b40
LP
2769 if (space)
2770 fputc(' ', f);
b0e39c82 2771 serialize_in_addrs(f, addresses, r);
07bdc70d
PF
2772 space = true;
2773 }
2774 }
2775
2776 if (link->network->dhcp_ntp && dhcp6_lease) {
2777 struct in6_addr *in6_addrs;
2778 char **hosts;
2779 char **hostname;
2780
2781 r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
2782 &in6_addrs);
2783 if (r > 0) {
2784 if (space)
2785 fputc(' ', f);
2786 serialize_in6_addrs(f, in6_addrs, r);
2787 space = true;
2788 }
2789
2790 r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
2791 if (r > 0) {
2792 STRV_FOREACH(hostname, hosts) {
2793 if (space)
2794 fputc(' ', f);
2795 fputs(*hostname, f);
2796 space = true;
2797 }
b0e39c82
TG
2798 }
2799 }
2800
2ce40956 2801 fputc('\n', f);
bd8f6538 2802
2ce40956 2803 fputs("DOMAINS=", f);
ea352b40
LP
2804 space = false;
2805 STRV_FOREACH(domain, link->network->domains) {
2806 if (space)
2807 fputc(' ', f);
2808 fputs(*domain, f);
2809 space = true;
2810 }
d5314fff 2811
ad0734e8 2812 if (link->network->dhcp_domains &&
9b4d1882
TG
2813 link->dhcp_lease) {
2814 const char *domainname;
2815
2816 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 2817 if (r >= 0) {
ea352b40
LP
2818 if (space)
2819 fputc(' ', f);
6192b846 2820 fputs(domainname, f);
07bdc70d
PF
2821 space = true;
2822 }
2823 }
2824
2825 if (link->network->dhcp_domains && dhcp6_lease) {
2826 char **domains;
2827
2828 r = sd_dhcp6_lease_get_domains(dhcp6_lease, &domains);
2829 if (r >= 0) {
2830 STRV_FOREACH(domain, domains) {
2831 if (space)
2832 fputc(' ', f);
2833 fputs(*domain, f);
2834 space = true;
2835 }
6192b846 2836 }
9b4d1882
TG
2837 }
2838
2ce40956 2839 fputc('\n', f);
6192b846 2840
67272d15
TG
2841 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2842 yes_no(link->network->wildcard_domain));
2843
3c9b8860 2844 fprintf(f, "LLMNR=%s\n",
a7e5da6e 2845 resolve_support_to_string(link->network->llmnr));
e7780c8d 2846
2ce40956 2847 fputs("ADDRESSES=", f);
e7780c8d
TG
2848 space = false;
2849 SET_FOREACH(a, link->addresses, i) {
2850 _cleanup_free_ char *address_str = NULL;
2851
2852 r = in_addr_to_string(a->family, &a->in_addr, &address_str);
2853 if (r < 0)
2854 goto fail;
2855
e7780c8d
TG
2856 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
2857 space = true;
2858 }
2859
2ce40956 2860 fputc('\n', f);
c1eb9872
TG
2861
2862 fputs("ROUTES=", f);
2863 space = false;
2864 SET_FOREACH(route, link->routes, i) {
2865 _cleanup_free_ char *route_str = NULL;
2866
2867 r = in_addr_to_string(route->family, &route->dst, &route_str);
2868 if (r < 0)
2869 goto fail;
2870
f833694d
TG
2871 fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str,
2872 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
c1eb9872
TG
2873 space = true;
2874 }
2875
2876 fputc('\n', f);
bcb7a07e 2877 }
7374f9d8 2878
0d4ad91d
AR
2879 if (!hashmap_isempty(link->bound_to_links)) {
2880 Link *carrier;
0d4ad91d
AR
2881 bool space = false;
2882
2883 fputs("CARRIER_BOUND_TO=", f);
2884 HASHMAP_FOREACH(carrier, link->bound_to_links, i) {
2885 if (space)
2886 fputc(' ', f);
2887 fputs(carrier->ifname, f);
2888 space = true;
2889 }
2890
2ce40956 2891 fputc('\n', f);
0d4ad91d
AR
2892 }
2893
2894 if (!hashmap_isempty(link->bound_by_links)) {
2895 Link *carrier;
0d4ad91d
AR
2896 bool space = false;
2897
2898 fputs("CARRIER_BOUND_BY=", f);
0d4ad91d
AR
2899 HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
2900 if (space)
2901 fputc(' ', f);
2902 fputs(carrier->ifname, f);
2903 space = true;
2904 }
2905
2ce40956 2906 fputc('\n', f);
0d4ad91d
AR
2907 }
2908
8eb9058d 2909 if (link->dhcp_lease) {
0bc70f1d 2910 struct in_addr address;
8eb9058d
LP
2911 const char *tz = NULL;
2912
0bc70f1d
TG
2913 assert(link->network);
2914
8eb9058d
LP
2915 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
2916 if (r >= 0)
2917 fprintf(f, "TIMEZONE=%s\n", tz);
8eb9058d 2918
0bc70f1d
TG
2919 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
2920 if (r >= 0) {
2921 fputs("DHCP4_ADDRESS=", f);
2922 serialize_in_addrs(f, &address, 1);
2923 fputc('\n', f);
2924 }
d9876a52 2925
bd91b83e 2926 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2927 if (r < 0)
c2d6bd61 2928 goto fail;
fe8db0c5 2929
7374f9d8 2930 fprintf(f,
b0e39c82
TG
2931 "DHCP_LEASE=%s\n",
2932 link->lease_file);
deb2e523 2933 } else
68a8723c 2934 unlink(link->lease_file);
fe8db0c5 2935
0bc70f1d
TG
2936 if (link->ipv4ll) {
2937 struct in_addr address;
2938
2939 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
2940 if (r >= 0) {
2941 fputs("IPV4LL_ADDRESS=", f);
2942 serialize_in_addrs(f, &address, 1);
2943 fputc('\n', f);
2944 }
2945 }
2946
49699bac
SS
2947 if (link->lldp) {
2948 assert(link->network);
2949
2950 r = sd_lldp_save(link->lldp, link->lldp_file);
2951 if (r < 0)
2952 goto fail;
2953
2954 fprintf(f,
2955 "LLDP_FILE=%s\n",
2956 link->lldp_file);
2957 } else
2958 unlink(link->lldp_file);
2959
c2d6bd61
LP
2960 r = fflush_and_check(f);
2961 if (r < 0)
2962 goto fail;
fe8db0c5 2963
c2d6bd61 2964 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2965 r = -errno;
c2d6bd61 2966 goto fail;
fe8db0c5
TG
2967 }
2968
c2d6bd61 2969 return 0;
dacd6cee 2970
c2d6bd61 2971fail:
6a7a4e4d 2972 (void) unlink(link->state_file);
6a7a4e4d
LP
2973 if (temp_path)
2974 (void) unlink(temp_path);
2975
dacd6cee 2976 return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
fe8db0c5
TG
2977}
2978
84de38c5
TG
2979/* The serialized state in /run is no longer up-to-date. */
2980void link_dirty(Link *link) {
2981 int r;
2982
2983 assert(link);
2984
2985 r = set_ensure_allocated(&link->manager->dirty_links, NULL);
2986 if (r < 0)
2987 /* allocation errors are ignored */
2988 return;
2989
2990 r = set_put(link->manager->dirty_links, link);
2991 if (r < 0)
2992 /* allocation errors are ignored */
2993 return;
2994
2995 link_ref(link);
2996}
2997
2998/* The serialized state in /run is up-to-date */
2999void link_clean(Link *link) {
3000 assert(link);
3001 assert(link->manager);
3002
3003 set_remove(link->manager->dirty_links, link);
3004 link_unref(link);
3005}
3006
fe8db0c5 3007static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 3008 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
3009 [LINK_STATE_ENSLAVING] = "configuring",
3010 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
3011 [LINK_STATE_SETTING_ROUTES] = "configuring",
3012 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 3013 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 3014 [LINK_STATE_FAILED] = "failed",
370e9930 3015 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
3016};
3017
3018DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
3019
3020static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
3021 [LINK_OPERSTATE_OFF] = "off",
3022 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
3023 [LINK_OPERSTATE_DORMANT] = "dormant",
3024 [LINK_OPERSTATE_CARRIER] = "carrier",
3025 [LINK_OPERSTATE_DEGRADED] = "degraded",
3026 [LINK_OPERSTATE_ROUTABLE] = "routable",
3027};
3028
3029DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);