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