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