]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
networkd: don't unlink state files on exit
[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"
1346b1f0 29#include "bus-util.h"
5a8bcb67
LP
30#include "udev-util.h"
31#include "libudev-private.h"
c6f7c917 32#include "network-internal.h"
5a8bcb67
LP
33#include "networkd-link.h"
34#include "networkd-netdev.h"
ed942a9e 35#include "conf-parser.h"
fe8db0c5
TG
36#include "dhcp-lease-internal.h"
37
78c958f8
TG
38static bool link_dhcp6_enabled(Link *link) {
39 if (link->flags & IFF_LOOPBACK)
40 return false;
41
42 if (!link->network)
43 return false;
44
cb9fc36a 45 return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
78c958f8
TG
46}
47
48static bool link_dhcp4_enabled(Link *link) {
49 if (link->flags & IFF_LOOPBACK)
50 return false;
51
52 if (!link->network)
53 return false;
54
cb9fc36a 55 return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
78c958f8
TG
56}
57
58static bool link_dhcp4_server_enabled(Link *link) {
59 if (link->flags & IFF_LOOPBACK)
60 return false;
61
62 if (!link->network)
63 return false;
64
65 return link->network->dhcp_server;
66}
67
68static bool link_ipv4ll_enabled(Link *link) {
69 if (link->flags & IFF_LOOPBACK)
70 return false;
71
72 if (!link->network)
73 return false;
74
75 return link->network->ipv4ll;
76}
77
ce43e484
SS
78static bool link_lldp_enabled(Link *link) {
79 if (link->flags & IFF_LOOPBACK)
80 return false;
81
82 if (!link->network)
83 return false;
84
5a8bcb67 85 if (link->network->bridge)
ce43e484
SS
86 return false;
87
88 return link->network->lldp;
89}
90
769d324c 91static bool link_ipv4_forward_enabled(Link *link) {
5a8bcb67
LP
92 if (link->flags & IFF_LOOPBACK)
93 return false;
94
95 if (!link->network)
96 return false;
97
769d324c
LP
98 return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
99}
100
101static bool link_ipv6_forward_enabled(Link *link) {
102 if (link->flags & IFF_LOOPBACK)
103 return false;
104
105 if (!link->network)
106 return false;
107
108 return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
5a8bcb67
LP
109}
110
51d18171
TG
111#define FLAG_STRING(string, flag, old, new) \
112 (((old ^ new) & flag) \
113 ? ((old & flag) ? (" -" string) : (" +" string)) \
114 : "")
115
116static int link_update_flags(Link *link, sd_rtnl_message *m) {
117 unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
118 uint8_t operstate;
119 int r;
120
121 assert(link);
122
123 r = sd_rtnl_message_link_get_flags(m, &flags);
124 if (r < 0) {
79008bdd 125 log_link_warning(link, "Could not get link flags");
51d18171
TG
126 return r;
127 }
128
129 r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
130 if (r < 0)
131 /* if we got a message without operstate, take it to mean
132 the state was unchanged */
133 operstate = link->kernel_operstate;
134
135 if ((link->flags == flags) && (link->kernel_operstate == operstate))
136 return 0;
137
138 if (link->flags != flags) {
79008bdd 139 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
140 FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
141 FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
142 FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
143 FLAG_STRING("UP", IFF_UP, link->flags, flags),
144 FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
145 FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
146 FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
147 FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
148 FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
149 FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
150 FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
151 FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
152 FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
153 FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
154 FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
155 FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
156 FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
157 FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
158 FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
159
160 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
161 IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
162 IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
163 IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
164 IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
165 IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
166 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
167 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
168
169 /* link flags are currently at most 18 bits, let's align to
170 * printing 20 */
171 if (unknown_flags_added)
79008bdd 172 log_link_debug(link,
51d18171
TG
173 "unknown link flags gained: %#.5x (ignoring)",
174 unknown_flags_added);
175
176 if (unknown_flags_removed)
79008bdd 177 log_link_debug(link,
51d18171
TG
178 "unknown link flags lost: %#.5x (ignoring)",
179 unknown_flags_removed);
180 }
181
182 link->flags = flags;
183 link->kernel_operstate = operstate;
184
185 link_save(link);
186
187 return 0;
188}
189
505f8da7 190static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
14b746f7 191 _cleanup_link_unref_ Link *link = NULL;
505f8da7 192 uint16_t type;
ca4e095a 193 const char *ifname;
505f8da7 194 int r, ifindex;
f579559b 195
0c2f9b84 196 assert(manager);
505f8da7 197 assert(message);
f579559b
TG
198 assert(ret);
199
505f8da7
TG
200 r = sd_rtnl_message_get_type(message, &type);
201 if (r < 0)
202 return r;
203 else if (type != RTM_NEWLINK)
204 return -EINVAL;
205
206 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
207 if (r < 0)
208 return r;
209 else if (ifindex <= 0)
210 return -EINVAL;
211
212 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
213 if (r < 0)
214 return r;
215
f579559b
TG
216 link = new0(Link, 1);
217 if (!link)
218 return -ENOMEM;
219
14b746f7 220 link->n_ref = 1;
5a3eb5a7 221 link->manager = manager;
8434fd5c 222 link->state = LINK_STATE_PENDING;
505f8da7
TG
223 link->ifindex = ifindex;
224 link->ifname = strdup(ifname);
225 if (!link->ifname)
226 return -ENOMEM;
f579559b 227
512922f8
TG
228 r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
229 if (r < 0)
79008bdd 230 log_link_debug(link, "MAC address not found for new device, continuing without");
512922f8 231
3c9b8860
TG
232 r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
233 link->ifindex);
fe8db0c5 234 if (r < 0)
315db1a8 235 return -ENOMEM;
fe8db0c5 236
3c9b8860
TG
237 r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
238 link->ifindex);
68a8723c
TG
239 if (r < 0)
240 return -ENOMEM;
241
49699bac
SS
242 r = asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d",
243 link->ifindex);
244 if (r < 0)
245 return -ENOMEM;
246
247
d5099efc 248 r = hashmap_ensure_allocated(&manager->links, NULL);
ae06ab10
TG
249 if (r < 0)
250 return r;
251
252 r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
f579559b
TG
253 if (r < 0)
254 return r;
255
51d18171
TG
256 r = link_update_flags(link, message);
257 if (r < 0)
258 return r;
259
f579559b
TG
260 *ret = link;
261 link = NULL;
262
263 return 0;
264}
265
14b746f7 266static void link_free(Link *link) {
428fd0a7
TG
267 Address *address;
268
f579559b
TG
269 if (!link)
270 return;
271
428fd0a7
TG
272 while ((address = link->addresses)) {
273 LIST_REMOVE(addresses, link->addresses, address);
274 address_free(address);
275 }
276
11bf3cce
LP
277 while ((address = link->pool_addresses)) {
278 LIST_REMOVE(addresses, link->pool_addresses, address);
279 address_free(address);
280 }
281
bfcdba8d 282 sd_dhcp_server_unref(link->dhcp_server);
e5b04c8d 283 sd_dhcp_client_unref(link->dhcp_client);
a6cc569e 284 sd_dhcp_lease_unref(link->dhcp_lease);
f5be5601 285
68a8723c
TG
286 free(link->lease_file);
287
07e10d1a
TG
288 sd_lldp_free(link->lldp);
289
49699bac
SS
290 free(link->lldp_file);
291
56cd007a 292 sd_ipv4ll_unref(link->ipv4ll);
4138fb2c 293 sd_dhcp6_client_unref(link->dhcp6_client);
6b66097b 294 sd_icmp6_nd_unref(link->icmp6_router_discovery);
4138fb2c 295
28aeb07f 296 if (link->manager)
ae06ab10 297 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
f579559b 298
c166a070 299 free(link->ifname);
68a8723c 300
fe8db0c5 301 free(link->state_file);
c166a070 302
b5db00e5
UTL
303 udev_device_unref(link->udev_device);
304
f579559b
TG
305 free(link);
306}
307
14b746f7
TG
308Link *link_unref(Link *link) {
309 if (link && (-- link->n_ref <= 0))
310 link_free(link);
311
312 return NULL;
313}
314
315Link *link_ref(Link *link) {
316 if (link)
317 assert_se(++ link->n_ref >= 2);
318
319 return link;
320}
321
11a7f229
TG
322int link_get(Manager *m, int ifindex, Link **ret) {
323 Link *link;
11a7f229
TG
324
325 assert(m);
11a7f229
TG
326 assert(ifindex);
327 assert(ret);
328
ae06ab10 329 link = hashmap_get(m->links, INT_TO_PTR(ifindex));
11a7f229
TG
330 if (!link)
331 return -ENODEV;
332
333 *ret = link;
334
335 return 0;
336}
337
e331e246
TG
338static void link_set_state(Link *link, LinkState state) {
339 assert(link);
340
341 if (link->state == state)
342 return;
343
344 link->state = state;
345
346 link_send_changed(link, "AdministrativeState", NULL);
347
348 return;
349}
350
370e9930
TG
351void link_drop(Link *link) {
352 if (!link || link->state == LINK_STATE_LINGER)
353 return;
354
e331e246 355 link_set_state(link, LINK_STATE_LINGER);
370e9930 356
79008bdd 357 log_link_debug(link, "link removed");
370e9930
TG
358
359 link_unref(link);
360
361 return;
362}
363
57bd6899
TG
364static void link_enter_unmanaged(Link *link) {
365 assert(link);
366
79008bdd 367 log_link_debug(link, "unmanaged");
57bd6899 368
e331e246 369 link_set_state(link, LINK_STATE_UNMANAGED);
57bd6899
TG
370
371 link_save(link);
372}
373
111bb8f9
TG
374static int link_stop_clients(Link *link) {
375 int r = 0, k;
376
377 assert(link);
378 assert(link->manager);
379 assert(link->manager->event);
380
381 if (!link->network)
382 return 0;
383
ba179154 384 if (link->dhcp_client) {
111bb8f9
TG
385 k = sd_dhcp_client_stop(link->dhcp_client);
386 if (k < 0) {
79008bdd 387 log_link_warning(link, "Could not stop DHCPv4 client: %s",
3c9b8860 388 strerror(-r));
111bb8f9
TG
389 r = k;
390 }
391 }
392
ba179154 393 if (link->ipv4ll) {
111bb8f9
TG
394 k = sd_ipv4ll_stop(link->ipv4ll);
395 if (k < 0) {
79008bdd 396 log_link_warning(link, "Could not stop IPv4 link-local: %s",
3c9b8860 397 strerror(-r));
111bb8f9 398 r = k;
dd43110f
TG
399 }
400 }
401
ba179154 402 if(link->icmp6_router_discovery) {
1873a3d3
PF
403
404 if (link->dhcp6_client) {
405 k = sd_dhcp6_client_stop(link->dhcp6_client);
406 if (k < 0) {
79008bdd 407 log_link_warning(link, "Could not stop DHCPv6 client: %s",
3c9b8860 408 strerror(-r));
1873a3d3
PF
409 r = k;
410 }
411 }
4138fb2c 412
1873a3d3 413 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
4138fb2c 414 if (k < 0) {
79008bdd 415 log_link_warning(link,
3c9b8860
TG
416 "Could not stop ICMPv6 router discovery: %s",
417 strerror(-r));
4138fb2c
PF
418 r = k;
419 }
420 }
421
ce43e484
SS
422 if (link->lldp) {
423
424 k = sd_lldp_stop(link->lldp);
425 if (k < 0) {
426 log_link_warning(link, "Could not stop LLDP : %s",
427 strerror(-r));
428 r = k;
429 }
430 }
431
111bb8f9
TG
432 return r;
433}
434
b22d8a00 435void link_enter_failed(Link *link) {
ef1ba606 436 assert(link);
f882c247 437
370e9930 438 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
2139694e
TG
439 return;
440
79008bdd 441 log_link_warning(link, "failed");
449f7554 442
e331e246 443 link_set_state(link, LINK_STATE_FAILED);
fe8db0c5 444
111bb8f9
TG
445 link_stop_clients(link);
446
fe8db0c5 447 link_save(link);
f882c247
TG
448}
449
4f434938
LP
450static Address* link_find_dhcp_server_address(Link *link) {
451 Address *address;
452
453 assert(link);
454 assert(link->network);
455
d4cdbea5 456 /* The first statically configured address if there is any */
4f434938
LP
457 LIST_FOREACH(addresses, address, link->network->static_addresses) {
458
459 if (address->family != AF_INET)
460 continue;
461
af93291c 462 if (in_addr_is_null(address->family, &address->in_addr))
4f434938
LP
463 continue;
464
465 return address;
466 }
467
468 /* If that didn't work, find a suitable address we got from the pool */
469 LIST_FOREACH(addresses, address, link->pool_addresses) {
470 if (address->family != AF_INET)
471 continue;
472
473 return address;
474 }
475
476 return NULL;
477}
478
dd43110f 479static int link_enter_configured(Link *link) {
dd43110f
TG
480 assert(link);
481 assert(link->network);
482 assert(link->state == LINK_STATE_SETTING_ROUTES);
483
79008bdd 484 log_link_info(link, "link configured");
dd43110f 485
e331e246 486 link_set_state(link, LINK_STATE_CONFIGURED);
dd43110f
TG
487
488 link_save(link);
489
490 return 0;
491}
492
3c9b8860
TG
493void link_client_handler(Link *link) {
494 assert(link);
495 assert(link->network);
496
497 if (!link->static_configured)
498 return;
499
78c958f8 500 if (link_ipv4ll_enabled(link))
3c9b8860
TG
501 if (!link->ipv4ll_address ||
502 !link->ipv4ll_route)
503 return;
504
78c958f8 505 if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
3c9b8860
TG
506 return;
507
9fdaa992
TG
508 if (link->state != LINK_STATE_CONFIGURED)
509 link_enter_configured(link);
3c9b8860
TG
510
511 return;
512}
513
f882c247 514static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 515 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
516 int r;
517
3c9b8860 518 assert(link->link_messages > 0);
370e9930
TG
519 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
520 LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
521 LINK_STATE_LINGER));
f882c247 522
3c9b8860 523 link->link_messages --;
f882c247 524
77a008c0 525 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
526 return 1;
527
528 r = sd_rtnl_message_get_errno(m);
c166a070 529 if (r < 0 && r != -EEXIST)
6c861f0a 530 log_link_warning_errno(link, -r, "%-*s: could not set route: %m", IFNAMSIZ, link->ifname);
f882c247 531
3c9b8860 532 if (link->link_messages == 0) {
79008bdd 533 log_link_debug(link, "routes set");
3c9b8860
TG
534 link->static_configured = true;
535 link_client_handler(link);
dd3efc09 536 }
f882c247
TG
537
538 return 1;
539}
540
541static int link_enter_set_routes(Link *link) {
a6cc569e 542 Route *rt;
f882c247
TG
543 int r;
544
545 assert(link);
546 assert(link->network);
ef1ba606 547 assert(link->state == LINK_STATE_SETTING_ADDRESSES);
f882c247 548
e331e246 549 link_set_state(link, LINK_STATE_SETTING_ROUTES);
f882c247 550
3d3d4255 551 LIST_FOREACH(routes, rt, link->network->static_routes) {
a6cc569e 552 r = route_configure(rt, link, &route_handler);
dd3efc09 553 if (r < 0) {
79008bdd 554 log_link_warning(link,
3c9b8860 555 "could not set routes: %s",
b1666580 556 strerror(-r));
3c9b8860 557 link_enter_failed(link);
a6cc569e
TG
558 return r;
559 }
560
3c9b8860 561 link->link_messages ++;
8ddbeaa2 562 }
f5be5601 563
3c9b8860
TG
564 if (link->link_messages == 0) {
565 link->static_configured = true;
566 link_client_handler(link);
431ca2ce 567 } else
79008bdd 568 log_link_debug(link, "setting routes");
f882c247
TG
569
570 return 0;
571}
572
b22d8a00 573int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 574 _cleanup_link_unref_ Link *link = userdata;
5c1d3fc9
UTL
575 int r;
576
577 assert(m);
578 assert(link);
579 assert(link->ifname);
580
5da8149f 581 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
5c1d3fc9
UTL
582 return 1;
583
584 r = sd_rtnl_message_get_errno(m);
b90b025a 585 if (r < 0 && r != -ESRCH)
6c861f0a 586 log_link_warning_errno(link, -r, "%-*s: could not drop route: %m", IFNAMSIZ, link->ifname);
5c1d3fc9 587
5bdd314c 588 return 1;
5c1d3fc9
UTL
589}
590
f882c247 591static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 592 _cleanup_link_unref_ Link *link = userdata;
f882c247
TG
593 int r;
594
4958aee4 595 assert(rtnl);
f5be5601
TG
596 assert(m);
597 assert(link);
598 assert(link->ifname);
3c9b8860 599 assert(link->link_messages > 0);
370e9930
TG
600 assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
601 LINK_STATE_FAILED, LINK_STATE_LINGER));
f882c247 602
3c9b8860 603 link->link_messages --;
f882c247 604
5da8149f 605 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
f882c247
TG
606 return 1;
607
608 r = sd_rtnl_message_get_errno(m);
c166a070 609 if (r < 0 && r != -EEXIST)
6c861f0a 610 log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
45af44d4
TG
611 else if (r >= 0)
612 link_rtnl_process_address(rtnl, m, link->manager);
f882c247 613
3c9b8860 614 if (link->link_messages == 0) {
79008bdd 615 log_link_debug(link, "addresses set");
ef1ba606 616 link_enter_set_routes(link);
dd3efc09 617 }
f882c247
TG
618
619 return 1;
620}
621
622static int link_enter_set_addresses(Link *link) {
a6cc569e 623 Address *ad;
f882c247
TG
624 int r;
625
626 assert(link);
627 assert(link->network);
f5be5601 628 assert(link->state != _LINK_STATE_INVALID);
f882c247 629
e331e246 630 link_set_state(link, LINK_STATE_SETTING_ADDRESSES);
f882c247 631
3d3d4255 632 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
a6cc569e 633 r = address_configure(ad, link, &address_handler);
dd3efc09 634 if (r < 0) {
5a8bcb67 635 log_link_warning_errno(link, r, "Could not set addresses: %m");
f5be5601
TG
636 link_enter_failed(link);
637 return r;
638 }
639
3c9b8860 640 link->link_messages ++;
f882c247
TG
641 }
642
d4cdbea5
TG
643 /* now that we can figure out a default address for the dhcp server,
644 start it */
645 if (link_dhcp4_server_enabled(link)) {
646 struct in_addr pool_start;
647 Address *address;
648
649 address = link_find_dhcp_server_address(link);
650 if (!address) {
651 log_link_warning(link,
652 "Failed to find suitable address for DHCPv4 server instance.");
653 link_enter_failed(link);
654 return 0;
655 }
656
657 r = sd_dhcp_server_set_address(link->dhcp_server,
658 &address->in_addr.in,
659 address->prefixlen);
660 if (r < 0)
661 return r;
662
663 /* offer 32 addresses starting from the address following the server address */
664 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
665 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
666 &pool_start, 32);
667 if (r < 0)
668 return r;
669
670 /* TODO:
671 r = sd_dhcp_server_set_router(link->dhcp_server,
672 &main_address->in_addr.in);
673 if (r < 0)
674 return r;
675
676 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
677 main_address->prefixlen);
678 if (r < 0)
679 return r;
680 */
681
682 r = sd_dhcp_server_start(link->dhcp_server);
683 if (r < 0) {
684 log_link_warning(link, "could not start DHCPv4 server "
685 "instance: %s", strerror(-r));
686
687 link_enter_failed(link);
688
689 return 0;
690 }
691
692 log_link_debug(link, "offering DHCPv4 leases");
693 }
694
3c9b8860 695 if (link->link_messages == 0) {
431ca2ce
TG
696 link_enter_set_routes(link);
697 } else
79008bdd 698 log_link_debug(link, "setting addresses");
431ca2ce 699
f882c247
TG
700 return 0;
701}
702
b22d8a00 703int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 704 _cleanup_link_unref_ Link *link = userdata;
ff254138
TG
705 int r;
706
707 assert(m);
708 assert(link);
709 assert(link->ifname);
710
5da8149f 711 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ff254138
TG
712 return 1;
713
714 r = sd_rtnl_message_get_errno(m);
b90b025a 715 if (r < 0 && r != -EADDRNOTAVAIL)
6c861f0a 716 log_link_warning_errno(link, -r, "%-*s: could not drop address: %m", IFNAMSIZ, link->ifname);
ff254138 717
5bdd314c 718 return 1;
ff254138
TG
719}
720
b98b483b
AR
721static int link_set_bridge_fdb(const Link *const link) {
722 FdbEntry *fdb_entry;
723 int r = 0;
724
725 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
726 r = fdb_entry_configure(link->manager->rtnl, fdb_entry, link->ifindex);
727 if(r < 0) {
728 log_link_error(link, "Failed to add MAC entry to static MAC table: %s", strerror(-r));
729 break;
730 }
731 }
732
733 return r;
734}
735
e1853b00
SS
736static int link_set_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
737 _cleanup_link_unref_ Link *link = userdata;
738 int r;
739
00e8d83a 740 log_link_debug(link, "set link");
e1853b00
SS
741
742 r = sd_rtnl_message_get_errno(m);
743 if (r < 0 && r != -EEXIST) {
00e8d83a 744 log_link_struct(link, LOG_ERR,
e1853b00
SS
745 "MESSAGE=%-*s: could not join netdev: %s",
746 IFNAMSIZ,
747 link->ifname, strerror(-r),
748 "ERRNO=%d", -r,
749 NULL);
750 link_enter_failed(link);
751 return 1;
752 }
753
754 return 0;
755}
756
3c9b8860
TG
757static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
758 sd_bus_error *ret_error) {
5da8149f 759 _cleanup_link_unref_ Link *link = userdata;
1346b1f0
TG
760 int r;
761
b226d99b
TG
762 assert(link);
763
5da8149f 764 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
370e9930 765 return 1;
370e9930 766
1346b1f0 767 r = sd_bus_message_get_errno(m);
70b34f5d 768 if (r > 0)
79008bdd 769 log_link_warning(link, "Could not set hostname: %s",
3c9b8860 770 strerror(r));
1346b1f0
TG
771
772 return 1;
773}
774
3c9b8860 775int link_set_hostname(Link *link, const char *hostname) {
1346b1f0
TG
776 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
777 int r = 0;
778
b226d99b
TG
779 assert(link);
780 assert(link->manager);
1346b1f0
TG
781 assert(hostname);
782
79008bdd 783 log_link_debug(link, "Setting transient hostname: '%s'", hostname);
1346b1f0 784
3c9b8860
TG
785 if (!link->manager->bus) {
786 /* TODO: replace by assert when we can rely on kdbus */
79008bdd 787 log_link_info(link,
3c9b8860 788 "Not connected to system bus, ignoring transient hostname.");
bcbca829
TG
789 return 0;
790 }
791
1346b1f0 792 r = sd_bus_message_new_method_call(
b226d99b 793 link->manager->bus,
151b9b96 794 &m,
1346b1f0
TG
795 "org.freedesktop.hostname1",
796 "/org/freedesktop/hostname1",
797 "org.freedesktop.hostname1",
151b9b96 798 "SetHostname");
1346b1f0
TG
799 if (r < 0)
800 return r;
801
802 r = sd_bus_message_append(m, "sb", hostname, false);
803 if (r < 0)
804 return r;
805
3c9b8860
TG
806 r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
807 link, 0);
5da8149f 808 if (r < 0) {
79008bdd 809 log_link_error(link, "Could not set transient hostname: %s",
3c9b8860 810 strerror(-r));
5da8149f
TG
811 return r;
812 }
b226d99b
TG
813
814 link_ref(link);
1346b1f0 815
5da8149f 816 return 0;
1346b1f0
TG
817}
818
4f882b2a 819static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 820 _cleanup_link_unref_ Link *link = userdata;
4f882b2a
TG
821 int r;
822
823 assert(m);
824 assert(link);
825 assert(link->ifname);
826
5da8149f 827 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
4f882b2a
TG
828 return 1;
829
830 r = sd_rtnl_message_get_errno(m);
c9ccc19f 831 if (r < 0)
6c861f0a 832 log_link_warning_errno(link, -r, "%-*s: could not set MTU: %m", IFNAMSIZ, link->ifname);
4f882b2a
TG
833
834 return 1;
835}
836
3c9b8860 837int link_set_mtu(Link *link, uint32_t mtu) {
cf6a8911 838 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
4f882b2a
TG
839 int r;
840
841 assert(link);
842 assert(link->manager);
843 assert(link->manager->rtnl);
844
79008bdd 845 log_link_debug(link, "setting MTU: %" PRIu32, mtu);
4f882b2a 846
151b9b96
LP
847 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
848 RTM_SETLINK, link->ifindex);
4f882b2a 849 if (r < 0) {
79008bdd 850 log_link_error(link, "Could not allocate RTM_SETLINK message");
4f882b2a
TG
851 return r;
852 }
853
854 r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
855 if (r < 0) {
79008bdd 856 log_link_error(link, "Could not append MTU: %s", strerror(-r));
4f882b2a
TG
857 return r;
858 }
859
3c9b8860
TG
860 r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
861 0, NULL);
4f882b2a 862 if (r < 0) {
79008bdd 863 log_link_error(link,
3c9b8860
TG
864 "Could not send rtnetlink message: %s",
865 strerror(-r));
4f882b2a
TG
866 return r;
867 }
868
ae941762 869 link_ref(link);
b226d99b 870
4f882b2a
TG
871 return 0;
872}
873
e1853b00
SS
874static int link_set_bridge(Link *link) {
875 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
876 int r;
877
878 assert(link);
879 assert(link->network);
880
881 if(link->network->cost == 0)
882 return 0;
883
884 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
885 RTM_SETLINK, link->ifindex);
886 if (r < 0) {
00e8d83a 887 log_link_error(link, "Could not allocate RTM_SETLINK message");
e1853b00
SS
888 return r;
889 }
890
891 r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
892 if (r < 0) {
00e8d83a 893 log_link_error(link,
e1853b00
SS
894 "Could not set message family %s", strerror(-r));
895 return r;
896 }
897
898 r = sd_rtnl_message_open_container(req, IFLA_PROTINFO);
899 if (r < 0) {
00e8d83a 900 log_link_error(link,
e1853b00
SS
901 "Could not append IFLA_PROTINFO attribute: %s",
902 strerror(-r));
903 return r;
904 }
905
906 if(link->network->cost != 0) {
907 r = sd_rtnl_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
908 if (r < 0) {
00e8d83a 909 log_link_error(link,
e1853b00
SS
910 "Could not append IFLA_BRPORT_COST attribute: %s",
911 strerror(-r));
912 return r;
913 }
914 }
915
916 r = sd_rtnl_message_close_container(req);
917 if (r < 0) {
00e8d83a 918 log_link_error(link,
e1853b00
SS
919 "Could not append IFLA_LINKINFO attribute: %s",
920 strerror(-r));
921 return r;
922 }
923
924 r = sd_rtnl_call_async(link->manager->rtnl, req, link_set_handler, link, 0, NULL);
925 if (r < 0) {
00e8d83a 926 log_link_error(link,
e1853b00
SS
927 "Could not send rtnetlink message: %s",
928 strerror(-r));
929 return r;
930 }
931
932 link_ref(link);
933
934 return r;
935}
936
49699bac
SS
937static void lldp_handler(sd_lldp *lldp, int event, void *userdata) {
938 Link *link = userdata;
939 int r;
940
941 assert(link);
942 assert(link->network);
943 assert(link->manager);
944
945 if (event != UPDATE_INFO)
946 return;
947
948 r = sd_lldp_save(link->lldp, link->lldp_file);
949 if (r < 0)
950 log_link_warning(link, "could not save LLDP");
951
952}
953
ff254138
TG
954static int link_acquire_conf(Link *link) {
955 int r;
956
957 assert(link);
958 assert(link->network);
ff254138
TG
959 assert(link->manager);
960 assert(link->manager->event);
961
78c958f8 962 if (link_ipv4ll_enabled(link)) {
eb34d4af 963 assert(link->ipv4ll);
ff254138 964
79008bdd 965 log_link_debug(link, "acquiring IPv4 link-local address");
5c1d3fc9
UTL
966
967 r = sd_ipv4ll_start(link->ipv4ll);
124fa2c6 968 if (r < 0) {
79008bdd 969 log_link_warning(link, "could not acquire IPv4 "
124fa2c6 970 "link-local address");
ff254138 971 return r;
124fa2c6 972 }
5c1d3fc9
UTL
973 }
974
78c958f8 975 if (link_dhcp4_enabled(link)) {
eb34d4af 976 assert(link->dhcp_client);
ff254138 977
79008bdd 978 log_link_debug(link, "acquiring DHCPv4 lease");
ab47d620 979
5c1d3fc9 980 r = sd_dhcp_client_start(link->dhcp_client);
124fa2c6 981 if (r < 0) {
79008bdd 982 log_link_warning(link, "could not acquire DHCPv4 "
124fa2c6 983 "lease");
5c1d3fc9 984 return r;
124fa2c6 985 }
5c1d3fc9 986 }
ff254138 987
78c958f8 988 if (link_dhcp6_enabled(link)) {
4138fb2c
PF
989 assert(link->icmp6_router_discovery);
990
79008bdd 991 log_link_debug(link, "discovering IPv6 routers");
4138fb2c
PF
992
993 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
994 if (r < 0) {
79008bdd 995 log_link_warning(link,
3c9b8860 996 "could not start IPv6 router discovery");
4138fb2c
PF
997 return r;
998 }
999 }
1000
ce43e484
SS
1001 if (link_lldp_enabled(link)) {
1002 assert(link->lldp);
1003
1004 log_link_debug(link, "Starting LLDP");
1005
1006 r = sd_lldp_start(link->lldp);
1007 if (r < 0) {
1008 log_link_warning(link, "could not start LLDP ");
1009 return r;
1010 }
1011 }
1012
ff254138
TG
1013 return 0;
1014}
1015
a61bb41c 1016bool link_has_carrier(Link *link) {
deb2e523
TG
1017 /* see Documentation/networking/operstates.txt in the kernel sources */
1018
a61bb41c 1019 if (link->kernel_operstate == IF_OPER_UP)
deb2e523
TG
1020 return true;
1021
a61bb41c 1022 if (link->kernel_operstate == IF_OPER_UNKNOWN)
deb2e523 1023 /* operstate may not be implemented, so fall back to flags */
a61bb41c 1024 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
deb2e523
TG
1025 return true;
1026
1027 return false;
1028}
1029
dd3efc09 1030static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
5da8149f 1031 _cleanup_link_unref_ Link *link = userdata;
dd3efc09
TG
1032 int r;
1033
1746cf2a
TG
1034 assert(link);
1035
5da8149f 1036 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1746cf2a
TG
1037 return 1;
1038
dd3efc09 1039 r = sd_rtnl_message_get_errno(m);
45ad2c13 1040 if (r < 0) {
9b86b393
TG
1041 /* we warn but don't fail the link, as it may
1042 be brought up later */
6c861f0a 1043 log_link_warning_errno(link, -r, "%-*s: could not bring up interface: %m", IFNAMSIZ, link->ifname);
45ad2c13
TG
1044 }
1045
f882c247
TG
1046 return 1;
1047}
1048
1049static int link_up(Link *link) {
cf6a8911 1050 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f579559b
TG
1051 int r;
1052
f882c247 1053 assert(link);
c106cc36 1054 assert(link->network);
f882c247
TG
1055 assert(link->manager);
1056 assert(link->manager->rtnl);
1057
79008bdd 1058 log_link_debug(link, "bringing link up");
449f7554 1059
151b9b96
LP
1060 r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1061 RTM_SETLINK, link->ifindex);
f579559b 1062 if (r < 0) {
79008bdd 1063 log_link_error(link, "Could not allocate RTM_SETLINK message");
f579559b
TG
1064 return r;
1065 }
1066
5d4795f3 1067 r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
fc25d7f8 1068 if (r < 0) {
79008bdd 1069 log_link_error(link, "Could not set link flags: %s",
3c9b8860 1070 strerror(-r));
fc25d7f8
TG
1071 return r;
1072 }
1073
c106cc36
TG
1074 if (link->network->mac) {
1075 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
1076 if (r < 0) {
1077 log_link_error(link, "Could not set MAC address: %s", strerror(-r));
1078 return r;
1079 }
1080 }
1081
1082 if (link->network->mtu) {
1083 r = sd_rtnl_message_append_u32(req, IFLA_MTU, link->network->mtu);
1084 if (r < 0) {
1085 log_link_error(link, "Could not set MTU: %s", strerror(-r));
1086 return r;
1087 }
1088 }
1089
3c9b8860
TG
1090 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1091 0, NULL);
f579559b 1092 if (r < 0) {
79008bdd 1093 log_link_error(link,
3c9b8860
TG
1094 "Could not send rtnetlink message: %s",
1095 strerror(-r));
f579559b
TG
1096 return r;
1097 }
1098
b226d99b
TG
1099 link_ref(link);
1100
f882c247
TG
1101 return 0;
1102}
1103
3f265037 1104static int link_joined(Link *link) {
f882c247
TG
1105 int r;
1106
ef1ba606 1107 assert(link);
f5be5601 1108 assert(link->network);
dd3efc09 1109
505f8da7
TG
1110 if (!(link->flags & IFF_UP)) {
1111 r = link_up(link);
1112 if (r < 0) {
1113 link_enter_failed(link);
1114 return r;
1115 }
ef1ba606 1116 }
f882c247 1117
e1853b00
SS
1118 if(link->network->bridge) {
1119 r = link_set_bridge(link);
1120 if (r < 0) {
00e8d83a 1121 log_link_error(link,
e1853b00
SS
1122 "Could not set bridge message: %s",
1123 strerror(-r));
1124 }
1125 }
1126
fb6730c4 1127 return link_enter_set_addresses(link);
02b59d57
TG
1128}
1129
3c9b8860
TG
1130static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1131 void *userdata) {
5da8149f 1132 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1133 int r;
1134
1746cf2a 1135 assert(link);
ef1ba606 1136 assert(link->network);
02b59d57 1137
52433f6b
TG
1138 link->enslaving --;
1139
5da8149f 1140 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1141 return 1;
1142
1143 r = sd_rtnl_message_get_errno(m);
856f962c 1144 if (r < 0 && r != -EEXIST) {
6c861f0a 1145 log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
ef1ba606
TG
1146 link_enter_failed(link);
1147 return 1;
ba179154 1148 } else
79008bdd 1149 log_link_debug(link, "joined netdev");
02b59d57 1150
856f962c 1151 if (link->enslaving <= 0)
3f265037 1152 link_joined(link);
02b59d57
TG
1153
1154 return 1;
1155}
1156
3f265037 1157static int link_enter_join_netdev(Link *link) {
6a0a2f86 1158 NetDev *netdev;
672682a6 1159 Iterator i;
02b59d57
TG
1160 int r;
1161
1162 assert(link);
1163 assert(link->network);
8434fd5c 1164 assert(link->state == LINK_STATE_PENDING);
02b59d57 1165
e331e246 1166 link_set_state(link, LINK_STATE_ENSLAVING);
02b59d57 1167
fe8db0c5
TG
1168 link_save(link);
1169
7951dea2
SS
1170 if (!link->network->bridge &&
1171 !link->network->bond &&
6a0a2f86 1172 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1173 return link_joined(link);
02b59d57 1174
d9c67ea1 1175 if (link->network->bond) {
6c861f0a 1176 log_link_struct(link, LOG_DEBUG,
97578344 1177 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1178 IFNAMSIZ,
af4e9e2c 1179 link->ifname, link->network->bond->ifname,
aa9f1140 1180 NETDEVIF(link->network->bond),
52433f6b 1181 NULL);
449f7554 1182
3f265037 1183 r = netdev_join(link->network->bond, link, &netdev_join_handler);
52433f6b 1184 if (r < 0) {
6c861f0a 1185 log_link_struct(link, LOG_WARNING,
3f265037 1186 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1187 IFNAMSIZ,
3c9b8860
TG
1188 link->ifname, link->network->bond->ifname,
1189 strerror(-r),
aa9f1140 1190 NETDEVIF(link->network->bond),
52433f6b
TG
1191 NULL);
1192 link_enter_failed(link);
1193 return r;
1194 }
1195
0ad6148e
MO
1196 link->enslaving ++;
1197 }
1198
d9c67ea1 1199 if (link->network->bridge) {
6c861f0a 1200 log_link_struct(link, LOG_DEBUG,
97578344 1201 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1202 IFNAMSIZ,
af4e9e2c 1203 link->ifname, link->network->bridge->ifname,
aa9f1140 1204 NETDEVIF(link->network->bridge),
0ad6148e
MO
1205 NULL);
1206
3c9b8860
TG
1207 r = netdev_join(link->network->bridge, link,
1208 &netdev_join_handler);
0ad6148e 1209 if (r < 0) {
6c861f0a 1210 log_link_struct(link, LOG_WARNING,
3f265037 1211 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1212 IFNAMSIZ,
3c9b8860
TG
1213 link->ifname, link->network->bridge->ifname,
1214 strerror(-r),
aa9f1140 1215 NETDEVIF(link->network->bridge),
0ad6148e
MO
1216 NULL);
1217 link_enter_failed(link);
1218 return r;
1219 }
1220
52433f6b
TG
1221 link->enslaving ++;
1222 }
1223
6a0a2f86 1224 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
6c861f0a 1225 log_link_struct(link, LOG_DEBUG,
97578344 1226 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1227 IFNAMSIZ,
3c9b8860
TG
1228 link->ifname, netdev->ifname, NETDEVIF(netdev),
1229 NULL);
7951dea2 1230
6a0a2f86 1231 r = netdev_join(netdev, link, &netdev_join_handler);
7951dea2 1232 if (r < 0) {
6c861f0a 1233 log_link_struct(link, LOG_WARNING,
3f265037 1234 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1235 IFNAMSIZ,
3c9b8860
TG
1236 link->ifname, netdev->ifname,
1237 strerror(-r),
6a0a2f86 1238 NETDEVIF(netdev), NULL);
326cb406
SS
1239 link_enter_failed(link);
1240 return r;
1241 }
1242
326cb406
SS
1243 link->enslaving ++;
1244 }
1245
ef1ba606
TG
1246 return 0;
1247}
1248
769d324c 1249static int link_set_ipv4_forward(Link *link) {
5a8bcb67 1250 const char *p = NULL;
43c6d5ab 1251 bool b;
5a8bcb67
LP
1252 int r;
1253
43c6d5ab
LP
1254 b = link_ipv4_forward_enabled(link);
1255
63c372cb 1256 p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
43c6d5ab 1257 r = write_string_file_no_create(p, one_zero(b));
5a8bcb67 1258 if (r < 0)
43c6d5ab
LP
1259 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
1260
1261 if (b) {
1262 _cleanup_free_ char *buf = NULL;
1263
1264 /* If IP forwarding is turned on for this interface,
1265 * then propagate this to the global setting. Given
1266 * that turning this on has side-effects on other
1267 * fields, we'll try to avoid doing this unless
1268 * necessary, hence check the previous value
1269 * first. Note that we never turn this option off
1270 * again, since all interfaces we manage do not do
1271 * forwarding anyway by default, and ownership rules
1272 * of this control are so unclear. */
1273
1274 r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf);
1275 if (r < 0)
1276 log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m");
1277 else if (!streq(buf, "1")) {
1278 r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1");
1279 if (r < 0)
1280 log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m");
1281 }
1282 }
769d324c
LP
1283
1284 return 0;
1285}
1286
1287static int link_set_ipv6_forward(Link *link) {
1288 const char *p = NULL;
1289 int r;
1290
63c372cb 1291 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
769d324c
LP
1292 r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
1293 if (r < 0)
1294 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
5a8bcb67
LP
1295
1296 return 0;
1297}
1298
a748b692 1299static int link_configure(Link *link) {
02b59d57
TG
1300 int r;
1301
ef1ba606 1302 assert(link);
b22d8a00 1303 assert(link->network);
8434fd5c 1304 assert(link->state == LINK_STATE_PENDING);
a748b692 1305
b98b483b
AR
1306 r = link_set_bridge_fdb(link);
1307 if (r < 0)
1308 return r;
1309
769d324c
LP
1310 r = link_set_ipv4_forward(link);
1311 if (r < 0)
1312 return r;
1313
1314 r = link_set_ipv6_forward(link);
5a8bcb67
LP
1315 if (r < 0)
1316 return r;
1317
78c958f8 1318 if (link_ipv4ll_enabled(link)) {
b22d8a00 1319 r = ipv4ll_configure(link);
eb34d4af
TG
1320 if (r < 0)
1321 return r;
1322 }
1323
78c958f8 1324 if (link_dhcp4_enabled(link)) {
3c9b8860 1325 r = dhcp4_configure(link);
eb34d4af
TG
1326 if (r < 0)
1327 return r;
eb34d4af
TG
1328 }
1329
78c958f8 1330 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
1331 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1332 if (r < 0)
1333 return r;
1334
1335 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1336 if (r < 0)
1337 return r;
dd43110f
TG
1338 }
1339
78c958f8 1340 if (link_dhcp6_enabled(link)) {
5c79bd79 1341 r = icmp6_configure(link);
4138fb2c
PF
1342 if (r < 0)
1343 return r;
1344 }
1345
ce43e484
SS
1346 if (link_lldp_enabled(link)) {
1347 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
1348 if (r < 0)
1349 return r;
1350
1351 r = sd_lldp_attach_event(link->lldp, NULL, 0);
1352 if (r < 0)
1353 return r;
49699bac
SS
1354
1355 r = sd_lldp_set_callback(link->lldp,
1356 lldp_handler, link);
1357 if (r < 0)
1358 return r;
ce43e484
SS
1359 }
1360
a61bb41c 1361 if (link_has_carrier(link)) {
1e9be60b
TG
1362 r = link_acquire_conf(link);
1363 if (r < 0)
1364 return r;
cc544d5f 1365 }
1e9be60b 1366
3f265037 1367 return link_enter_join_netdev(link);
505f8da7
TG
1368}
1369
3c9b8860
TG
1370static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1371 void *userdata) {
5da8149f 1372 _cleanup_link_unref_ Link *link = userdata;
505f8da7 1373 Network *network;
505f8da7
TG
1374 int r;
1375
1376 assert(link);
1377 assert(link->ifname);
1378 assert(link->manager);
1379
8434fd5c 1380 if (link->state != LINK_STATE_PENDING)
5da8149f 1381 return 1;
505f8da7 1382
79008bdd 1383 log_link_debug(link, "link state is up-to-date");
505f8da7 1384
3c9b8860
TG
1385 r = network_get(link->manager, link->udev_device, link->ifname,
1386 &link->mac, &network);
57bd6899
TG
1387 if (r == -ENOENT) {
1388 link_enter_unmanaged(link);
5da8149f 1389 return 1;
57bd6899
TG
1390 } else if (r < 0)
1391 return r;
505f8da7 1392
bd2efe92 1393 if (link->flags & IFF_LOOPBACK) {
78c958f8 1394 if (network->ipv4ll)
79008bdd 1395 log_link_debug(link, "ignoring IPv4LL for loopback link");
78c958f8 1396
cb9fc36a 1397 if (network->dhcp != ADDRESS_FAMILY_NO)
79008bdd 1398 log_link_debug(link, "ignoring DHCP clients for loopback link");
78c958f8
TG
1399
1400 if (network->dhcp_server)
79008bdd 1401 log_link_debug(link, "ignoring DHCP server for loopback link");
bd2efe92
TG
1402 }
1403
505f8da7
TG
1404 r = network_apply(link->manager, network, link);
1405 if (r < 0)
1406 return r;
1407
a748b692
TG
1408 r = link_configure(link);
1409 if (r < 0)
1410 return r;
1411
5da8149f 1412 return 1;
505f8da7
TG
1413}
1414
4f561e8e
TG
1415int link_initialized(Link *link, struct udev_device *device) {
1416 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1417 int r;
1418
1419 assert(link);
1420 assert(link->manager);
1421 assert(link->manager->rtnl);
1422 assert(device);
1423
8434fd5c 1424 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
1425 return 0;
1426
679b3605
TG
1427 if (link->udev_device)
1428 return 0;
1429
79008bdd 1430 log_link_debug(link, "udev initialized link");
4f561e8e
TG
1431
1432 link->udev_device = udev_device_ref(device);
1433
3c9b8860
TG
1434 /* udev has initialized the link, but we don't know if we have yet
1435 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1436 * when it returns we know that the pending NEWLINKs have already been
1437 * processed and that we are up-to-date */
4f561e8e 1438
3c9b8860
TG
1439 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1440 link->ifindex);
4f561e8e
TG
1441 if (r < 0)
1442 return r;
1443
3c9b8860
TG
1444 r = sd_rtnl_call_async(link->manager->rtnl, req,
1445 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
1446 if (r < 0)
1447 return r;
1448
5da8149f
TG
1449 link_ref(link);
1450
4f561e8e
TG
1451 return 0;
1452}
1453
5a8bcb67
LP
1454static Address* link_get_equal_address(Link *link, Address *needle) {
1455 Address *i;
1456
1457 assert(link);
1458 assert(needle);
1459
1460 LIST_FOREACH(addresses, i, link->addresses)
1461 if (address_equal(i, needle))
1462 return i;
1463
1464 return NULL;
1465}
1466
45af44d4 1467int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
fbbeb65a
TG
1468 Manager *m = userdata;
1469 Link *link = NULL;
1470 uint16_t type;
1471 _cleanup_address_free_ Address *address = NULL;
5a8bcb67
LP
1472 Address *existing;
1473 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
c6d3b303 1474 const char *valid_str = NULL;
fbbeb65a
TG
1475 int r, ifindex;
1476
1477 assert(rtnl);
1478 assert(message);
1479 assert(m);
1480
45af44d4
TG
1481 if (sd_rtnl_message_is_error(message)) {
1482 r = sd_rtnl_message_get_errno(message);
1483 if (r < 0)
1484 log_warning_errno(r, "rtnl: failed to receive address: %m");
1485
1486 return 0;
1487 }
1488
fbbeb65a
TG
1489 r = sd_rtnl_message_get_type(message, &type);
1490 if (r < 0) {
1491 log_warning("rtnl: could not get message type");
1492 return 0;
1493 }
1494
1495 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
45af44d4
TG
1496 if (r < 0) {
1497 log_warning_errno(r, "rtnl: could not get ifindex: %m");
1498 return 0;
1499 } else if (ifindex <= 0) {
1500 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
fbbeb65a
TG
1501 return 0;
1502 } else {
1503 r = link_get(m, ifindex, &link);
1504 if (r < 0 || !link) {
6a24f148
TG
1505 /* when enumerating we might be out of sync, but we will
1506 * get the address again, so just ignore it */
1507 if (!m->enumerating)
1508 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
fbbeb65a
TG
1509 return 0;
1510 }
1511 }
1512
1513 r = address_new_dynamic(&address);
1514 if (r < 0)
393c0c5e 1515 return r;
fbbeb65a
TG
1516
1517 r = sd_rtnl_message_addr_get_family(message, &address->family);
1518 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
5a8bcb67 1519 log_link_warning(link, "rtnl: received address with invalid family, ignoring");
fbbeb65a
TG
1520 return 0;
1521 }
1522
1523 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1524 if (r < 0) {
5a8bcb67 1525 log_link_warning(link, "rtnl: received address with invalid prefixlen, ignoring");
e375dcde
TG
1526 return 0;
1527 }
1528
1529 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1530 if (r < 0) {
5a8bcb67 1531 log_link_warning(link, "rtnl: received address with invalid scope, ignoring");
fbbeb65a
TG
1532 return 0;
1533 }
1534
81163121
TG
1535 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1536 if (r < 0) {
5a8bcb67 1537 log_link_warning(link, "rtnl: received address with invalid flags, ignoring");
81163121
TG
1538 return 0;
1539 }
1540
fbbeb65a
TG
1541 switch (address->family) {
1542 case AF_INET:
5a8bcb67 1543 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
fbbeb65a 1544 if (r < 0) {
5a8bcb67 1545 log_link_warning(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1546 return 0;
1547 }
1548
1549 break;
1550
1551 case AF_INET6:
5a8bcb67 1552 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
fbbeb65a 1553 if (r < 0) {
5a8bcb67 1554 log_link_warning(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1555 return 0;
1556 }
1557
1558 break;
1559
1560 default:
1561 assert_not_reached("invalid address family");
1562 }
1563
5a8bcb67 1564 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
79008bdd 1565 log_link_warning(link, "could not print address");
fbbeb65a
TG
1566 return 0;
1567 }
1568
5a8bcb67 1569 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo);
c6d3b303
TG
1570 if (r >= 0) {
1571 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1572 valid_str = "ever";
1573 else
1574 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1575 address->cinfo.ifa_valid * USEC_PER_SEC,
1576 USEC_PER_SEC);
1577 }
1578
5a8bcb67
LP
1579 existing = link_get_equal_address(link, address);
1580
1581 switch (type) {
1582 case RTM_NEWADDR:
1583 if (existing) {
1584 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
428fd0a7 1585
428fd0a7 1586
5a8bcb67
LP
1587 existing->scope = address->scope;
1588 existing->flags = address->flags;
1589 existing->cinfo = address->cinfo;
428fd0a7 1590
5a8bcb67
LP
1591 } else {
1592 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
428fd0a7 1593
5a8bcb67
LP
1594 LIST_PREPEND(addresses, link->addresses, address);
1595 address_establish(address, link);
fbbeb65a 1596
5a8bcb67 1597 address = NULL;
428fd0a7 1598
5a8bcb67
LP
1599 link_save(link);
1600 }
f5602be9 1601
428fd0a7 1602 break;
5a8bcb67 1603
fbbeb65a 1604 case RTM_DELADDR:
428fd0a7 1605
5a8bcb67
LP
1606 if (existing) {
1607 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1608 address_release(existing, link);
1609 LIST_REMOVE(addresses, link->addresses, existing);
1610 address_free(existing);
393c0c5e 1611 } else
5a8bcb67 1612 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
f5602be9 1613
fbbeb65a
TG
1614 break;
1615 default:
1616 assert_not_reached("Received invalid RTNL message type");
1617 }
1618
1619 return 1;
1620}
1621
505f8da7
TG
1622int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1623 Link *link;
1624 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1625 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1626 int r;
1627
1628 assert(m);
fbbeb65a 1629 assert(m->rtnl);
505f8da7
TG
1630 assert(message);
1631 assert(ret);
1632
1633 r = link_new(m, message, ret);
1634 if (r < 0)
1635 return r;
1636
1637 link = *ret;
1638
79008bdd 1639 log_link_debug(link, "link %d added", link->ifindex);
505f8da7
TG
1640
1641 if (detect_container(NULL) <= 0) {
1642 /* not in a container, udev will be around */
ae06ab10 1643 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7
TG
1644 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1645 if (!device) {
79008bdd 1646 log_link_warning(link,
3c9b8860 1647 "could not find udev device: %m");
9fecce80 1648 return -errno;
505f8da7
TG
1649 }
1650
3c4cb064 1651 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 1652 /* not yet ready */
79008bdd 1653 log_link_debug(link, "link pending udev initialization...");
505f8da7 1654 return 0;
3c4cb064 1655 }
505f8da7 1656
4f561e8e
TG
1657 r = link_initialized(link, device);
1658 if (r < 0)
1659 return r;
1660 } else {
5da8149f
TG
1661 /* we are calling a callback directly, so must take a ref */
1662 link_ref(link);
1663
4f561e8e
TG
1664 r = link_initialized_and_synced(m->rtnl, NULL, link);
1665 if (r < 0)
1666 return r;
1667 }
505f8da7 1668
a748b692
TG
1669 return 0;
1670}
1671
9c0a72f9
TG
1672static int link_carrier_gained(Link *link) {
1673 int r;
1674
1675 assert(link);
1676
1677 if (link->network) {
1678 r = link_acquire_conf(link);
1679 if (r < 0) {
1680 link_enter_failed(link);
1681 return r;
1682 }
1683 }
1684
1685 return 0;
1686}
1687
1688static int link_carrier_lost(Link *link) {
1689 int r;
1690
1691 assert(link);
1692
1693 r = link_stop_clients(link);
1694 if (r < 0) {
1695 link_enter_failed(link);
1696 return r;
1697 }
1698
1699 return 0;
1700}
1701
1702int link_carrier_reset(Link *link) {
1703 int r;
1704
1705 assert(link);
1706
1707 if (link_has_carrier(link)) {
1708 r = link_carrier_lost(link);
1709 if (r < 0)
1710 return r;
1711
1712 r = link_carrier_gained(link);
1713 if (r < 0)
1714 return r;
1715
1716 log_link_info(link, "reset carrier");
1717 }
1718
1719 return 0;
1720}
1721
1722
22936833 1723int link_update(Link *link, sd_rtnl_message *m) {
c49b33ac 1724 struct ether_addr mac;
ca4e095a 1725 const char *ifname;
afe7fd56 1726 uint32_t mtu;
a61bb41c 1727 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
1728 int r;
1729
dd3efc09 1730 assert(link);
b8941f74 1731 assert(link->ifname);
22936833
TG
1732 assert(m);
1733
7619683b
TG
1734 if (link->state == LINK_STATE_LINGER) {
1735 link_ref(link);
79008bdd 1736 log_link_info(link, "link readded");
e331e246 1737 link_set_state(link, LINK_STATE_ENSLAVING);
7619683b
TG
1738 }
1739
b8941f74
TG
1740 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1741 if (r >= 0 && !streq(ifname, link->ifname)) {
79008bdd 1742 log_link_info(link, "renamed to %s", ifname);
b8941f74
TG
1743
1744 free(link->ifname);
1745 link->ifname = strdup(ifname);
1746 if (!link->ifname)
1747 return -ENOMEM;
1748 }
1749
afe7fd56
TG
1750 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1751 if (r >= 0 && mtu > 0) {
1752 link->mtu = mtu;
1753 if (!link->original_mtu) {
1754 link->original_mtu = mtu;
79008bdd 1755 log_link_debug(link, "saved original MTU: %"
afe7fd56
TG
1756 PRIu32, link->original_mtu);
1757 }
1758
1759 if (link->dhcp_client) {
3c9b8860
TG
1760 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1761 link->mtu);
afe7fd56 1762 if (r < 0) {
79008bdd 1763 log_link_warning(link,
3c9b8860 1764 "Could not update MTU in DHCP client: %s",
afe7fd56
TG
1765 strerror(-r));
1766 return r;
1767 }
1768 }
9842de0d 1769 }
69629de9 1770
e9189a1f
TG
1771 /* The kernel may broadcast NEWLINK messages without the MAC address
1772 set, simply ignore them. */
c49b33ac 1773 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 1774 if (r >= 0) {
3c9b8860
TG
1775 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1776 ETH_ALEN)) {
c49b33ac 1777
3c9b8860
TG
1778 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1779 ETH_ALEN);
c49b33ac 1780
79008bdd 1781 log_link_debug(link, "MAC address: "
20861203
TG
1782 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1783 mac.ether_addr_octet[0],
1784 mac.ether_addr_octet[1],
1785 mac.ether_addr_octet[2],
1786 mac.ether_addr_octet[3],
1787 mac.ether_addr_octet[4],
1788 mac.ether_addr_octet[5]);
c49b33ac 1789
20861203
TG
1790 if (link->ipv4ll) {
1791 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1792 if (r < 0) {
79008bdd 1793 log_link_warning(link,
3c9b8860 1794 "Could not update MAC address in IPv4LL client: %s",
20861203
TG
1795 strerror(-r));
1796 return r;
1797 }
c49b33ac 1798 }
c49b33ac 1799
20861203 1800 if (link->dhcp_client) {
3c9b8860 1801 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
1802 (const uint8_t *) &link->mac,
1803 sizeof (link->mac),
1804 ARPHRD_ETHER);
20861203 1805 if (r < 0) {
79008bdd 1806 log_link_warning(link,
3c9b8860 1807 "Could not update MAC address in DHCP client: %s",
20861203
TG
1808 strerror(-r));
1809 return r;
1810 }
c49b33ac 1811 }
4138fb2c
PF
1812
1813 if (link->dhcp6_client) {
1814 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
1815 (const uint8_t *) &link->mac,
1816 sizeof (link->mac),
1817 ARPHRD_ETHER);
4138fb2c 1818 if (r < 0) {
79008bdd 1819 log_link_warning(link,
3c9b8860 1820 "Could not update MAC address in DHCPv6 client: %s",
4138fb2c
PF
1821 strerror(-r));
1822 return r;
1823 }
1824 }
c49b33ac 1825 }
4f882b2a
TG
1826 }
1827
a61bb41c
TG
1828 had_carrier = link_has_carrier(link);
1829
1830 r = link_update_flags(link, m);
1831 if (r < 0)
1832 return r;
1833
1834 carrier_gained = !had_carrier && link_has_carrier(link);
1835 carrier_lost = had_carrier && !link_has_carrier(link);
1836
1837 if (carrier_gained) {
79008bdd 1838 log_link_info(link, "gained carrier");
a61bb41c 1839
9c0a72f9
TG
1840 r = link_carrier_gained(link);
1841 if (r < 0)
1842 return r;
a61bb41c 1843 } else if (carrier_lost) {
79008bdd 1844 log_link_info(link, "lost carrier");
a61bb41c 1845
9c0a72f9
TG
1846 r = link_carrier_lost(link);
1847 if (r < 0)
a61bb41c 1848 return r;
9c0a72f9 1849
a61bb41c
TG
1850 }
1851
1852 return 0;
dd3efc09 1853}
fe8db0c5 1854
e375dcde 1855static void link_update_operstate(Link *link) {
e331e246 1856 LinkOperationalState operstate;
e375dcde
TG
1857 assert(link);
1858
1859 if (link->kernel_operstate == IF_OPER_DORMANT)
e331e246 1860 operstate = LINK_OPERSTATE_DORMANT;
a61bb41c 1861 else if (link_has_carrier(link)) {
e375dcde
TG
1862 Address *address;
1863 uint8_t scope = RT_SCOPE_NOWHERE;
1864
1865 /* if we have carrier, check what addresses we have */
1866 LIST_FOREACH(addresses, address, link->addresses) {
81163121
TG
1867 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1868 continue;
1869
e375dcde
TG
1870 if (address->scope < scope)
1871 scope = address->scope;
1872 }
1873
1874 if (scope < RT_SCOPE_SITE)
1875 /* universally accessible addresses found */
e331e246 1876 operstate = LINK_OPERSTATE_ROUTABLE;
e375dcde
TG
1877 else if (scope < RT_SCOPE_HOST)
1878 /* only link or site local addresses found */
e331e246 1879 operstate = LINK_OPERSTATE_DEGRADED;
e375dcde
TG
1880 else
1881 /* no useful addresses found */
e331e246 1882 operstate = LINK_OPERSTATE_CARRIER;
54cba0b1 1883 } else if (link->flags & IFF_UP)
e331e246 1884 operstate = LINK_OPERSTATE_NO_CARRIER;
54cba0b1 1885 else
e331e246
TG
1886 operstate = LINK_OPERSTATE_OFF;
1887
1888 if (link->operstate != operstate) {
1889 link->operstate = operstate;
1890 link_send_changed(link, "OperationalState", NULL);
1891 }
e375dcde
TG
1892}
1893
fe8db0c5 1894int link_save(Link *link) {
68a8723c 1895 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 1896 _cleanup_fclose_ FILE *f = NULL;
e375dcde 1897 const char *admin_state, *oper_state;
fe8db0c5
TG
1898 int r;
1899
1900 assert(link);
1901 assert(link->state_file);
68a8723c 1902 assert(link->lease_file);
bbf7c048
TG
1903 assert(link->manager);
1904
e375dcde
TG
1905 link_update_operstate(link);
1906
bbf7c048
TG
1907 r = manager_save(link->manager);
1908 if (r < 0)
1909 return r;
fe8db0c5 1910
370e9930
TG
1911 if (link->state == LINK_STATE_LINGER) {
1912 unlink(link->state_file);
1913 return 0;
1914 }
1915
deb2e523
TG
1916 admin_state = link_state_to_string(link->state);
1917 assert(admin_state);
1918
e375dcde
TG
1919 oper_state = link_operstate_to_string(link->operstate);
1920 assert(oper_state);
deb2e523 1921
fe8db0c5
TG
1922 r = fopen_temporary(link->state_file, &f, &temp_path);
1923 if (r < 0)
c2d6bd61 1924 return r;
fe8db0c5
TG
1925
1926 fchmod(fileno(f), 0644);
1927
1928 fprintf(f,
1929 "# This is private data. Do not parse.\n"
deb2e523 1930 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
1931 "OPER_STATE=%s\n",
1932 admin_state, oper_state);
fe8db0c5 1933
bcb7a07e 1934 if (link->network) {
ea352b40
LP
1935 char **address, **domain;
1936 bool space;
b0e39c82 1937
adc5b2e2
TG
1938 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
1939
b0e39c82 1940 fputs("DNS=", f);
ea352b40
LP
1941 space = false;
1942 STRV_FOREACH(address, link->network->dns) {
1943 if (space)
1944 fputc(' ', f);
1945 fputs(*address, f);
1946 space = true;
1947 }
d5314fff 1948
b0e39c82
TG
1949 if (link->network->dhcp_dns &&
1950 link->dhcp_lease) {
1951 const struct in_addr *addresses;
1952
1953 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1954 if (r > 0) {
ea352b40
LP
1955 if (space)
1956 fputc(' ', f);
b0e39c82 1957 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
1958 }
1959 }
1960
b0e39c82
TG
1961 fputs("\n", f);
1962
1963 fprintf(f, "NTP=");
ea352b40
LP
1964 space = false;
1965 STRV_FOREACH(address, link->network->ntp) {
1966 if (space)
1967 fputc(' ', f);
1968 fputs(*address, f);
1969 space = true;
1970 }
d5314fff 1971
b0e39c82
TG
1972 if (link->network->dhcp_ntp &&
1973 link->dhcp_lease) {
1974 const struct in_addr *addresses;
1975
1976 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1977 if (r > 0) {
ea352b40
LP
1978 if (space)
1979 fputc(' ', f);
b0e39c82 1980 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
1981 }
1982 }
1983
b0e39c82 1984 fputs("\n", f);
bd8f6538 1985
6192b846 1986 fprintf(f, "DOMAINS=");
ea352b40
LP
1987 space = false;
1988 STRV_FOREACH(domain, link->network->domains) {
1989 if (space)
1990 fputc(' ', f);
1991 fputs(*domain, f);
1992 space = true;
1993 }
d5314fff 1994
ad0734e8 1995 if (link->network->dhcp_domains &&
9b4d1882
TG
1996 link->dhcp_lease) {
1997 const char *domainname;
1998
1999 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 2000 if (r >= 0) {
ea352b40
LP
2001 if (space)
2002 fputc(' ', f);
6192b846 2003 fputs(domainname, f);
6192b846 2004 }
9b4d1882
TG
2005 }
2006
6192b846
TG
2007 fputs("\n", f);
2008
67272d15
TG
2009 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2010 yes_no(link->network->wildcard_domain));
2011
3c9b8860
TG
2012 fprintf(f, "LLMNR=%s\n",
2013 llmnr_support_to_string(link->network->llmnr));
bcb7a07e 2014 }
7374f9d8 2015
fe8db0c5 2016 if (link->dhcp_lease) {
d9876a52
TG
2017 assert(link->network);
2018
1dc24d5f 2019 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2020 if (r < 0)
c2d6bd61 2021 goto fail;
fe8db0c5 2022
7374f9d8 2023 fprintf(f,
b0e39c82
TG
2024 "DHCP_LEASE=%s\n",
2025 link->lease_file);
deb2e523 2026 } else
68a8723c 2027 unlink(link->lease_file);
fe8db0c5 2028
49699bac
SS
2029 if (link->lldp) {
2030 assert(link->network);
2031
2032 r = sd_lldp_save(link->lldp, link->lldp_file);
2033 if (r < 0)
2034 goto fail;
2035
2036 fprintf(f,
2037 "LLDP_FILE=%s\n",
2038 link->lldp_file);
2039 } else
2040 unlink(link->lldp_file);
2041
c2d6bd61
LP
2042 r = fflush_and_check(f);
2043 if (r < 0)
2044 goto fail;
fe8db0c5 2045
c2d6bd61 2046 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2047 r = -errno;
c2d6bd61 2048 goto fail;
fe8db0c5
TG
2049 }
2050
c2d6bd61 2051 return 0;
c2d6bd61 2052fail:
79008bdd 2053 log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
c2d6bd61
LP
2054 unlink(link->state_file);
2055 unlink(temp_path);
fe8db0c5
TG
2056 return r;
2057}
2058
2059static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 2060 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
2061 [LINK_STATE_ENSLAVING] = "configuring",
2062 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2063 [LINK_STATE_SETTING_ROUTES] = "configuring",
2064 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 2065 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 2066 [LINK_STATE_FAILED] = "failed",
370e9930 2067 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
2068};
2069
2070DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
2071
2072static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
2073 [LINK_OPERSTATE_OFF] = "off",
2074 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
2075 [LINK_OPERSTATE_DORMANT] = "dormant",
2076 [LINK_OPERSTATE_CARRIER] = "carrier",
2077 [LINK_OPERSTATE_DEGRADED] = "degraded",
2078 [LINK_OPERSTATE_ROUTABLE] = "routable",
2079};
2080
2081DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);