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