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