]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link.c
hwdb: adjust --help text to be more like other --help texts
[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
a245ced0 731static int link_set_bridge_fdb(Link *const link) {
b98b483b
AR
732 FdbEntry *fdb_entry;
733 int r = 0;
734
735 LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
ea6ec096 736 r = fdb_entry_configure(link, fdb_entry);
b98b483b
AR
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
7f77697a
TG
1100 r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
1101 if (r < 0) {
1102 log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
1103 return r;
1104 }
d0d6a4cd 1105
7f77697a
TG
1106 r = sd_rtnl_message_open_container(req, AF_INET6);
1107 if (r < 0) {
1108 log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
1109 return r;
1110 }
d0d6a4cd 1111
7f77697a 1112 if (!link_ipv6ll_enabled(link)) {
d0d6a4cd
TG
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 }
7f77697a 1118 }
d0d6a4cd 1119
7f77697a
TG
1120 if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
1121 r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
d0d6a4cd 1122 if (r < 0) {
7f77697a 1123 log_link_error(link, "Could not append IFLA_INET6_TOKEN: %s", strerror(-r));
d0d6a4cd
TG
1124 return r;
1125 }
7f77697a 1126 }
d0d6a4cd 1127
7f77697a
TG
1128 r = sd_rtnl_message_close_container(req);
1129 if (r < 0) {
1130 log_link_error(link, "Could not close AF_INET6 container: %s", strerror(-r));
1131 return r;
1132 }
1133
1134 r = sd_rtnl_message_close_container(req);
1135 if (r < 0) {
e2acdb6b 1136 log_link_error(link, "Could not close IFLA_AF_SPEC container: %s", strerror(-r));
7f77697a 1137 return r;
d0d6a4cd
TG
1138 }
1139
3c9b8860
TG
1140 r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1141 0, NULL);
f579559b 1142 if (r < 0) {
79008bdd 1143 log_link_error(link,
3c9b8860
TG
1144 "Could not send rtnetlink message: %s",
1145 strerror(-r));
f579559b
TG
1146 return r;
1147 }
1148
b226d99b
TG
1149 link_ref(link);
1150
f882c247
TG
1151 return 0;
1152}
1153
3f265037 1154static int link_joined(Link *link) {
f882c247
TG
1155 int r;
1156
ef1ba606 1157 assert(link);
f5be5601 1158 assert(link->network);
dd3efc09 1159
505f8da7
TG
1160 if (!(link->flags & IFF_UP)) {
1161 r = link_up(link);
1162 if (r < 0) {
1163 link_enter_failed(link);
1164 return r;
1165 }
ef1ba606 1166 }
f882c247 1167
e1853b00
SS
1168 if(link->network->bridge) {
1169 r = link_set_bridge(link);
1170 if (r < 0) {
00e8d83a 1171 log_link_error(link,
e1853b00
SS
1172 "Could not set bridge message: %s",
1173 strerror(-r));
1174 }
1175 }
1176
fb6730c4 1177 return link_enter_set_addresses(link);
02b59d57
TG
1178}
1179
3c9b8860
TG
1180static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1181 void *userdata) {
5da8149f 1182 _cleanup_link_unref_ Link *link = userdata;
02b59d57
TG
1183 int r;
1184
1746cf2a 1185 assert(link);
ef1ba606 1186 assert(link->network);
02b59d57 1187
52433f6b
TG
1188 link->enslaving --;
1189
5da8149f 1190 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
02b59d57
TG
1191 return 1;
1192
1193 r = sd_rtnl_message_get_errno(m);
856f962c 1194 if (r < 0 && r != -EEXIST) {
6c861f0a 1195 log_link_error_errno(link, -r, "%-*s: could not join netdev: %m", IFNAMSIZ, link->ifname);
ef1ba606
TG
1196 link_enter_failed(link);
1197 return 1;
ba179154 1198 } else
79008bdd 1199 log_link_debug(link, "joined netdev");
02b59d57 1200
856f962c 1201 if (link->enslaving <= 0)
3f265037 1202 link_joined(link);
02b59d57
TG
1203
1204 return 1;
1205}
1206
3f265037 1207static int link_enter_join_netdev(Link *link) {
6a0a2f86 1208 NetDev *netdev;
672682a6 1209 Iterator i;
02b59d57
TG
1210 int r;
1211
1212 assert(link);
1213 assert(link->network);
8434fd5c 1214 assert(link->state == LINK_STATE_PENDING);
02b59d57 1215
e331e246 1216 link_set_state(link, LINK_STATE_ENSLAVING);
02b59d57 1217
fe8db0c5
TG
1218 link_save(link);
1219
7951dea2
SS
1220 if (!link->network->bridge &&
1221 !link->network->bond &&
6a0a2f86 1222 hashmap_isempty(link->network->stacked_netdevs))
3f265037 1223 return link_joined(link);
02b59d57 1224
d9c67ea1 1225 if (link->network->bond) {
6c861f0a 1226 log_link_struct(link, LOG_DEBUG,
97578344 1227 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1228 IFNAMSIZ,
af4e9e2c 1229 link->ifname, link->network->bond->ifname,
aa9f1140 1230 NETDEVIF(link->network->bond),
52433f6b 1231 NULL);
449f7554 1232
3f265037 1233 r = netdev_join(link->network->bond, link, &netdev_join_handler);
52433f6b 1234 if (r < 0) {
6c861f0a 1235 log_link_struct(link, LOG_WARNING,
3f265037 1236 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1237 IFNAMSIZ,
3c9b8860
TG
1238 link->ifname, link->network->bond->ifname,
1239 strerror(-r),
aa9f1140 1240 NETDEVIF(link->network->bond),
52433f6b
TG
1241 NULL);
1242 link_enter_failed(link);
1243 return r;
1244 }
1245
0ad6148e
MO
1246 link->enslaving ++;
1247 }
1248
d9c67ea1 1249 if (link->network->bridge) {
6c861f0a 1250 log_link_struct(link, LOG_DEBUG,
97578344 1251 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1252 IFNAMSIZ,
af4e9e2c 1253 link->ifname, link->network->bridge->ifname,
aa9f1140 1254 NETDEVIF(link->network->bridge),
0ad6148e
MO
1255 NULL);
1256
3c9b8860
TG
1257 r = netdev_join(link->network->bridge, link,
1258 &netdev_join_handler);
0ad6148e 1259 if (r < 0) {
6c861f0a 1260 log_link_struct(link, LOG_WARNING,
3f265037 1261 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1262 IFNAMSIZ,
3c9b8860
TG
1263 link->ifname, link->network->bridge->ifname,
1264 strerror(-r),
aa9f1140 1265 NETDEVIF(link->network->bridge),
0ad6148e
MO
1266 NULL);
1267 link_enter_failed(link);
1268 return r;
1269 }
1270
52433f6b
TG
1271 link->enslaving ++;
1272 }
1273
6a0a2f86 1274 HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
6c861f0a 1275 log_link_struct(link, LOG_DEBUG,
97578344 1276 "MESSAGE=%-*s: enslaving by '%s'",
987efa17 1277 IFNAMSIZ,
3c9b8860
TG
1278 link->ifname, netdev->ifname, NETDEVIF(netdev),
1279 NULL);
7951dea2 1280
6a0a2f86 1281 r = netdev_join(netdev, link, &netdev_join_handler);
7951dea2 1282 if (r < 0) {
6c861f0a 1283 log_link_struct(link, LOG_WARNING,
3f265037 1284 "MESSAGE=%-*s: could not join netdev '%s': %s",
987efa17 1285 IFNAMSIZ,
3c9b8860
TG
1286 link->ifname, netdev->ifname,
1287 strerror(-r),
6a0a2f86 1288 NETDEVIF(netdev), NULL);
326cb406
SS
1289 link_enter_failed(link);
1290 return r;
1291 }
1292
326cb406
SS
1293 link->enslaving ++;
1294 }
1295
ef1ba606
TG
1296 return 0;
1297}
1298
769d324c 1299static int link_set_ipv4_forward(Link *link) {
5a8bcb67 1300 const char *p = NULL;
43c6d5ab 1301 bool b;
5a8bcb67
LP
1302 int r;
1303
43c6d5ab
LP
1304 b = link_ipv4_forward_enabled(link);
1305
63c372cb 1306 p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
43c6d5ab 1307 r = write_string_file_no_create(p, one_zero(b));
5a8bcb67 1308 if (r < 0)
43c6d5ab
LP
1309 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
1310
1311 if (b) {
1312 _cleanup_free_ char *buf = NULL;
1313
1314 /* If IP forwarding is turned on for this interface,
1315 * then propagate this to the global setting. Given
1316 * that turning this on has side-effects on other
1317 * fields, we'll try to avoid doing this unless
1318 * necessary, hence check the previous value
1319 * first. Note that we never turn this option off
1320 * again, since all interfaces we manage do not do
1321 * forwarding anyway by default, and ownership rules
1322 * of this control are so unclear. */
1323
1324 r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf);
1325 if (r < 0)
1326 log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m");
1327 else if (!streq(buf, "1")) {
1328 r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1");
1329 if (r < 0)
1330 log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m");
1331 }
1332 }
769d324c
LP
1333
1334 return 0;
1335}
1336
1337static int link_set_ipv6_forward(Link *link) {
1338 const char *p = NULL;
1339 int r;
1340
63c372cb 1341 p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
769d324c
LP
1342 r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
1343 if (r < 0)
1344 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
5a8bcb67
LP
1345
1346 return 0;
1347}
1348
a748b692 1349static int link_configure(Link *link) {
02b59d57
TG
1350 int r;
1351
ef1ba606 1352 assert(link);
b22d8a00 1353 assert(link->network);
8434fd5c 1354 assert(link->state == LINK_STATE_PENDING);
a748b692 1355
b98b483b
AR
1356 r = link_set_bridge_fdb(link);
1357 if (r < 0)
1358 return r;
1359
769d324c
LP
1360 r = link_set_ipv4_forward(link);
1361 if (r < 0)
1362 return r;
1363
1364 r = link_set_ipv6_forward(link);
5a8bcb67
LP
1365 if (r < 0)
1366 return r;
1367
78c958f8 1368 if (link_ipv4ll_enabled(link)) {
b22d8a00 1369 r = ipv4ll_configure(link);
eb34d4af
TG
1370 if (r < 0)
1371 return r;
1372 }
1373
78c958f8 1374 if (link_dhcp4_enabled(link)) {
3c9b8860 1375 r = dhcp4_configure(link);
eb34d4af
TG
1376 if (r < 0)
1377 return r;
eb34d4af
TG
1378 }
1379
78c958f8 1380 if (link_dhcp4_server_enabled(link)) {
dd43110f
TG
1381 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1382 if (r < 0)
1383 return r;
1384
1385 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1386 if (r < 0)
1387 return r;
dd43110f
TG
1388 }
1389
78c958f8 1390 if (link_dhcp6_enabled(link)) {
5c79bd79 1391 r = icmp6_configure(link);
4138fb2c
PF
1392 if (r < 0)
1393 return r;
1394 }
1395
ce43e484
SS
1396 if (link_lldp_enabled(link)) {
1397 r = sd_lldp_new(link->ifindex, link->ifname, &link->mac, &link->lldp);
1398 if (r < 0)
1399 return r;
1400
1401 r = sd_lldp_attach_event(link->lldp, NULL, 0);
1402 if (r < 0)
1403 return r;
49699bac
SS
1404
1405 r = sd_lldp_set_callback(link->lldp,
1406 lldp_handler, link);
1407 if (r < 0)
1408 return r;
ce43e484
SS
1409 }
1410
a61bb41c 1411 if (link_has_carrier(link)) {
1e9be60b
TG
1412 r = link_acquire_conf(link);
1413 if (r < 0)
1414 return r;
cc544d5f 1415 }
1e9be60b 1416
3f265037 1417 return link_enter_join_netdev(link);
505f8da7
TG
1418}
1419
3c9b8860
TG
1420static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1421 void *userdata) {
5da8149f 1422 _cleanup_link_unref_ Link *link = userdata;
505f8da7 1423 Network *network;
505f8da7
TG
1424 int r;
1425
1426 assert(link);
1427 assert(link->ifname);
1428 assert(link->manager);
1429
8434fd5c 1430 if (link->state != LINK_STATE_PENDING)
5da8149f 1431 return 1;
505f8da7 1432
79008bdd 1433 log_link_debug(link, "link state is up-to-date");
505f8da7 1434
3c9b8860
TG
1435 r = network_get(link->manager, link->udev_device, link->ifname,
1436 &link->mac, &network);
57bd6899
TG
1437 if (r == -ENOENT) {
1438 link_enter_unmanaged(link);
5da8149f 1439 return 1;
57bd6899
TG
1440 } else if (r < 0)
1441 return r;
505f8da7 1442
bd2efe92 1443 if (link->flags & IFF_LOOPBACK) {
d0d6a4cd
TG
1444 if (network->link_local != ADDRESS_FAMILY_NO)
1445 log_link_debug(link, "ignoring link-local autoconfiguration for loopback link");
78c958f8 1446
cb9fc36a 1447 if (network->dhcp != ADDRESS_FAMILY_NO)
79008bdd 1448 log_link_debug(link, "ignoring DHCP clients for loopback link");
78c958f8
TG
1449
1450 if (network->dhcp_server)
79008bdd 1451 log_link_debug(link, "ignoring DHCP server for loopback link");
bd2efe92
TG
1452 }
1453
505f8da7
TG
1454 r = network_apply(link->manager, network, link);
1455 if (r < 0)
1456 return r;
1457
a748b692
TG
1458 r = link_configure(link);
1459 if (r < 0)
1460 return r;
1461
5da8149f 1462 return 1;
505f8da7
TG
1463}
1464
4f561e8e
TG
1465int link_initialized(Link *link, struct udev_device *device) {
1466 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1467 int r;
1468
1469 assert(link);
1470 assert(link->manager);
1471 assert(link->manager->rtnl);
1472 assert(device);
1473
8434fd5c 1474 if (link->state != LINK_STATE_PENDING)
4f561e8e
TG
1475 return 0;
1476
679b3605
TG
1477 if (link->udev_device)
1478 return 0;
1479
79008bdd 1480 log_link_debug(link, "udev initialized link");
4f561e8e
TG
1481
1482 link->udev_device = udev_device_ref(device);
1483
3c9b8860
TG
1484 /* udev has initialized the link, but we don't know if we have yet
1485 * processed the NEWLINK messages with the latest state. Do a GETLINK,
1486 * when it returns we know that the pending NEWLINKs have already been
1487 * processed and that we are up-to-date */
4f561e8e 1488
3c9b8860
TG
1489 r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1490 link->ifindex);
4f561e8e
TG
1491 if (r < 0)
1492 return r;
1493
3c9b8860
TG
1494 r = sd_rtnl_call_async(link->manager->rtnl, req,
1495 link_initialized_and_synced, link, 0, NULL);
4f561e8e
TG
1496 if (r < 0)
1497 return r;
1498
5da8149f
TG
1499 link_ref(link);
1500
4f561e8e
TG
1501 return 0;
1502}
1503
5a8bcb67
LP
1504static Address* link_get_equal_address(Link *link, Address *needle) {
1505 Address *i;
1506
1507 assert(link);
1508 assert(needle);
1509
1510 LIST_FOREACH(addresses, i, link->addresses)
1511 if (address_equal(i, needle))
1512 return i;
1513
1514 return NULL;
1515}
1516
45af44d4 1517int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
fbbeb65a
TG
1518 Manager *m = userdata;
1519 Link *link = NULL;
1520 uint16_t type;
1521 _cleanup_address_free_ Address *address = NULL;
5a8bcb67
LP
1522 Address *existing;
1523 char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
c6d3b303 1524 const char *valid_str = NULL;
fbbeb65a
TG
1525 int r, ifindex;
1526
1527 assert(rtnl);
1528 assert(message);
1529 assert(m);
1530
45af44d4
TG
1531 if (sd_rtnl_message_is_error(message)) {
1532 r = sd_rtnl_message_get_errno(message);
1533 if (r < 0)
1534 log_warning_errno(r, "rtnl: failed to receive address: %m");
1535
1536 return 0;
1537 }
1538
fbbeb65a
TG
1539 r = sd_rtnl_message_get_type(message, &type);
1540 if (r < 0) {
1541 log_warning("rtnl: could not get message type");
1542 return 0;
1543 }
1544
1545 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
45af44d4
TG
1546 if (r < 0) {
1547 log_warning_errno(r, "rtnl: could not get ifindex: %m");
1548 return 0;
1549 } else if (ifindex <= 0) {
1550 log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
fbbeb65a
TG
1551 return 0;
1552 } else {
1553 r = link_get(m, ifindex, &link);
1554 if (r < 0 || !link) {
6a24f148
TG
1555 /* when enumerating we might be out of sync, but we will
1556 * get the address again, so just ignore it */
1557 if (!m->enumerating)
1558 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex);
fbbeb65a
TG
1559 return 0;
1560 }
1561 }
1562
1563 r = address_new_dynamic(&address);
1564 if (r < 0)
393c0c5e 1565 return r;
fbbeb65a
TG
1566
1567 r = sd_rtnl_message_addr_get_family(message, &address->family);
1568 if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
5a8bcb67 1569 log_link_warning(link, "rtnl: received address with invalid family, ignoring");
fbbeb65a
TG
1570 return 0;
1571 }
1572
1573 r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1574 if (r < 0) {
5a8bcb67 1575 log_link_warning(link, "rtnl: received address with invalid prefixlen, ignoring");
e375dcde
TG
1576 return 0;
1577 }
1578
1579 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1580 if (r < 0) {
5a8bcb67 1581 log_link_warning(link, "rtnl: received address with invalid scope, ignoring");
fbbeb65a
TG
1582 return 0;
1583 }
1584
81163121
TG
1585 r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1586 if (r < 0) {
5a8bcb67 1587 log_link_warning(link, "rtnl: received address with invalid flags, ignoring");
81163121
TG
1588 return 0;
1589 }
1590
fbbeb65a
TG
1591 switch (address->family) {
1592 case AF_INET:
5a8bcb67 1593 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
fbbeb65a 1594 if (r < 0) {
5a8bcb67 1595 log_link_warning(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1596 return 0;
1597 }
1598
1599 break;
1600
1601 case AF_INET6:
5a8bcb67 1602 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
fbbeb65a 1603 if (r < 0) {
5a8bcb67 1604 log_link_warning(link, "rtnl: received address without valid address, ignoring");
fbbeb65a
TG
1605 return 0;
1606 }
1607
1608 break;
1609
1610 default:
1611 assert_not_reached("invalid address family");
1612 }
1613
5a8bcb67 1614 if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
79008bdd 1615 log_link_warning(link, "could not print address");
fbbeb65a
TG
1616 return 0;
1617 }
1618
5a8bcb67 1619 r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO, &address->cinfo);
c6d3b303
TG
1620 if (r >= 0) {
1621 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1622 valid_str = "ever";
1623 else
1624 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1625 address->cinfo.ifa_valid * USEC_PER_SEC,
1626 USEC_PER_SEC);
1627 }
1628
5a8bcb67
LP
1629 existing = link_get_equal_address(link, address);
1630
1631 switch (type) {
1632 case RTM_NEWADDR:
1633 if (existing) {
1634 log_link_debug(link, "Updating address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
428fd0a7 1635
428fd0a7 1636
5a8bcb67
LP
1637 existing->scope = address->scope;
1638 existing->flags = address->flags;
1639 existing->cinfo = address->cinfo;
428fd0a7 1640
5a8bcb67
LP
1641 } else {
1642 log_link_debug(link, "Adding address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
428fd0a7 1643
5a8bcb67
LP
1644 LIST_PREPEND(addresses, link->addresses, address);
1645 address_establish(address, link);
fbbeb65a 1646
5a8bcb67 1647 address = NULL;
428fd0a7 1648
5a8bcb67
LP
1649 link_save(link);
1650 }
f5602be9 1651
428fd0a7 1652 break;
5a8bcb67 1653
fbbeb65a 1654 case RTM_DELADDR:
428fd0a7 1655
5a8bcb67
LP
1656 if (existing) {
1657 log_link_debug(link, "Removing address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
1658 address_release(existing, link);
1659 LIST_REMOVE(addresses, link->addresses, existing);
1660 address_free(existing);
393c0c5e 1661 } else
5a8bcb67 1662 log_link_warning(link, "Removing non-existent address: %s/%u (valid for %s)", buf, address->prefixlen, valid_str);
f5602be9 1663
fbbeb65a
TG
1664 break;
1665 default:
1666 assert_not_reached("Received invalid RTNL message type");
1667 }
1668
1669 return 1;
1670}
1671
505f8da7
TG
1672int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1673 Link *link;
1674 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1675 char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1676 int r;
1677
1678 assert(m);
fbbeb65a 1679 assert(m->rtnl);
505f8da7
TG
1680 assert(message);
1681 assert(ret);
1682
1683 r = link_new(m, message, ret);
1684 if (r < 0)
1685 return r;
1686
1687 link = *ret;
1688
79008bdd 1689 log_link_debug(link, "link %d added", link->ifindex);
505f8da7
TG
1690
1691 if (detect_container(NULL) <= 0) {
1692 /* not in a container, udev will be around */
ae06ab10 1693 sprintf(ifindex_str, "n%d", link->ifindex);
505f8da7
TG
1694 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1695 if (!device) {
79008bdd 1696 log_link_warning(link,
3c9b8860 1697 "could not find udev device: %m");
9fecce80 1698 return -errno;
505f8da7
TG
1699 }
1700
3c4cb064 1701 if (udev_device_get_is_initialized(device) <= 0) {
505f8da7 1702 /* not yet ready */
79008bdd 1703 log_link_debug(link, "link pending udev initialization...");
505f8da7 1704 return 0;
3c4cb064 1705 }
505f8da7 1706
4f561e8e
TG
1707 r = link_initialized(link, device);
1708 if (r < 0)
1709 return r;
1710 } else {
5da8149f
TG
1711 /* we are calling a callback directly, so must take a ref */
1712 link_ref(link);
1713
4f561e8e
TG
1714 r = link_initialized_and_synced(m->rtnl, NULL, link);
1715 if (r < 0)
1716 return r;
1717 }
505f8da7 1718
a748b692
TG
1719 return 0;
1720}
1721
9c0a72f9
TG
1722static int link_carrier_gained(Link *link) {
1723 int r;
1724
1725 assert(link);
1726
1727 if (link->network) {
1728 r = link_acquire_conf(link);
1729 if (r < 0) {
1730 link_enter_failed(link);
1731 return r;
1732 }
1733 }
1734
1735 return 0;
1736}
1737
1738static int link_carrier_lost(Link *link) {
1739 int r;
1740
1741 assert(link);
1742
1743 r = link_stop_clients(link);
1744 if (r < 0) {
1745 link_enter_failed(link);
1746 return r;
1747 }
1748
1749 return 0;
1750}
1751
1752int link_carrier_reset(Link *link) {
1753 int r;
1754
1755 assert(link);
1756
1757 if (link_has_carrier(link)) {
1758 r = link_carrier_lost(link);
1759 if (r < 0)
1760 return r;
1761
1762 r = link_carrier_gained(link);
1763 if (r < 0)
1764 return r;
1765
1766 log_link_info(link, "reset carrier");
1767 }
1768
1769 return 0;
1770}
1771
1772
22936833 1773int link_update(Link *link, sd_rtnl_message *m) {
c49b33ac 1774 struct ether_addr mac;
ca4e095a 1775 const char *ifname;
afe7fd56 1776 uint32_t mtu;
a61bb41c 1777 bool had_carrier, carrier_gained, carrier_lost;
22936833
TG
1778 int r;
1779
dd3efc09 1780 assert(link);
b8941f74 1781 assert(link->ifname);
22936833
TG
1782 assert(m);
1783
7619683b
TG
1784 if (link->state == LINK_STATE_LINGER) {
1785 link_ref(link);
79008bdd 1786 log_link_info(link, "link readded");
e331e246 1787 link_set_state(link, LINK_STATE_ENSLAVING);
7619683b
TG
1788 }
1789
b8941f74
TG
1790 r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1791 if (r >= 0 && !streq(ifname, link->ifname)) {
79008bdd 1792 log_link_info(link, "renamed to %s", ifname);
b8941f74
TG
1793
1794 free(link->ifname);
1795 link->ifname = strdup(ifname);
1796 if (!link->ifname)
1797 return -ENOMEM;
1798 }
1799
afe7fd56
TG
1800 r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1801 if (r >= 0 && mtu > 0) {
1802 link->mtu = mtu;
1803 if (!link->original_mtu) {
1804 link->original_mtu = mtu;
79008bdd 1805 log_link_debug(link, "saved original MTU: %"
afe7fd56
TG
1806 PRIu32, link->original_mtu);
1807 }
1808
1809 if (link->dhcp_client) {
3c9b8860
TG
1810 r = sd_dhcp_client_set_mtu(link->dhcp_client,
1811 link->mtu);
afe7fd56 1812 if (r < 0) {
79008bdd 1813 log_link_warning(link,
3c9b8860 1814 "Could not update MTU in DHCP client: %s",
afe7fd56
TG
1815 strerror(-r));
1816 return r;
1817 }
1818 }
9842de0d 1819 }
69629de9 1820
e9189a1f
TG
1821 /* The kernel may broadcast NEWLINK messages without the MAC address
1822 set, simply ignore them. */
c49b33ac 1823 r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
e9189a1f 1824 if (r >= 0) {
3c9b8860
TG
1825 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1826 ETH_ALEN)) {
c49b33ac 1827
3c9b8860
TG
1828 memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1829 ETH_ALEN);
c49b33ac 1830
79008bdd 1831 log_link_debug(link, "MAC address: "
20861203
TG
1832 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1833 mac.ether_addr_octet[0],
1834 mac.ether_addr_octet[1],
1835 mac.ether_addr_octet[2],
1836 mac.ether_addr_octet[3],
1837 mac.ether_addr_octet[4],
1838 mac.ether_addr_octet[5]);
c49b33ac 1839
20861203
TG
1840 if (link->ipv4ll) {
1841 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1842 if (r < 0) {
79008bdd 1843 log_link_warning(link,
3c9b8860 1844 "Could not update MAC address in IPv4LL client: %s",
20861203
TG
1845 strerror(-r));
1846 return r;
1847 }
c49b33ac 1848 }
c49b33ac 1849
20861203 1850 if (link->dhcp_client) {
3c9b8860 1851 r = sd_dhcp_client_set_mac(link->dhcp_client,
76253e73
DW
1852 (const uint8_t *) &link->mac,
1853 sizeof (link->mac),
1854 ARPHRD_ETHER);
20861203 1855 if (r < 0) {
79008bdd 1856 log_link_warning(link,
3c9b8860 1857 "Could not update MAC address in DHCP client: %s",
20861203
TG
1858 strerror(-r));
1859 return r;
1860 }
c49b33ac 1861 }
4138fb2c
PF
1862
1863 if (link->dhcp6_client) {
1864 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
76253e73
DW
1865 (const uint8_t *) &link->mac,
1866 sizeof (link->mac),
1867 ARPHRD_ETHER);
4138fb2c 1868 if (r < 0) {
79008bdd 1869 log_link_warning(link,
3c9b8860 1870 "Could not update MAC address in DHCPv6 client: %s",
4138fb2c
PF
1871 strerror(-r));
1872 return r;
1873 }
1874 }
c49b33ac 1875 }
4f882b2a
TG
1876 }
1877
a61bb41c
TG
1878 had_carrier = link_has_carrier(link);
1879
1880 r = link_update_flags(link, m);
1881 if (r < 0)
1882 return r;
1883
1884 carrier_gained = !had_carrier && link_has_carrier(link);
1885 carrier_lost = had_carrier && !link_has_carrier(link);
1886
1887 if (carrier_gained) {
79008bdd 1888 log_link_info(link, "gained carrier");
a61bb41c 1889
9c0a72f9
TG
1890 r = link_carrier_gained(link);
1891 if (r < 0)
1892 return r;
a61bb41c 1893 } else if (carrier_lost) {
79008bdd 1894 log_link_info(link, "lost carrier");
a61bb41c 1895
9c0a72f9
TG
1896 r = link_carrier_lost(link);
1897 if (r < 0)
a61bb41c 1898 return r;
9c0a72f9 1899
a61bb41c
TG
1900 }
1901
1902 return 0;
dd3efc09 1903}
fe8db0c5 1904
e375dcde 1905static void link_update_operstate(Link *link) {
e331e246 1906 LinkOperationalState operstate;
e375dcde
TG
1907 assert(link);
1908
1909 if (link->kernel_operstate == IF_OPER_DORMANT)
e331e246 1910 operstate = LINK_OPERSTATE_DORMANT;
a61bb41c 1911 else if (link_has_carrier(link)) {
e375dcde
TG
1912 Address *address;
1913 uint8_t scope = RT_SCOPE_NOWHERE;
1914
1915 /* if we have carrier, check what addresses we have */
1916 LIST_FOREACH(addresses, address, link->addresses) {
81163121
TG
1917 if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1918 continue;
1919
e375dcde
TG
1920 if (address->scope < scope)
1921 scope = address->scope;
1922 }
1923
1924 if (scope < RT_SCOPE_SITE)
1925 /* universally accessible addresses found */
e331e246 1926 operstate = LINK_OPERSTATE_ROUTABLE;
e375dcde
TG
1927 else if (scope < RT_SCOPE_HOST)
1928 /* only link or site local addresses found */
e331e246 1929 operstate = LINK_OPERSTATE_DEGRADED;
e375dcde
TG
1930 else
1931 /* no useful addresses found */
e331e246 1932 operstate = LINK_OPERSTATE_CARRIER;
54cba0b1 1933 } else if (link->flags & IFF_UP)
e331e246 1934 operstate = LINK_OPERSTATE_NO_CARRIER;
54cba0b1 1935 else
e331e246
TG
1936 operstate = LINK_OPERSTATE_OFF;
1937
1938 if (link->operstate != operstate) {
1939 link->operstate = operstate;
1940 link_send_changed(link, "OperationalState", NULL);
1941 }
e375dcde
TG
1942}
1943
fe8db0c5 1944int link_save(Link *link) {
68a8723c 1945 _cleanup_free_ char *temp_path = NULL;
fe8db0c5 1946 _cleanup_fclose_ FILE *f = NULL;
e375dcde 1947 const char *admin_state, *oper_state;
fe8db0c5
TG
1948 int r;
1949
1950 assert(link);
1951 assert(link->state_file);
68a8723c 1952 assert(link->lease_file);
bbf7c048
TG
1953 assert(link->manager);
1954
e375dcde
TG
1955 link_update_operstate(link);
1956
bbf7c048
TG
1957 r = manager_save(link->manager);
1958 if (r < 0)
1959 return r;
fe8db0c5 1960
370e9930
TG
1961 if (link->state == LINK_STATE_LINGER) {
1962 unlink(link->state_file);
1963 return 0;
1964 }
1965
deb2e523
TG
1966 admin_state = link_state_to_string(link->state);
1967 assert(admin_state);
1968
e375dcde
TG
1969 oper_state = link_operstate_to_string(link->operstate);
1970 assert(oper_state);
deb2e523 1971
fe8db0c5
TG
1972 r = fopen_temporary(link->state_file, &f, &temp_path);
1973 if (r < 0)
c2d6bd61 1974 return r;
fe8db0c5
TG
1975
1976 fchmod(fileno(f), 0644);
1977
1978 fprintf(f,
1979 "# This is private data. Do not parse.\n"
deb2e523 1980 "ADMIN_STATE=%s\n"
6dcaa6f5
TG
1981 "OPER_STATE=%s\n",
1982 admin_state, oper_state);
fe8db0c5 1983
bcb7a07e 1984 if (link->network) {
ea352b40
LP
1985 char **address, **domain;
1986 bool space;
b0e39c82 1987
adc5b2e2
TG
1988 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
1989
b0e39c82 1990 fputs("DNS=", f);
ea352b40
LP
1991 space = false;
1992 STRV_FOREACH(address, link->network->dns) {
1993 if (space)
1994 fputc(' ', f);
1995 fputs(*address, f);
1996 space = true;
1997 }
d5314fff 1998
b0e39c82
TG
1999 if (link->network->dhcp_dns &&
2000 link->dhcp_lease) {
2001 const struct in_addr *addresses;
2002
2003 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
2004 if (r > 0) {
ea352b40
LP
2005 if (space)
2006 fputc(' ', f);
b0e39c82 2007 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
2008 }
2009 }
2010
b0e39c82
TG
2011 fputs("\n", f);
2012
2013 fprintf(f, "NTP=");
ea352b40
LP
2014 space = false;
2015 STRV_FOREACH(address, link->network->ntp) {
2016 if (space)
2017 fputc(' ', f);
2018 fputs(*address, f);
2019 space = true;
2020 }
d5314fff 2021
b0e39c82
TG
2022 if (link->network->dhcp_ntp &&
2023 link->dhcp_lease) {
2024 const struct in_addr *addresses;
2025
2026 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
2027 if (r > 0) {
ea352b40
LP
2028 if (space)
2029 fputc(' ', f);
b0e39c82 2030 serialize_in_addrs(f, addresses, r);
b0e39c82
TG
2031 }
2032 }
2033
b0e39c82 2034 fputs("\n", f);
bd8f6538 2035
6192b846 2036 fprintf(f, "DOMAINS=");
ea352b40
LP
2037 space = false;
2038 STRV_FOREACH(domain, link->network->domains) {
2039 if (space)
2040 fputc(' ', f);
2041 fputs(*domain, f);
2042 space = true;
2043 }
d5314fff 2044
ad0734e8 2045 if (link->network->dhcp_domains &&
9b4d1882
TG
2046 link->dhcp_lease) {
2047 const char *domainname;
2048
2049 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
6192b846 2050 if (r >= 0) {
ea352b40
LP
2051 if (space)
2052 fputc(' ', f);
6192b846 2053 fputs(domainname, f);
6192b846 2054 }
9b4d1882
TG
2055 }
2056
6192b846
TG
2057 fputs("\n", f);
2058
67272d15
TG
2059 fprintf(f, "WILDCARD_DOMAIN=%s\n",
2060 yes_no(link->network->wildcard_domain));
2061
3c9b8860
TG
2062 fprintf(f, "LLMNR=%s\n",
2063 llmnr_support_to_string(link->network->llmnr));
bcb7a07e 2064 }
7374f9d8 2065
fe8db0c5 2066 if (link->dhcp_lease) {
d9876a52
TG
2067 assert(link->network);
2068
1dc24d5f 2069 r = sd_dhcp_lease_save(link->dhcp_lease, link->lease_file);
fe8db0c5 2070 if (r < 0)
c2d6bd61 2071 goto fail;
fe8db0c5 2072
7374f9d8 2073 fprintf(f,
b0e39c82
TG
2074 "DHCP_LEASE=%s\n",
2075 link->lease_file);
deb2e523 2076 } else
68a8723c 2077 unlink(link->lease_file);
fe8db0c5 2078
49699bac
SS
2079 if (link->lldp) {
2080 assert(link->network);
2081
2082 r = sd_lldp_save(link->lldp, link->lldp_file);
2083 if (r < 0)
2084 goto fail;
2085
2086 fprintf(f,
2087 "LLDP_FILE=%s\n",
2088 link->lldp_file);
2089 } else
2090 unlink(link->lldp_file);
2091
c2d6bd61
LP
2092 r = fflush_and_check(f);
2093 if (r < 0)
2094 goto fail;
fe8db0c5 2095
c2d6bd61 2096 if (rename(temp_path, link->state_file) < 0) {
fe8db0c5 2097 r = -errno;
c2d6bd61 2098 goto fail;
fe8db0c5
TG
2099 }
2100
c2d6bd61 2101 return 0;
c2d6bd61 2102fail:
79008bdd 2103 log_link_error(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
c2d6bd61
LP
2104 unlink(link->state_file);
2105 unlink(temp_path);
fe8db0c5
TG
2106 return r;
2107}
2108
2109static const char* const link_state_table[_LINK_STATE_MAX] = {
8434fd5c 2110 [LINK_STATE_PENDING] = "pending",
fe8db0c5
TG
2111 [LINK_STATE_ENSLAVING] = "configuring",
2112 [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2113 [LINK_STATE_SETTING_ROUTES] = "configuring",
2114 [LINK_STATE_CONFIGURED] = "configured",
57bd6899 2115 [LINK_STATE_UNMANAGED] = "unmanaged",
fe8db0c5 2116 [LINK_STATE_FAILED] = "failed",
370e9930 2117 [LINK_STATE_LINGER] = "linger",
fe8db0c5
TG
2118};
2119
2120DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
e375dcde
TG
2121
2122static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
d3df0e39
TG
2123 [LINK_OPERSTATE_OFF] = "off",
2124 [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
e375dcde
TG
2125 [LINK_OPERSTATE_DORMANT] = "dormant",
2126 [LINK_OPERSTATE_CARRIER] = "carrier",
2127 [LINK_OPERSTATE_DEGRADED] = "degraded",
2128 [LINK_OPERSTATE_ROUTABLE] = "routable",
2129};
2130
2131DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);