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