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