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