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