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