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