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