LCOV - code coverage report
Current view: top level - network - networkd-link.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 288 2183 13.2 %
Date: 2019-08-22 15:41:25 Functions: 19 114 16.7 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <netinet/in.h>
       4             : #include <linux/if.h>
       5             : #include <linux/if_arp.h>
       6             : #include <unistd.h>
       7             : 
       8             : #include "alloc-util.h"
       9             : #include "bus-util.h"
      10             : #include "dhcp-identifier.h"
      11             : #include "dhcp-lease-internal.h"
      12             : #include "env-file.h"
      13             : #include "fd-util.h"
      14             : #include "fileio.h"
      15             : #include "missing_network.h"
      16             : #include "netdev/bond.h"
      17             : #include "netdev/bridge.h"
      18             : #include "netdev/ipvlan.h"
      19             : #include "netdev/vrf.h"
      20             : #include "netlink-util.h"
      21             : #include "network-internal.h"
      22             : #include "networkd-can.h"
      23             : #include "networkd-dhcp-server.h"
      24             : #include "networkd-dhcp4.h"
      25             : #include "networkd-dhcp6.h"
      26             : #include "networkd-ipv4ll.h"
      27             : #include "networkd-ipv6-proxy-ndp.h"
      28             : #include "networkd-link-bus.h"
      29             : #include "networkd-link.h"
      30             : #include "networkd-lldp-tx.h"
      31             : #include "networkd-manager.h"
      32             : #include "networkd-ndisc.h"
      33             : #include "networkd-neighbor.h"
      34             : #include "networkd-radv.h"
      35             : #include "networkd-routing-policy-rule.h"
      36             : #include "set.h"
      37             : #include "socket-util.h"
      38             : #include "stdio-util.h"
      39             : #include "string-table.h"
      40             : #include "strv.h"
      41             : #include "sysctl-util.h"
      42             : #include "tmpfile-util.h"
      43             : #include "udev-util.h"
      44             : #include "util.h"
      45             : #include "virt.h"
      46             : 
      47           0 : uint32_t link_get_vrf_table(Link *link) {
      48           0 :         return link->network->vrf ? VRF(link->network->vrf)->table : RT_TABLE_MAIN;
      49             : }
      50             : 
      51           0 : uint32_t link_get_dhcp_route_table(Link *link) {
      52             :         /* When the interface is part of an VRF use the VRFs routing table, unless
      53             :          * another table is explicitly specified. */
      54           0 :         if (link->network->dhcp_route_table_set)
      55           0 :                 return link->network->dhcp_route_table;
      56           0 :         return link_get_vrf_table(link);
      57             : }
      58             : 
      59           0 : uint32_t link_get_ipv6_accept_ra_route_table(Link *link) {
      60           0 :         if (link->network->ipv6_accept_ra_route_table_set)
      61           0 :                 return link->network->ipv6_accept_ra_route_table;
      62           0 :         return link_get_vrf_table(link);
      63             : }
      64             : 
      65           0 : DUID* link_get_duid(Link *link) {
      66           0 :         if (link->network->duid.type != _DUID_TYPE_INVALID)
      67           0 :                 return &link->network->duid;
      68             :         else
      69           0 :                 return &link->manager->duid;
      70             : }
      71             : 
      72           0 : int link_sysctl_ipv6_enabled(Link *link) {
      73           0 :         _cleanup_free_ char *value = NULL;
      74             :         int r;
      75             : 
      76           0 :         assert(link);
      77           0 :         assert(link->ifname);
      78             : 
      79           0 :         if (link->sysctl_ipv6_enabled >= 0)
      80           0 :                 return link->sysctl_ipv6_enabled;
      81             : 
      82           0 :         const char *ifname = link->ifname; /* work around bogus gcc warning */
      83           0 :         r = sysctl_read_ip_property(AF_INET6, ifname, "disable_ipv6", &value);
      84           0 :         if (r < 0)
      85           0 :                 return log_link_warning_errno(link, r,
      86             :                                               "Failed to read net.ipv6.conf.%s.disable_ipv6 sysctl property: %m",
      87             :                                               ifname);
      88             : 
      89           0 :         link->sysctl_ipv6_enabled = value[0] == '0';
      90           0 :         return link->sysctl_ipv6_enabled;
      91             : }
      92             : 
      93           0 : static bool link_dhcp6_enabled(Link *link) {
      94           0 :         assert(link);
      95             : 
      96           0 :         if (!socket_ipv6_is_supported())
      97           0 :                 return false;
      98             : 
      99           0 :         if (link->flags & IFF_LOOPBACK)
     100           0 :                 return false;
     101             : 
     102           0 :         if (!link->network)
     103           0 :                 return false;
     104             : 
     105           0 :         if (link->network->bond)
     106           0 :                 return false;
     107             : 
     108           0 :         if (link->iftype == ARPHRD_CAN)
     109           0 :                 return false;
     110             : 
     111           0 :         if (link_sysctl_ipv6_enabled(link) == 0)
     112           0 :                 return false;
     113             : 
     114           0 :         return link->network->dhcp & ADDRESS_FAMILY_IPV6;
     115             : }
     116             : 
     117           0 : static bool link_dhcp4_enabled(Link *link) {
     118           0 :         assert(link);
     119             : 
     120           0 :         if (link->flags & IFF_LOOPBACK)
     121           0 :                 return false;
     122             : 
     123           0 :         if (!link->network)
     124           0 :                 return false;
     125             : 
     126           0 :         if (link->network->bond)
     127           0 :                 return false;
     128             : 
     129           0 :         if (link->iftype == ARPHRD_CAN)
     130           0 :                 return false;
     131             : 
     132           0 :         return link->network->dhcp & ADDRESS_FAMILY_IPV4;
     133             : }
     134             : 
     135           0 : static bool link_dhcp4_server_enabled(Link *link) {
     136           0 :         assert(link);
     137             : 
     138           0 :         if (link->flags & IFF_LOOPBACK)
     139           0 :                 return false;
     140             : 
     141           0 :         if (!link->network)
     142           0 :                 return false;
     143             : 
     144           0 :         if (link->network->bond)
     145           0 :                 return false;
     146             : 
     147           0 :         if (link->iftype == ARPHRD_CAN)
     148           0 :                 return false;
     149             : 
     150           0 :         return link->network->dhcp_server;
     151             : }
     152             : 
     153           0 : bool link_ipv4ll_enabled(Link *link, AddressFamily mask) {
     154           0 :         assert(link);
     155           0 :         assert((mask & ~(ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) == 0);
     156             : 
     157           0 :         if (link->flags & IFF_LOOPBACK)
     158           0 :                 return false;
     159             : 
     160           0 :         if (!link->network)
     161           0 :                 return false;
     162             : 
     163           0 :         if (link->iftype == ARPHRD_CAN)
     164           0 :                 return false;
     165             : 
     166           0 :         if (STRPTR_IN_SET(link->kind,
     167             :                           "vrf", "wireguard", "ipip", "gre", "ip6gre","ip6tnl", "sit", "vti",
     168             :                           "vti6", "nlmon", "xfrm"))
     169           0 :                 return false;
     170             : 
     171             :         /* L3 or L3S mode do not support ARP. */
     172           0 :         if (IN_SET(link_get_ipvlan_mode(link), NETDEV_IPVLAN_MODE_L3, NETDEV_IPVLAN_MODE_L3S))
     173           0 :                 return false;
     174             : 
     175           0 :         if (link->network->bond)
     176           0 :                 return false;
     177             : 
     178           0 :         return link->network->link_local & mask;
     179             : }
     180             : 
     181           0 : static bool link_ipv6ll_enabled(Link *link) {
     182           0 :         assert(link);
     183             : 
     184           0 :         if (!socket_ipv6_is_supported())
     185           0 :                 return false;
     186             : 
     187           0 :         if (link->flags & IFF_LOOPBACK)
     188           0 :                 return false;
     189             : 
     190           0 :         if (!link->network)
     191           0 :                 return false;
     192             : 
     193           0 :         if (link->iftype == ARPHRD_CAN)
     194           0 :                 return false;
     195             : 
     196           0 :         if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "nlmon"))
     197           0 :                 return false;
     198             : 
     199           0 :         if (link->network->bond)
     200           0 :                 return false;
     201             : 
     202           0 :         if (link_sysctl_ipv6_enabled(link) == 0)
     203           0 :                 return false;
     204             : 
     205           0 :         return link->network->link_local & ADDRESS_FAMILY_IPV6;
     206             : }
     207             : 
     208           0 : static bool link_ipv6_enabled(Link *link) {
     209           0 :         assert(link);
     210             : 
     211           0 :         if (!socket_ipv6_is_supported())
     212           0 :                 return false;
     213             : 
     214           0 :         if (link->network->bond)
     215           0 :                 return false;
     216             : 
     217           0 :         if (link_sysctl_ipv6_enabled(link) == 0)
     218           0 :                 return false;
     219             : 
     220           0 :         if (link->iftype == ARPHRD_CAN)
     221           0 :                 return false;
     222             : 
     223             :         /* DHCPv6 client will not be started if no IPv6 link-local address is configured. */
     224           0 :         return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
     225             : }
     226             : 
     227           0 : static bool link_radv_enabled(Link *link) {
     228           0 :         assert(link);
     229             : 
     230           0 :         if (!link_ipv6ll_enabled(link))
     231           0 :                 return false;
     232             : 
     233           0 :         return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE;
     234             : }
     235             : 
     236           0 : static bool link_ipv4_forward_enabled(Link *link) {
     237           0 :         assert(link);
     238             : 
     239           0 :         if (link->flags & IFF_LOOPBACK)
     240           0 :                 return false;
     241             : 
     242           0 :         if (!link->network)
     243           0 :                 return false;
     244             : 
     245           0 :         if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
     246           0 :                 return false;
     247             : 
     248           0 :         return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
     249             : }
     250             : 
     251           0 : static bool link_ipv6_forward_enabled(Link *link) {
     252           0 :         assert(link);
     253             : 
     254           0 :         if (!socket_ipv6_is_supported())
     255           0 :                 return false;
     256             : 
     257           0 :         if (link->flags & IFF_LOOPBACK)
     258           0 :                 return false;
     259             : 
     260           0 :         if (!link->network)
     261           0 :                 return false;
     262             : 
     263           0 :         if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
     264           0 :                 return false;
     265             : 
     266           0 :         if (link_sysctl_ipv6_enabled(link) == 0)
     267           0 :                 return false;
     268             : 
     269           0 :         return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
     270             : }
     271             : 
     272           0 : static bool link_proxy_arp_enabled(Link *link) {
     273           0 :         assert(link);
     274             : 
     275           0 :         if (link->flags & IFF_LOOPBACK)
     276           0 :                 return false;
     277             : 
     278           0 :         if (!link->network)
     279           0 :                 return false;
     280             : 
     281           0 :         if (link->network->proxy_arp < 0)
     282           0 :                 return false;
     283             : 
     284           0 :         return true;
     285             : }
     286             : 
     287           0 : static bool link_ipv6_accept_ra_enabled(Link *link) {
     288           0 :         assert(link);
     289             : 
     290           0 :         if (!socket_ipv6_is_supported())
     291           0 :                 return false;
     292             : 
     293           0 :         if (link->flags & IFF_LOOPBACK)
     294           0 :                 return false;
     295             : 
     296           0 :         if (!link->network)
     297           0 :                 return false;
     298             : 
     299           0 :         if (!link_ipv6ll_enabled(link))
     300           0 :                 return false;
     301             : 
     302             :         /* If unset use system default (enabled if local forwarding is disabled.
     303             :          * disabled if local forwarding is enabled).
     304             :          * If set, ignore or enforce RA independent of local forwarding state.
     305             :          */
     306           0 :         if (link->network->ipv6_accept_ra < 0)
     307             :                 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
     308           0 :                 return !link_ipv6_forward_enabled(link);
     309           0 :         else if (link->network->ipv6_accept_ra > 0)
     310             :                 /* accept RA even if ip_forward is enabled */
     311           0 :                 return true;
     312             :         else
     313             :                 /* ignore RA */
     314           0 :                 return false;
     315             : }
     316             : 
     317           0 : static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
     318           0 :         assert(link);
     319             : 
     320           0 :         if (!socket_ipv6_is_supported())
     321           0 :                 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
     322             : 
     323           0 :         if (link->flags & IFF_LOOPBACK)
     324           0 :                 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
     325             : 
     326           0 :         if (!link->network)
     327           0 :                 return _IPV6_PRIVACY_EXTENSIONS_INVALID;
     328             : 
     329           0 :         return link->network->ipv6_privacy_extensions;
     330             : }
     331             : 
     332           0 : static int link_enable_ipv6(Link *link) {
     333             :         bool disabled;
     334             :         int r;
     335             : 
     336           0 :         if (link->flags & IFF_LOOPBACK)
     337           0 :                 return 0;
     338             : 
     339           0 :         disabled = !link_ipv6_enabled(link);
     340             : 
     341           0 :         r = sysctl_write_ip_property_boolean(AF_INET6, link->ifname, "disable_ipv6", disabled);
     342           0 :         if (r < 0)
     343           0 :                 log_link_warning_errno(link, r, "Cannot %s IPv6: %m", enable_disable(!disabled));
     344             :         else
     345           0 :                 log_link_info(link, "IPv6 successfully %sd", enable_disable(!disabled));
     346             : 
     347           0 :         return 0;
     348             : }
     349             : 
     350           3 : static bool link_is_enslaved(Link *link) {
     351           3 :         if (link->flags & IFF_SLAVE)
     352             :                 /* Even if the link is not managed by networkd, honor IFF_SLAVE flag. */
     353           0 :                 return true;
     354             : 
     355           3 :         if (!link->network)
     356           3 :                 return false;
     357             : 
     358           0 :         if (link->master_ifindex > 0 && link->network->bridge)
     359           0 :                 return true;
     360             : 
     361             :         /* TODO: add conditions for other netdevs. */
     362             : 
     363           0 :         return false;
     364             : }
     365             : 
     366           0 : static void link_update_master_operstate(Link *link, NetDev *netdev) {
     367             :         Link *master;
     368             : 
     369           0 :         if (!netdev)
     370           0 :                 return;
     371             : 
     372           0 :         if (link_get(link->manager, netdev->ifindex, &master) < 0)
     373           0 :                 return;
     374             : 
     375           0 :         link_update_operstate(master, true);
     376             : }
     377             : 
     378           6 : void link_update_operstate(Link *link, bool also_update_master) {
     379             :         LinkOperationalState operstate;
     380             :         LinkCarrierState carrier_state;
     381             :         LinkAddressState address_state;
     382           6 :         _cleanup_strv_free_ char **p = NULL;
     383           6 :         uint8_t scope = RT_SCOPE_NOWHERE;
     384           6 :         bool changed = false;
     385             :         Address *address;
     386             :         Iterator i;
     387             : 
     388           6 :         assert(link);
     389             : 
     390           6 :         if (link->kernel_operstate == IF_OPER_DORMANT)
     391           0 :                 carrier_state = LINK_CARRIER_STATE_DORMANT;
     392           6 :         else if (link_has_carrier(link)) {
     393           3 :                 if (link_is_enslaved(link))
     394           0 :                         carrier_state = LINK_CARRIER_STATE_ENSLAVED;
     395             :                 else
     396           3 :                         carrier_state = LINK_CARRIER_STATE_CARRIER;
     397           3 :         } else if (link->flags & IFF_UP)
     398           2 :                 carrier_state = LINK_CARRIER_STATE_NO_CARRIER;
     399             :         else
     400           1 :                 carrier_state = LINK_CARRIER_STATE_OFF;
     401             : 
     402           6 :         if (carrier_state >= LINK_CARRIER_STATE_CARRIER) {
     403             :                 Link *slave;
     404             : 
     405           3 :                 SET_FOREACH(slave, link->slaves, i) {
     406           0 :                         link_update_operstate(slave, false);
     407             : 
     408           0 :                         if (slave->carrier_state < LINK_CARRIER_STATE_CARRIER)
     409           0 :                                 carrier_state = LINK_CARRIER_STATE_DEGRADED_CARRIER;
     410             :                 }
     411             :         }
     412             : 
     413           6 :         SET_FOREACH(address, link->addresses, i) {
     414           0 :                 if (!address_is_ready(address))
     415           0 :                         continue;
     416             : 
     417           0 :                 if (address->scope < scope)
     418           0 :                         scope = address->scope;
     419             :         }
     420             : 
     421             :         /* for operstate we also take foreign addresses into account */
     422           6 :         SET_FOREACH(address, link->addresses_foreign, i) {
     423           0 :                 if (!address_is_ready(address))
     424           0 :                         continue;
     425             : 
     426           0 :                 if (address->scope < scope)
     427           0 :                         scope = address->scope;
     428             :         }
     429             : 
     430           6 :         if (scope < RT_SCOPE_SITE)
     431             :                 /* universally accessible addresses found */
     432           0 :                 address_state = LINK_ADDRESS_STATE_ROUTABLE;
     433           6 :         else if (scope < RT_SCOPE_HOST)
     434             :                 /* only link or site local addresses found */
     435           0 :                 address_state = LINK_ADDRESS_STATE_DEGRADED;
     436             :         else
     437             :                 /* no useful addresses found */
     438           6 :                 address_state = LINK_ADDRESS_STATE_OFF;
     439             : 
     440             :         /* Mapping of address and carrier state vs operational state
     441             :          *                                                     carrier state
     442             :          *                          | off | no-carrier | dormant | degraded-carrier | carrier  | enslaved
     443             :          *                 ------------------------------------------------------------------------------
     444             :          *                 off      | off | no-carrier | dormant | degraded-carrier | carrier  | enslaved
     445             :          * address_state   degraded | off | no-carrier | dormant | degraded-carrier | degraded | enslaved
     446             :          *                 routable | off | no-carrier | dormant | degraded-carrier | routable | routable
     447             :          */
     448             : 
     449           6 :         if (carrier_state < LINK_CARRIER_STATE_CARRIER || address_state == LINK_ADDRESS_STATE_OFF)
     450           6 :                 operstate = (LinkOperationalState) carrier_state;
     451           0 :         else if (address_state == LINK_ADDRESS_STATE_ROUTABLE)
     452           0 :                 operstate = LINK_OPERSTATE_ROUTABLE;
     453           0 :         else if (carrier_state == LINK_CARRIER_STATE_CARRIER)
     454           0 :                 operstate = LINK_OPERSTATE_DEGRADED;
     455             :         else
     456           0 :                 operstate = LINK_OPERSTATE_ENSLAVED;
     457             : 
     458           6 :         if (link->carrier_state != carrier_state) {
     459           5 :                 link->carrier_state = carrier_state;
     460           5 :                 changed = true;
     461           5 :                 if (strv_extend(&p, "CarrierState") < 0)
     462           0 :                         log_oom();
     463             :         }
     464             : 
     465           6 :         if (link->address_state != address_state) {
     466           0 :                 link->address_state = address_state;
     467           0 :                 changed = true;
     468           0 :                 if (strv_extend(&p, "AddressState") < 0)
     469           0 :                         log_oom();
     470             :         }
     471             : 
     472           6 :         if (link->operstate != operstate) {
     473           5 :                 link->operstate = operstate;
     474           5 :                 changed = true;
     475           5 :                 if (strv_extend(&p, "OperationalState") < 0)
     476           0 :                         log_oom();
     477             :         }
     478             : 
     479           6 :         if (p)
     480           5 :                 link_send_changed_strv(link, p);
     481           6 :         if (changed)
     482           5 :                 link_dirty(link);
     483             : 
     484           6 :         if (also_update_master && link->network) {
     485           0 :                 link_update_master_operstate(link, link->network->bond);
     486           0 :                 link_update_master_operstate(link, link->network->bridge);
     487             :         }
     488           6 : }
     489             : 
     490             : #define FLAG_STRING(string, flag, old, new) \
     491             :         (((old ^ new) & flag) \
     492             :                 ? ((old & flag) ? (" -" string) : (" +" string)) \
     493             :                 : "")
     494             : 
     495          12 : static int link_update_flags(Link *link, sd_netlink_message *m, bool force_update_operstate) {
     496             :         unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
     497             :         uint8_t operstate;
     498             :         int r;
     499             : 
     500          12 :         assert(link);
     501             : 
     502          12 :         r = sd_rtnl_message_link_get_flags(m, &flags);
     503          12 :         if (r < 0)
     504           0 :                 return log_link_warning_errno(link, r, "Could not get link flags: %m");
     505             : 
     506          12 :         r = sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &operstate);
     507          12 :         if (r < 0)
     508             :                 /* if we got a message without operstate, take it to mean
     509             :                    the state was unchanged */
     510           0 :                 operstate = link->kernel_operstate;
     511             : 
     512          12 :         if (!force_update_operstate && (link->flags == flags) && (link->kernel_operstate == operstate))
     513           6 :                 return 0;
     514             : 
     515           6 :         if (link->flags != flags) {
     516           6 :                 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",
     517             :                                FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
     518             :                                FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
     519             :                                FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
     520             :                                FLAG_STRING("UP", IFF_UP, link->flags, flags),
     521             :                                FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
     522             :                                FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
     523             :                                FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
     524             :                                FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
     525             :                                FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
     526             :                                FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
     527             :                                FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
     528             :                                FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
     529             :                                FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
     530             :                                FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
     531             :                                FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
     532             :                                FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
     533             :                                FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
     534             :                                FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
     535             :                                FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
     536             : 
     537           6 :                 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
     538             :                                   IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
     539             :                                   IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
     540             :                                   IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
     541             :                                   IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
     542             :                                   IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
     543           6 :                 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
     544           6 :                 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
     545             : 
     546             :                 /* link flags are currently at most 18 bits, let's align to
     547             :                  * printing 20 */
     548           6 :                 if (unknown_flags_added)
     549           0 :                         log_link_debug(link,
     550             :                                        "Unknown link flags gained: %#.5x (ignoring)",
     551             :                                        unknown_flags_added);
     552             : 
     553           6 :                 if (unknown_flags_removed)
     554           0 :                         log_link_debug(link,
     555             :                                        "Unknown link flags lost: %#.5x (ignoring)",
     556             :                                        unknown_flags_removed);
     557             :         }
     558             : 
     559           6 :         link->flags = flags;
     560           6 :         link->kernel_operstate = operstate;
     561             : 
     562           6 :         link_update_operstate(link, true);
     563             : 
     564           6 :         return 0;
     565             : }
     566             : 
     567           6 : static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
     568           6 :         _cleanup_(link_unrefp) Link *link = NULL;
     569             :         uint16_t type;
     570           6 :         const char *ifname, *kind = NULL;
     571             :         int r, ifindex;
     572             :         unsigned short iftype;
     573             : 
     574           6 :         assert(manager);
     575           6 :         assert(message);
     576           6 :         assert(ret);
     577             : 
     578             :         /* check for link kind */
     579           6 :         r = sd_netlink_message_enter_container(message, IFLA_LINKINFO);
     580           6 :         if (r == 0) {
     581           3 :                 (void) sd_netlink_message_read_string(message, IFLA_INFO_KIND, &kind);
     582           3 :                 r = sd_netlink_message_exit_container(message);
     583           3 :                 if (r < 0)
     584           0 :                         return r;
     585             :         }
     586             : 
     587           6 :         r = sd_netlink_message_get_type(message, &type);
     588           6 :         if (r < 0)
     589           0 :                 return r;
     590           6 :         else if (type != RTM_NEWLINK)
     591           0 :                 return -EINVAL;
     592             : 
     593           6 :         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
     594           6 :         if (r < 0)
     595           0 :                 return r;
     596           6 :         else if (ifindex <= 0)
     597           0 :                 return -EINVAL;
     598             : 
     599           6 :         r = sd_rtnl_message_link_get_type(message, &iftype);
     600           6 :         if (r < 0)
     601           0 :                 return r;
     602             : 
     603           6 :         r = sd_netlink_message_read_string(message, IFLA_IFNAME, &ifname);
     604           6 :         if (r < 0)
     605           0 :                 return r;
     606             : 
     607           6 :         link = new(Link, 1);
     608           6 :         if (!link)
     609           0 :                 return -ENOMEM;
     610             : 
     611           6 :         *link = (Link) {
     612             :                 .n_ref = 1,
     613             :                 .manager = manager,
     614             :                 .state = LINK_STATE_PENDING,
     615             :                 .ifindex = ifindex,
     616             :                 .iftype = iftype,
     617             :                 .sysctl_ipv6_enabled = -1,
     618             : 
     619             :                 .n_dns = (unsigned) -1,
     620             :                 .dns_default_route = -1,
     621             :                 .llmnr = _RESOLVE_SUPPORT_INVALID,
     622             :                 .mdns = _RESOLVE_SUPPORT_INVALID,
     623             :                 .dnssec_mode = _DNSSEC_MODE_INVALID,
     624             :                 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
     625             :         };
     626             : 
     627           6 :         link->ifname = strdup(ifname);
     628           6 :         if (!link->ifname)
     629           0 :                 return -ENOMEM;
     630             : 
     631           6 :         if (kind) {
     632           3 :                 link->kind = strdup(kind);
     633           3 :                 if (!link->kind)
     634           0 :                         return -ENOMEM;
     635             :         }
     636             : 
     637           6 :         r = sd_netlink_message_read_u32(message, IFLA_MASTER, (uint32_t *)&link->master_ifindex);
     638           6 :         if (r < 0)
     639           5 :                 log_link_debug_errno(link, r, "New device has no master, continuing without");
     640             : 
     641           6 :         r = sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
     642           6 :         if (r < 0)
     643           1 :                 log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
     644             : 
     645           6 :         if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
     646           0 :                 return -ENOMEM;
     647             : 
     648           6 :         if (asprintf(&link->lease_file, "/run/systemd/netif/leases/%d", link->ifindex) < 0)
     649           0 :                 return -ENOMEM;
     650             : 
     651           6 :         if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
     652           0 :                 return -ENOMEM;
     653             : 
     654           6 :         r = hashmap_ensure_allocated(&manager->links, NULL);
     655           6 :         if (r < 0)
     656           0 :                 return r;
     657             : 
     658           6 :         r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
     659           6 :         if (r < 0)
     660           0 :                 return r;
     661             : 
     662           6 :         r = link_update_flags(link, message, false);
     663           6 :         if (r < 0)
     664           0 :                 return r;
     665             : 
     666           6 :         *ret = TAKE_PTR(link);
     667             : 
     668           6 :         return 0;
     669             : }
     670             : 
     671           6 : void link_ntp_settings_clear(Link *link) {
     672           6 :         link->ntp = strv_free(link->ntp);
     673           6 : }
     674             : 
     675           6 : void link_dns_settings_clear(Link *link) {
     676           6 :         link->dns = mfree(link->dns);
     677           6 :         link->n_dns = (unsigned) -1;
     678             : 
     679           6 :         link->search_domains = ordered_set_free_free(link->search_domains);
     680           6 :         link->route_domains = ordered_set_free_free(link->route_domains);
     681             : 
     682           6 :         link->dns_default_route = -1;
     683           6 :         link->llmnr = _RESOLVE_SUPPORT_INVALID;
     684           6 :         link->mdns = _RESOLVE_SUPPORT_INVALID;
     685           6 :         link->dnssec_mode = _DNSSEC_MODE_INVALID;
     686           6 :         link->dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID;
     687             : 
     688           6 :         link->dnssec_negative_trust_anchors = set_free_free(link->dnssec_negative_trust_anchors);
     689           6 : }
     690             : 
     691           6 : static Link *link_free(Link *link) {
     692             :         Address *address;
     693             : 
     694           6 :         assert(link);
     695             : 
     696           6 :         link_ntp_settings_clear(link);
     697           6 :         link_dns_settings_clear(link);
     698             : 
     699           6 :         link->routes = set_free_with_destructor(link->routes, route_free);
     700           6 :         link->routes_foreign = set_free_with_destructor(link->routes_foreign, route_free);
     701             : 
     702           6 :         link->neighbors = set_free_with_destructor(link->neighbors, neighbor_free);
     703           6 :         link->neighbors_foreign = set_free_with_destructor(link->neighbors_foreign, neighbor_free);
     704             : 
     705           6 :         link->addresses = set_free_with_destructor(link->addresses, address_free);
     706           6 :         link->addresses_foreign = set_free_with_destructor(link->addresses_foreign, address_free);
     707             : 
     708           6 :         while ((address = link->pool_addresses)) {
     709           0 :                 LIST_REMOVE(addresses, link->pool_addresses, address);
     710           0 :                 address_free(address);
     711             :         }
     712             : 
     713           6 :         sd_dhcp_server_unref(link->dhcp_server);
     714           6 :         sd_dhcp_client_unref(link->dhcp_client);
     715           6 :         sd_dhcp_lease_unref(link->dhcp_lease);
     716           6 :         set_free(link->dhcp_routes);
     717             : 
     718           6 :         link_lldp_emit_stop(link);
     719             : 
     720           6 :         free(link->lease_file);
     721             : 
     722           6 :         sd_lldp_unref(link->lldp);
     723           6 :         free(link->lldp_file);
     724             : 
     725           6 :         ndisc_flush(link);
     726             : 
     727           6 :         sd_ipv4ll_unref(link->ipv4ll);
     728           6 :         sd_dhcp6_client_unref(link->dhcp6_client);
     729           6 :         sd_ndisc_unref(link->ndisc);
     730           6 :         sd_radv_unref(link->radv);
     731             : 
     732           6 :         free(link->ifname);
     733           6 :         free(link->kind);
     734             : 
     735           6 :         (void) unlink(link->state_file);
     736           6 :         free(link->state_file);
     737             : 
     738           6 :         sd_device_unref(link->sd_device);
     739             : 
     740           6 :         hashmap_free(link->bound_to_links);
     741           6 :         hashmap_free(link->bound_by_links);
     742             : 
     743           6 :         set_free_with_destructor(link->slaves, link_unref);
     744             : 
     745           6 :         network_unref(link->network);
     746             : 
     747           6 :         return mfree(link);
     748             : }
     749             : 
     750          28 : DEFINE_TRIVIAL_REF_UNREF_FUNC(Link, link, link_free);
     751             : 
     752           6 : int link_get(Manager *m, int ifindex, Link **ret) {
     753             :         Link *link;
     754             : 
     755           6 :         assert(m);
     756           6 :         assert(ifindex);
     757           6 :         assert(ret);
     758             : 
     759           6 :         link = hashmap_get(m->links, INT_TO_PTR(ifindex));
     760           6 :         if (!link)
     761           6 :                 return -ENODEV;
     762             : 
     763           0 :         *ret = link;
     764             : 
     765           0 :         return 0;
     766             : }
     767             : 
     768           6 : void link_set_state(Link *link, LinkState state) {
     769           6 :         assert(link);
     770             : 
     771           6 :         if (link->state == state)
     772           0 :                 return;
     773             : 
     774           6 :         log_link_debug(link, "State changed: %s -> %s",
     775             :                        link_state_to_string(link->state),
     776             :                        link_state_to_string(state));
     777             : 
     778           6 :         link->state = state;
     779             : 
     780           6 :         link_send_changed(link, "AdministrativeState", NULL);
     781             : }
     782             : 
     783           0 : static void link_enter_unmanaged(Link *link) {
     784           0 :         assert(link);
     785             : 
     786           0 :         link_set_state(link, LINK_STATE_UNMANAGED);
     787             : 
     788           0 :         link_dirty(link);
     789           0 : }
     790             : 
     791           6 : int link_stop_clients(Link *link, bool may_keep_dhcp) {
     792           6 :         int r = 0, k;
     793             : 
     794           6 :         assert(link);
     795           6 :         assert(link->manager);
     796           6 :         assert(link->manager->event);
     797             : 
     798           6 :         dhcp4_release_old_lease(link);
     799             : 
     800           6 :         if (link->dhcp_client && (!may_keep_dhcp || !link->network ||
     801           0 :                                   !FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP))) {
     802           0 :                 k = sd_dhcp_client_stop(link->dhcp_client);
     803           0 :                 if (k < 0)
     804           0 :                         r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
     805             :         }
     806             : 
     807           6 :         if (link->ipv4ll) {
     808           0 :                 k = sd_ipv4ll_stop(link->ipv4ll);
     809           0 :                 if (k < 0)
     810           0 :                         r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
     811             :         }
     812             : 
     813           6 :         if (link->dhcp6_client) {
     814           0 :                 k = sd_dhcp6_client_stop(link->dhcp6_client);
     815           0 :                 if (k < 0)
     816           0 :                         r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
     817             :         }
     818             : 
     819           6 :         if (link->ndisc) {
     820           0 :                 k = sd_ndisc_stop(link->ndisc);
     821           0 :                 if (k < 0)
     822           0 :                         r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
     823             :         }
     824             : 
     825           6 :         if (link->radv) {
     826           0 :                 k = sd_radv_stop(link->radv);
     827           0 :                 if (k < 0)
     828           0 :                         r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
     829             :         }
     830             : 
     831           6 :         link_lldp_emit_stop(link);
     832           6 :         return r;
     833             : }
     834             : 
     835           0 : void link_enter_failed(Link *link) {
     836           0 :         assert(link);
     837             : 
     838           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
     839           0 :                 return;
     840             : 
     841           0 :         log_link_warning(link, "Failed");
     842             : 
     843           0 :         link_set_state(link, LINK_STATE_FAILED);
     844             : 
     845           0 :         link_stop_clients(link, false);
     846             : 
     847           0 :         link_dirty(link);
     848             : }
     849             : 
     850           0 : static int link_join_netdevs_after_configured(Link *link) {
     851             :         NetDev *netdev;
     852             :         Iterator i;
     853             :         int r;
     854             : 
     855           0 :         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
     856           0 :                 if (netdev->ifindex > 0)
     857             :                         /* Assume already enslaved. */
     858           0 :                         continue;
     859             : 
     860           0 :                 if (netdev_get_create_type(netdev) != NETDEV_CREATE_AFTER_CONFIGURED)
     861           0 :                         continue;
     862             : 
     863           0 :                 log_struct(LOG_DEBUG,
     864             :                            LOG_LINK_INTERFACE(link),
     865             :                            LOG_NETDEV_INTERFACE(netdev),
     866             :                            LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
     867             : 
     868           0 :                 r = netdev_join(netdev, link, NULL);
     869           0 :                 if (r < 0)
     870           0 :                         return log_struct_errno(LOG_WARNING, r,
     871             :                                                 LOG_LINK_INTERFACE(link),
     872             :                                                 LOG_NETDEV_INTERFACE(netdev),
     873             :                                                 LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
     874             :         }
     875             : 
     876           0 :         return 0;
     877             : }
     878             : 
     879           0 : static void link_enter_configured(Link *link) {
     880           0 :         assert(link);
     881           0 :         assert(link->network);
     882             : 
     883           0 :         if (link->state != LINK_STATE_CONFIGURING)
     884           0 :                 return;
     885             : 
     886           0 :         log_link_info(link, "Configured");
     887             : 
     888           0 :         link_set_state(link, LINK_STATE_CONFIGURED);
     889             : 
     890           0 :         (void) link_join_netdevs_after_configured(link);
     891             : 
     892           0 :         link_dirty(link);
     893             : }
     894             : 
     895           0 : static int link_request_set_routing_policy_rule(Link *link) {
     896           0 :         RoutingPolicyRule *rule, *rrule = NULL;
     897             :         int r;
     898             : 
     899           0 :         assert(link);
     900           0 :         assert(link->network);
     901             : 
     902           0 :         link->routing_policy_rules_configured = false;
     903             : 
     904           0 :         LIST_FOREACH(rules, rule, link->network->rules) {
     905           0 :                 r = routing_policy_rule_get(link->manager, rule, &rrule);
     906           0 :                 if (r >= 0) {
     907           0 :                         if (r == 0)
     908           0 :                                 (void) routing_policy_rule_make_local(link->manager, rrule);
     909           0 :                         continue;
     910             :                 }
     911             : 
     912           0 :                 r = routing_policy_rule_configure(rule, link, NULL);
     913           0 :                 if (r < 0)
     914           0 :                         return log_link_warning_errno(link, r, "Could not set routing policy rules: %m");
     915           0 :                 if (r > 0)
     916           0 :                         link->routing_policy_rule_messages++;
     917             :         }
     918             : 
     919           0 :         routing_policy_rule_purge(link->manager, link);
     920           0 :         if (link->routing_policy_rule_messages == 0) {
     921           0 :                 link->routing_policy_rules_configured = true;
     922           0 :                 link_check_ready(link);
     923             :         } else {
     924           0 :                 log_link_debug(link, "Setting routing policy rules");
     925           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
     926             :         }
     927             : 
     928           0 :         return 0;
     929             : }
     930             : 
     931           0 : static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
     932             :         int r;
     933             : 
     934           0 :         assert(link);
     935           0 :         assert(link->route_messages > 0);
     936           0 :         assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
     937             :                       LINK_STATE_FAILED, LINK_STATE_LINGER));
     938             : 
     939           0 :         link->route_messages--;
     940             : 
     941           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
     942           0 :                 return 1;
     943             : 
     944           0 :         r = sd_netlink_message_get_errno(m);
     945           0 :         if (r < 0 && r != -EEXIST) {
     946           0 :                 log_link_warning_errno(link, r, "Could not set route: %m");
     947           0 :                 link_enter_failed(link);
     948           0 :                 return 1;
     949             :         }
     950             : 
     951           0 :         if (link->route_messages == 0) {
     952           0 :                 log_link_debug(link, "Routes set");
     953           0 :                 link->static_routes_configured = true;
     954           0 :                 link_check_ready(link);
     955             :         }
     956             : 
     957           0 :         return 1;
     958             : }
     959             : 
     960           0 : int link_request_set_routes(Link *link) {
     961             :         enum {
     962             :                 PHASE_NON_GATEWAY, /* First phase: Routes without a gateway */
     963             :                 PHASE_GATEWAY,     /* Second phase: Routes with a gateway */
     964             :                 _PHASE_MAX
     965             :         } phase;
     966             :         Route *rt;
     967             :         int r;
     968             : 
     969           0 :         assert(link);
     970           0 :         assert(link->network);
     971           0 :         assert(link->addresses_configured);
     972           0 :         assert(link->address_messages == 0);
     973           0 :         assert(link->state != _LINK_STATE_INVALID);
     974             : 
     975           0 :         link->static_routes_configured = false;
     976             : 
     977           0 :         if (!link_has_carrier(link) && !link->network->configure_without_carrier)
     978             :                 /* During configuring addresses, the link lost its carrier. As networkd is dropping
     979             :                  * the addresses now, let's not configure the routes either. */
     980           0 :                 return 0;
     981             : 
     982           0 :         r = link_request_set_routing_policy_rule(link);
     983           0 :         if (r < 0)
     984           0 :                 return r;
     985             : 
     986             :         /* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
     987           0 :         for (phase = 0; phase < _PHASE_MAX; phase++)
     988           0 :                 LIST_FOREACH(routes, rt, link->network->static_routes) {
     989             : 
     990           0 :                         if (in_addr_is_null(rt->family, &rt->gw) != (phase == PHASE_NON_GATEWAY))
     991           0 :                                 continue;
     992             : 
     993           0 :                         r = route_configure(rt, link, route_handler);
     994           0 :                         if (r < 0)
     995           0 :                                 return log_link_warning_errno(link, r, "Could not set routes: %m");
     996           0 :                         if (r > 0)
     997           0 :                                 link->route_messages++;
     998             :                 }
     999             : 
    1000           0 :         if (link->route_messages == 0) {
    1001           0 :                 link->static_routes_configured = true;
    1002           0 :                 link_check_ready(link);
    1003             :         } else {
    1004           0 :                 log_link_debug(link, "Setting routes");
    1005           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
    1006             :         }
    1007             : 
    1008           0 :         return 0;
    1009             : }
    1010             : 
    1011           0 : void link_check_ready(Link *link) {
    1012             :         Address *a;
    1013             :         Iterator i;
    1014             :         int r;
    1015             : 
    1016           0 :         assert(link);
    1017             : 
    1018           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1019           0 :                 return;
    1020             : 
    1021           0 :         if (!link->network)
    1022           0 :                 return;
    1023             : 
    1024           0 :         if (!link->addresses_configured)
    1025           0 :                 return;
    1026             : 
    1027           0 :         if (!link->neighbors_configured)
    1028           0 :                 return;
    1029             : 
    1030           0 :         SET_FOREACH(a, link->addresses, i)
    1031           0 :                 if (!address_is_ready(a))
    1032           0 :                         return;
    1033             : 
    1034           0 :         if (!link->addresses_ready) {
    1035           0 :                 link->addresses_ready = true;
    1036           0 :                 r = link_request_set_routes(link);
    1037           0 :                 if (r < 0)
    1038           0 :                         link_enter_failed(link);
    1039           0 :                 return;
    1040             :         }
    1041             : 
    1042           0 :         if (!link->static_routes_configured)
    1043           0 :                 return;
    1044             : 
    1045           0 :         if (!link->routing_policy_rules_configured)
    1046           0 :                 return;
    1047             : 
    1048           0 :         if (link_has_carrier(link) || !link->network->configure_without_carrier) {
    1049             : 
    1050           0 :                 if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !(link->ipv4ll_address && link->ipv4ll_route))
    1051           0 :                         return;
    1052             : 
    1053           0 :                 if (link_ipv6ll_enabled(link) &&
    1054           0 :                     in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address))
    1055           0 :                         return;
    1056             : 
    1057           0 :                 if ((link_dhcp4_enabled(link) || link_dhcp6_enabled(link)) &&
    1058           0 :                     !link->dhcp4_configured &&
    1059           0 :                     !link->dhcp6_configured &&
    1060           0 :                     !(link_ipv4ll_enabled(link, ADDRESS_FAMILY_FALLBACK_IPV4) && link->ipv4ll_address && link->ipv4ll_route))
    1061             :                         /* When DHCP is enabled, at least one protocol must provide an address, or
    1062             :                          * an IPv4ll fallback address must be configured. */
    1063           0 :                         return;
    1064             : 
    1065           0 :                 if (link_ipv6_accept_ra_enabled(link) && !link->ndisc_configured)
    1066           0 :                         return;
    1067             :         }
    1068             : 
    1069           0 :         if (link->state != LINK_STATE_CONFIGURED)
    1070           0 :                 link_enter_configured(link);
    1071             : 
    1072           0 :         return;
    1073             : }
    1074             : 
    1075           0 : static int link_request_set_neighbors(Link *link) {
    1076             :         Neighbor *neighbor;
    1077             :         int r;
    1078             : 
    1079           0 :         assert(link);
    1080           0 :         assert(link->network);
    1081           0 :         assert(link->state != _LINK_STATE_INVALID);
    1082             : 
    1083           0 :         link->neighbors_configured = false;
    1084             : 
    1085           0 :         LIST_FOREACH(neighbors, neighbor, link->network->neighbors) {
    1086           0 :                 r = neighbor_configure(neighbor, link, NULL);
    1087           0 :                 if (r < 0)
    1088           0 :                         return log_link_warning_errno(link, r, "Could not set neighbor: %m");
    1089             :         }
    1090             : 
    1091           0 :         if (link->neighbor_messages == 0) {
    1092           0 :                 link->neighbors_configured = true;
    1093           0 :                 link_check_ready(link);
    1094             :         } else {
    1095           0 :                 log_link_debug(link, "Setting neighbors");
    1096           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
    1097             :         }
    1098             : 
    1099           0 :         return 0;
    1100             : }
    1101             : 
    1102           0 : static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1103             :         int r;
    1104             : 
    1105           0 :         assert(rtnl);
    1106           0 :         assert(m);
    1107           0 :         assert(link);
    1108           0 :         assert(link->ifname);
    1109           0 :         assert(link->address_messages > 0);
    1110           0 :         assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
    1111             :                LINK_STATE_FAILED, LINK_STATE_LINGER));
    1112             : 
    1113           0 :         link->address_messages--;
    1114             : 
    1115           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1116           0 :                 return 1;
    1117             : 
    1118           0 :         r = sd_netlink_message_get_errno(m);
    1119           0 :         if (r < 0 && r != -EEXIST) {
    1120           0 :                 log_link_warning_errno(link, r, "could not set address: %m");
    1121           0 :                 link_enter_failed(link);
    1122           0 :                 return 1;
    1123           0 :         } else if (r >= 0)
    1124           0 :                 (void) manager_rtnl_process_address(rtnl, m, link->manager);
    1125             : 
    1126           0 :         if (link->address_messages == 0) {
    1127           0 :                 log_link_debug(link, "Addresses set");
    1128           0 :                 link->addresses_configured = true;
    1129           0 :                 link_check_ready(link);
    1130             :         }
    1131             : 
    1132           0 :         return 1;
    1133             : }
    1134             : 
    1135           0 : static int link_set_bridge_fdb(Link *link) {
    1136             :         FdbEntry *fdb_entry;
    1137             :         int r;
    1138             : 
    1139           0 :         LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) {
    1140           0 :                 r = fdb_entry_configure(link, fdb_entry);
    1141           0 :                 if (r < 0)
    1142           0 :                         return log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m");
    1143             :         }
    1144             : 
    1145           0 :         return 0;
    1146             : }
    1147             : 
    1148           0 : static int link_request_set_addresses(Link *link) {
    1149             :         AddressLabel *label;
    1150             :         Address *ad;
    1151             :         int r;
    1152             : 
    1153           0 :         assert(link);
    1154           0 :         assert(link->network);
    1155           0 :         assert(link->state != _LINK_STATE_INVALID);
    1156             : 
    1157             :         /* Reset all *_configured flags we are configuring. */
    1158           0 :         link->addresses_configured = false;
    1159           0 :         link->addresses_ready = false;
    1160           0 :         link->neighbors_configured = false;
    1161           0 :         link->static_routes_configured = false;
    1162           0 :         link->routing_policy_rules_configured = false;
    1163             : 
    1164           0 :         r = link_set_bridge_fdb(link);
    1165           0 :         if (r < 0)
    1166           0 :                 return r;
    1167             : 
    1168           0 :         r = link_request_set_neighbors(link);
    1169           0 :         if (r < 0)
    1170           0 :                 return r;
    1171             : 
    1172           0 :         LIST_FOREACH(addresses, ad, link->network->static_addresses) {
    1173             :                 bool update;
    1174             : 
    1175           0 :                 update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
    1176             : 
    1177           0 :                 r = address_configure(ad, link, address_handler, update);
    1178           0 :                 if (r < 0)
    1179           0 :                         return log_link_warning_errno(link, r, "Could not set addresses: %m");
    1180           0 :                 if (r > 0)
    1181           0 :                         link->address_messages++;
    1182             :         }
    1183             : 
    1184           0 :         LIST_FOREACH(labels, label, link->network->address_labels) {
    1185           0 :                 r = address_label_configure(label, link, NULL, false);
    1186           0 :                 if (r < 0)
    1187           0 :                         return log_link_warning_errno(link, r, "Could not set address label: %m");
    1188             : 
    1189           0 :                 link->address_label_messages++;
    1190             :         }
    1191             : 
    1192             :         /* now that we can figure out a default address for the dhcp server,
    1193             :            start it */
    1194           0 :         if (link_dhcp4_server_enabled(link) && (link->flags & IFF_UP)) {
    1195           0 :                 r = dhcp4_server_configure(link);
    1196           0 :                 if (r < 0)
    1197           0 :                         return r;
    1198           0 :                 log_link_debug(link, "Offering DHCPv4 leases");
    1199             :         }
    1200             : 
    1201           0 :         if (link->address_messages == 0) {
    1202           0 :                 link->addresses_configured = true;
    1203           0 :                 link_check_ready(link);
    1204             :         } else {
    1205           0 :                 log_link_debug(link, "Setting addresses");
    1206           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
    1207             :         }
    1208             : 
    1209           0 :         return 0;
    1210             : }
    1211             : 
    1212           0 : static int link_set_bridge_vlan(Link *link) {
    1213             :         int r;
    1214             : 
    1215           0 :         r = br_vlan_configure(link, link->network->pvid, link->network->br_vid_bitmap, link->network->br_untagged_bitmap);
    1216           0 :         if (r < 0)
    1217           0 :                 log_link_error_errno(link, r, "Failed to assign VLANs to bridge port: %m");
    1218             : 
    1219           0 :         return r;
    1220             : }
    1221             : 
    1222           0 : static int link_set_proxy_arp(Link *link) {
    1223             :         int r;
    1224             : 
    1225           0 :         if (!link_proxy_arp_enabled(link))
    1226           0 :                 return 0;
    1227             : 
    1228           0 :         r = sysctl_write_ip_property_boolean(AF_INET, link->ifname, "proxy_arp", link->network->proxy_arp > 0);
    1229           0 :         if (r < 0)
    1230           0 :                 log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
    1231             : 
    1232           0 :         return 0;
    1233             : }
    1234             : 
    1235             : static int link_configure_after_setting_mtu(Link *link);
    1236             : 
    1237           0 : static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1238             :         int r;
    1239             : 
    1240           0 :         assert(m);
    1241           0 :         assert(link);
    1242           0 :         assert(link->ifname);
    1243             : 
    1244           0 :         link->setting_mtu = false;
    1245             : 
    1246           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1247           0 :                 return 1;
    1248             : 
    1249           0 :         r = sd_netlink_message_get_errno(m);
    1250           0 :         if (r < 0)
    1251           0 :                 log_link_warning_errno(link, r, "Could not set MTU, ignoring: %m");
    1252             :         else
    1253           0 :                 log_link_debug(link, "Setting MTU done.");
    1254             : 
    1255           0 :         if (link->state == LINK_STATE_INITIALIZED) {
    1256           0 :                 r = link_configure_after_setting_mtu(link);
    1257           0 :                 if (r < 0)
    1258           0 :                         link_enter_failed(link);
    1259             :         }
    1260             : 
    1261           0 :         return 1;
    1262             : }
    1263             : 
    1264           0 : int link_set_mtu(Link *link, uint32_t mtu) {
    1265           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    1266             :         int r;
    1267             : 
    1268           0 :         assert(link);
    1269           0 :         assert(link->manager);
    1270           0 :         assert(link->manager->rtnl);
    1271             : 
    1272           0 :         if (mtu == 0 || link->setting_mtu)
    1273           0 :                 return 0;
    1274             : 
    1275           0 :         if (link->mtu == mtu)
    1276           0 :                 return 0;
    1277             : 
    1278           0 :         log_link_debug(link, "Setting MTU: %" PRIu32, mtu);
    1279             : 
    1280           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
    1281           0 :         if (r < 0)
    1282           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
    1283             : 
    1284             :         /* If IPv6 not configured (no static IPv6 address and IPv6LL autoconfiguration is disabled)
    1285             :          * for this interface, then disable IPv6 else enable it. */
    1286           0 :         (void) link_enable_ipv6(link);
    1287             : 
    1288             :         /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes
    1289             :          * on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */
    1290           0 :         if (link_ipv6_enabled(link) && mtu < IPV6_MIN_MTU) {
    1291             : 
    1292           0 :                 log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as "
    1293             :                                  "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m");
    1294             : 
    1295           0 :                 mtu = IPV6_MIN_MTU;
    1296             :         }
    1297             : 
    1298           0 :         r = sd_netlink_message_append_u32(req, IFLA_MTU, mtu);
    1299           0 :         if (r < 0)
    1300           0 :                 return log_link_error_errno(link, r, "Could not append MTU: %m");
    1301             : 
    1302           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, set_mtu_handler,
    1303             :                                link_netlink_destroy_callback, link);
    1304           0 :         if (r < 0)
    1305           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
    1306             : 
    1307           0 :         link_ref(link);
    1308           0 :         link->setting_mtu = true;
    1309             : 
    1310           0 :         return 0;
    1311             : }
    1312             : 
    1313           0 : static bool link_reduces_vlan_mtu(Link *link) {
    1314             :         /* See netif_reduces_vlan_mtu() in kernel. */
    1315           0 :         return streq_ptr(link->kind, "macsec");
    1316             : }
    1317             : 
    1318           0 : static uint32_t link_get_requested_mtu_by_stacked_netdevs(Link *link) {
    1319           0 :         uint32_t mtu = 0;
    1320             :         NetDev *dev;
    1321             :         Iterator i;
    1322             : 
    1323           0 :         HASHMAP_FOREACH(dev, link->network->stacked_netdevs, i)
    1324           0 :                 if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0)
    1325             :                         /* See vlan_dev_change_mtu() in kernel. */
    1326           0 :                         mtu = MAX(mtu, link_reduces_vlan_mtu(link) ? dev->mtu + 4 : dev->mtu);
    1327             : 
    1328           0 :                 else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu)
    1329             :                         /* See macvlan_change_mtu() in kernel. */
    1330           0 :                         mtu = dev->mtu;
    1331             : 
    1332           0 :         return mtu;
    1333             : }
    1334             : 
    1335           0 : static int link_configure_mtu(Link *link) {
    1336             :         uint32_t mtu;
    1337             : 
    1338           0 :         assert(link);
    1339           0 :         assert(link->network);
    1340             : 
    1341           0 :         if (link->network->mtu > 0)
    1342           0 :                 return link_set_mtu(link, link->network->mtu);
    1343             : 
    1344           0 :         mtu = link_get_requested_mtu_by_stacked_netdevs(link);
    1345           0 :         if (link->mtu >= mtu)
    1346           0 :                 return 0;
    1347             : 
    1348           0 :         log_link_notice(link, "Bumping MTU bytes from %"PRIu32" to %"PRIu32" because of stacked device. "
    1349             :                         "If it is not desired, then please explicitly specify MTUBytes= setting.",
    1350             :                         link->mtu, mtu);
    1351             : 
    1352           0 :         return link_set_mtu(link, mtu);
    1353             : }
    1354             : 
    1355           0 : static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1356             :         int r;
    1357             : 
    1358           0 :         assert(m);
    1359           0 :         assert(link);
    1360           0 :         assert(link->ifname);
    1361             : 
    1362           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1363           0 :                 return 1;
    1364             : 
    1365           0 :         r = sd_netlink_message_get_errno(m);
    1366           0 :         if (r < 0)
    1367           0 :                 log_link_warning_errno(link, r, "Could not set link flags, ignoring: %m");
    1368             : 
    1369           0 :         return 1;
    1370             : }
    1371             : 
    1372           0 : static int link_set_flags(Link *link) {
    1373           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    1374           0 :         unsigned ifi_change = 0;
    1375           0 :         unsigned ifi_flags = 0;
    1376             :         int r;
    1377             : 
    1378           0 :         assert(link);
    1379           0 :         assert(link->manager);
    1380           0 :         assert(link->manager->rtnl);
    1381             : 
    1382           0 :         if (link->flags & IFF_LOOPBACK)
    1383           0 :                 return 0;
    1384             : 
    1385           0 :         if (!link->network)
    1386           0 :                 return 0;
    1387             : 
    1388           0 :         if (link->network->arp < 0 && link->network->multicast < 0 && link->network->allmulticast < 0)
    1389           0 :                 return 0;
    1390             : 
    1391           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
    1392           0 :         if (r < 0)
    1393           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
    1394             : 
    1395           0 :         if (link->network->arp >= 0) {
    1396           0 :                 ifi_change |= IFF_NOARP;
    1397           0 :                 SET_FLAG(ifi_flags, IFF_NOARP, link->network->arp == 0);
    1398             :         }
    1399             : 
    1400           0 :         if (link->network->multicast >= 0) {
    1401           0 :                 ifi_change |= IFF_MULTICAST;
    1402           0 :                 SET_FLAG(ifi_flags, IFF_MULTICAST, link->network->multicast);
    1403             :         }
    1404             : 
    1405           0 :         if (link->network->allmulticast >= 0) {
    1406           0 :                 ifi_change |= IFF_ALLMULTI;
    1407           0 :                 SET_FLAG(ifi_flags, IFF_ALLMULTI, link->network->allmulticast);
    1408             :         }
    1409             : 
    1410           0 :         r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change);
    1411           0 :         if (r < 0)
    1412           0 :                 return log_link_error_errno(link, r, "Could not set link flags: %m");
    1413             : 
    1414           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, set_flags_handler,
    1415             :                                link_netlink_destroy_callback, link);
    1416           0 :         if (r < 0)
    1417           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
    1418             : 
    1419           0 :         link_ref(link);
    1420             : 
    1421           0 :         return 0;
    1422             : }
    1423             : 
    1424           0 : static int link_acquire_ipv6_conf(Link *link) {
    1425             :         int r;
    1426             : 
    1427           0 :         assert(link);
    1428             : 
    1429           0 :         if (link_ipv6_accept_ra_enabled(link)) {
    1430           0 :                 assert(link->ndisc);
    1431             : 
    1432           0 :                 log_link_debug(link, "Discovering IPv6 routers");
    1433             : 
    1434           0 :                 r = sd_ndisc_start(link->ndisc);
    1435           0 :                 if (r < 0 && r != -EBUSY)
    1436           0 :                         return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
    1437             :         }
    1438             : 
    1439           0 :         if (link_radv_enabled(link)) {
    1440           0 :                 assert(link->radv);
    1441           0 :                 assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
    1442             : 
    1443           0 :                 log_link_debug(link, "Starting IPv6 Router Advertisements");
    1444             : 
    1445           0 :                 r = sd_radv_start(link->radv);
    1446           0 :                 if (r < 0 && r != -EBUSY)
    1447           0 :                         return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
    1448             :         }
    1449             : 
    1450           0 :         (void) dhcp6_request_prefix_delegation(link);
    1451             : 
    1452           0 :         return 0;
    1453             : }
    1454             : 
    1455           0 : static int link_acquire_ipv4_conf(Link *link) {
    1456             :         int r;
    1457             : 
    1458           0 :         assert(link);
    1459           0 :         assert(link->manager);
    1460           0 :         assert(link->manager->event);
    1461             : 
    1462           0 :         if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4)) {
    1463           0 :                 assert(link->ipv4ll);
    1464             : 
    1465           0 :                 log_link_debug(link, "Acquiring IPv4 link-local address");
    1466             : 
    1467           0 :                 r = sd_ipv4ll_start(link->ipv4ll);
    1468           0 :                 if (r < 0)
    1469           0 :                         return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
    1470             :         }
    1471             : 
    1472           0 :         if (link_dhcp4_enabled(link)) {
    1473           0 :                 assert(link->dhcp_client);
    1474             : 
    1475           0 :                 log_link_debug(link, "Acquiring DHCPv4 lease");
    1476             : 
    1477           0 :                 r = sd_dhcp_client_start(link->dhcp_client);
    1478           0 :                 if (r < 0)
    1479           0 :                         return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
    1480             :         }
    1481             : 
    1482           0 :         return 0;
    1483             : }
    1484             : 
    1485           0 : static int link_acquire_conf(Link *link) {
    1486             :         int r;
    1487             : 
    1488           0 :         assert(link);
    1489             : 
    1490           0 :         r = link_acquire_ipv4_conf(link);
    1491           0 :         if (r < 0)
    1492           0 :                 return r;
    1493             : 
    1494           0 :         if (!in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) {
    1495           0 :                 r = link_acquire_ipv6_conf(link);
    1496           0 :                 if (r < 0)
    1497           0 :                         return r;
    1498             :         }
    1499             : 
    1500           0 :         if (link_lldp_emit_enabled(link)) {
    1501           0 :                 r = link_lldp_emit_start(link);
    1502           0 :                 if (r < 0)
    1503           0 :                         return log_link_warning_errno(link, r, "Failed to start LLDP transmission: %m");
    1504             :         }
    1505             : 
    1506           0 :         return 0;
    1507             : }
    1508             : 
    1509          18 : bool link_has_carrier(Link *link) {
    1510             :         /* see Documentation/networking/operstates.txt in the kernel sources */
    1511             : 
    1512          18 :         if (link->kernel_operstate == IF_OPER_UP)
    1513           3 :                 return true;
    1514             : 
    1515          15 :         if (link->kernel_operstate == IF_OPER_UNKNOWN)
    1516             :                 /* operstate may not be implemented, so fall back to flags */
    1517           6 :                 if (FLAGS_SET(link->flags, IFF_LOWER_UP | IFF_RUNNING) &&
    1518           6 :                     !FLAGS_SET(link->flags, IFF_DORMANT))
    1519           6 :                         return true;
    1520             : 
    1521           9 :         return false;
    1522             : }
    1523             : 
    1524           0 : static int link_address_genmode_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1525             :         int r;
    1526             : 
    1527           0 :         assert(link);
    1528             : 
    1529           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1530           0 :                 return 1;
    1531             : 
    1532           0 :         r = sd_netlink_message_get_errno(m);
    1533           0 :         if (r < 0)
    1534           0 :                 log_link_warning_errno(link, r, "Could not set address genmode for interface, ignoring: %m");
    1535             : 
    1536           0 :         return 1;
    1537             : }
    1538             : 
    1539           0 : static int link_configure_addrgen_mode(Link *link) {
    1540           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    1541             :         uint8_t ipv6ll_mode;
    1542             :         int r;
    1543             : 
    1544           0 :         assert(link);
    1545           0 :         assert(link->network);
    1546           0 :         assert(link->manager);
    1547           0 :         assert(link->manager->rtnl);
    1548             : 
    1549           0 :         if (!socket_ipv6_is_supported())
    1550           0 :                 return 0;
    1551             : 
    1552           0 :         log_link_debug(link, "Setting address genmode for link");
    1553             : 
    1554           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
    1555           0 :         if (r < 0)
    1556           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
    1557             : 
    1558           0 :         r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
    1559           0 :         if (r < 0)
    1560           0 :                 return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
    1561             : 
    1562           0 :         r = sd_netlink_message_open_container(req, AF_INET6);
    1563           0 :         if (r < 0)
    1564           0 :                 return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
    1565             : 
    1566           0 :         if (!link_ipv6ll_enabled(link))
    1567           0 :                 ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
    1568           0 :         else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
    1569             :                 /* The file may not exist. And event if it exists, when stable_secret is unset,
    1570             :                  * reading the file fails with EIO. */
    1571           0 :                 ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
    1572             :         else
    1573           0 :                 ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
    1574             : 
    1575           0 :         r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
    1576           0 :         if (r < 0)
    1577           0 :                 return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
    1578             : 
    1579           0 :         r = sd_netlink_message_close_container(req);
    1580           0 :         if (r < 0)
    1581           0 :                 return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
    1582             : 
    1583           0 :         r = sd_netlink_message_close_container(req);
    1584           0 :         if (r < 0)
    1585           0 :                 return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
    1586             : 
    1587           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, link_address_genmode_handler,
    1588             :                                link_netlink_destroy_callback, link);
    1589           0 :         if (r < 0)
    1590           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
    1591             : 
    1592           0 :         link_ref(link);
    1593             : 
    1594           0 :         return 0;
    1595             : }
    1596             : 
    1597           0 : static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1598             :         int r;
    1599             : 
    1600           0 :         assert(link);
    1601             : 
    1602           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1603           0 :                 return 1;
    1604             : 
    1605           0 :         r = sd_netlink_message_get_errno(m);
    1606           0 :         if (r < 0)
    1607             :                 /* we warn but don't fail the link, as it may be brought up later */
    1608           0 :                 log_link_warning_errno(link, r, "Could not bring up interface: %m");
    1609             : 
    1610           0 :         return 1;
    1611             : }
    1612             : 
    1613           0 : static int link_up(Link *link) {
    1614           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    1615             :         int r;
    1616             : 
    1617           0 :         assert(link);
    1618           0 :         assert(link->network);
    1619           0 :         assert(link->manager);
    1620           0 :         assert(link->manager->rtnl);
    1621             : 
    1622           0 :         log_link_debug(link, "Bringing link up");
    1623             : 
    1624           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
    1625           0 :         if (r < 0)
    1626           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
    1627             : 
    1628             :         /* set it free if not enslaved with networkd */
    1629           0 :         if (!link->network->bridge && !link->network->bond && !link->network->vrf) {
    1630           0 :                 r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
    1631           0 :                 if (r < 0)
    1632           0 :                         return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
    1633             :         }
    1634             : 
    1635           0 :         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
    1636           0 :         if (r < 0)
    1637           0 :                 return log_link_error_errno(link, r, "Could not set link flags: %m");
    1638             : 
    1639           0 :         if (link->network->mac) {
    1640           0 :                 r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac);
    1641           0 :                 if (r < 0)
    1642           0 :                         return log_link_error_errno(link, r, "Could not set MAC address: %m");
    1643             :         }
    1644             : 
    1645           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
    1646             :                                link_netlink_destroy_callback, link);
    1647           0 :         if (r < 0)
    1648           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
    1649             : 
    1650           0 :         link_ref(link);
    1651             : 
    1652           0 :         return 0;
    1653             : }
    1654             : 
    1655           0 : static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    1656             :         int r;
    1657             : 
    1658           0 :         assert(link);
    1659             : 
    1660           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    1661           0 :                 return 1;
    1662             : 
    1663           0 :         r = sd_netlink_message_get_errno(m);
    1664           0 :         if (r < 0)
    1665           0 :                 log_link_warning_errno(link, r, "Could not bring down interface: %m");
    1666             : 
    1667           0 :         return 1;
    1668             : }
    1669             : 
    1670           0 : int link_down(Link *link, link_netlink_message_handler_t callback) {
    1671           0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    1672             :         int r;
    1673             : 
    1674           0 :         assert(link);
    1675           0 :         assert(link->manager);
    1676           0 :         assert(link->manager->rtnl);
    1677             : 
    1678           0 :         log_link_debug(link, "Bringing link down");
    1679             : 
    1680           0 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
    1681             :                                      RTM_SETLINK, link->ifindex);
    1682           0 :         if (r < 0)
    1683           0 :                 return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
    1684             : 
    1685           0 :         r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP);
    1686           0 :         if (r < 0)
    1687           0 :                 return log_link_error_errno(link, r, "Could not set link flags: %m");
    1688             : 
    1689           0 :         r = netlink_call_async(link->manager->rtnl, NULL, req,
    1690             :                                callback ?: link_down_handler,
    1691             :                                link_netlink_destroy_callback, link);
    1692           0 :         if (r < 0)
    1693           0 :                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
    1694             : 
    1695           0 :         link_ref(link);
    1696             : 
    1697           0 :         return 0;
    1698             : }
    1699             : 
    1700           0 : static int link_handle_bound_to_list(Link *link) {
    1701             :         Link *l;
    1702             :         Iterator i;
    1703             :         int r;
    1704           0 :         bool required_up = false;
    1705           0 :         bool link_is_up = false;
    1706             : 
    1707           0 :         assert(link);
    1708             : 
    1709           0 :         if (hashmap_isempty(link->bound_to_links))
    1710           0 :                 return 0;
    1711             : 
    1712           0 :         if (link->flags & IFF_UP)
    1713           0 :                 link_is_up = true;
    1714             : 
    1715           0 :         HASHMAP_FOREACH (l, link->bound_to_links, i)
    1716           0 :                 if (link_has_carrier(l)) {
    1717           0 :                         required_up = true;
    1718           0 :                         break;
    1719             :                 }
    1720             : 
    1721           0 :         if (!required_up && link_is_up) {
    1722           0 :                 r = link_down(link, NULL);
    1723           0 :                 if (r < 0)
    1724           0 :                         return r;
    1725           0 :         } else if (required_up && !link_is_up) {
    1726           0 :                 r = link_up(link);
    1727           0 :                 if (r < 0)
    1728           0 :                         return r;
    1729             :         }
    1730             : 
    1731           0 :         return 0;
    1732             : }
    1733             : 
    1734           0 : static int link_handle_bound_by_list(Link *link) {
    1735             :         Iterator i;
    1736             :         Link *l;
    1737             :         int r;
    1738             : 
    1739           0 :         assert(link);
    1740             : 
    1741           0 :         if (hashmap_isempty(link->bound_by_links))
    1742           0 :                 return 0;
    1743             : 
    1744           0 :         HASHMAP_FOREACH (l, link->bound_by_links, i) {
    1745           0 :                 r = link_handle_bound_to_list(l);
    1746           0 :                 if (r < 0)
    1747           0 :                         return r;
    1748             :         }
    1749             : 
    1750           0 :         return 0;
    1751             : }
    1752             : 
    1753           0 : static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
    1754             :         int r;
    1755             : 
    1756           0 :         assert(link);
    1757           0 :         assert(carrier);
    1758             : 
    1759           0 :         if (link == carrier)
    1760           0 :                 return 0;
    1761             : 
    1762           0 :         if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
    1763           0 :                 return 0;
    1764             : 
    1765           0 :         r = hashmap_ensure_allocated(h, NULL);
    1766           0 :         if (r < 0)
    1767           0 :                 return r;
    1768             : 
    1769           0 :         r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
    1770           0 :         if (r < 0)
    1771           0 :                 return r;
    1772             : 
    1773           0 :         return 0;
    1774             : }
    1775             : 
    1776           0 : static int link_new_bound_by_list(Link *link) {
    1777             :         Manager *m;
    1778             :         Link *carrier;
    1779             :         Iterator i;
    1780             :         int r;
    1781           0 :         bool list_updated = false;
    1782             : 
    1783           0 :         assert(link);
    1784           0 :         assert(link->manager);
    1785             : 
    1786           0 :         m = link->manager;
    1787             : 
    1788           0 :         HASHMAP_FOREACH(carrier, m->links, i) {
    1789           0 :                 if (!carrier->network)
    1790           0 :                         continue;
    1791             : 
    1792           0 :                 if (strv_isempty(carrier->network->bind_carrier))
    1793           0 :                         continue;
    1794             : 
    1795           0 :                 if (strv_fnmatch(carrier->network->bind_carrier, link->ifname, 0)) {
    1796           0 :                         r = link_put_carrier(link, carrier, &link->bound_by_links);
    1797           0 :                         if (r < 0)
    1798           0 :                                 return r;
    1799             : 
    1800           0 :                         list_updated = true;
    1801             :                 }
    1802             :         }
    1803             : 
    1804           0 :         if (list_updated)
    1805           0 :                 link_dirty(link);
    1806             : 
    1807           0 :         HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
    1808           0 :                 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
    1809           0 :                 if (r < 0)
    1810           0 :                         return r;
    1811             : 
    1812           0 :                 link_dirty(carrier);
    1813             :         }
    1814             : 
    1815           0 :         return 0;
    1816             : }
    1817             : 
    1818           0 : static int link_new_bound_to_list(Link *link) {
    1819             :         Manager *m;
    1820             :         Link *carrier;
    1821             :         Iterator i;
    1822             :         int r;
    1823           0 :         bool list_updated = false;
    1824             : 
    1825           0 :         assert(link);
    1826           0 :         assert(link->manager);
    1827             : 
    1828           0 :         if (!link->network)
    1829           0 :                 return 0;
    1830             : 
    1831           0 :         if (strv_isempty(link->network->bind_carrier))
    1832           0 :                 return 0;
    1833             : 
    1834           0 :         m = link->manager;
    1835             : 
    1836           0 :         HASHMAP_FOREACH (carrier, m->links, i) {
    1837           0 :                 if (strv_fnmatch(link->network->bind_carrier, carrier->ifname, 0)) {
    1838           0 :                         r = link_put_carrier(link, carrier, &link->bound_to_links);
    1839           0 :                         if (r < 0)
    1840           0 :                                 return r;
    1841             : 
    1842           0 :                         list_updated = true;
    1843             :                 }
    1844             :         }
    1845             : 
    1846           0 :         if (list_updated)
    1847           0 :                 link_dirty(link);
    1848             : 
    1849           0 :         HASHMAP_FOREACH (carrier, link->bound_to_links, i) {
    1850           0 :                 r = link_put_carrier(carrier, link, &carrier->bound_by_links);
    1851           0 :                 if (r < 0)
    1852           0 :                         return r;
    1853             : 
    1854           0 :                 link_dirty(carrier);
    1855             :         }
    1856             : 
    1857           0 :         return 0;
    1858             : }
    1859             : 
    1860           0 : static int link_new_carrier_maps(Link *link) {
    1861             :         int r;
    1862             : 
    1863           0 :         r = link_new_bound_by_list(link);
    1864           0 :         if (r < 0)
    1865           0 :                 return r;
    1866             : 
    1867           0 :         r = link_handle_bound_by_list(link);
    1868           0 :         if (r < 0)
    1869           0 :                 return r;
    1870             : 
    1871           0 :         r = link_new_bound_to_list(link);
    1872           0 :         if (r < 0)
    1873           0 :                 return r;
    1874             : 
    1875           0 :         r = link_handle_bound_to_list(link);
    1876           0 :         if (r < 0)
    1877           0 :                 return r;
    1878             : 
    1879           0 :         return 0;
    1880             : }
    1881             : 
    1882           0 : static void link_free_bound_to_list(Link *link) {
    1883             :         Link *bound_to;
    1884             :         Iterator i;
    1885             : 
    1886           0 :         HASHMAP_FOREACH (bound_to, link->bound_to_links, i) {
    1887           0 :                 hashmap_remove(link->bound_to_links, INT_TO_PTR(bound_to->ifindex));
    1888             : 
    1889           0 :                 if (hashmap_remove(bound_to->bound_by_links, INT_TO_PTR(link->ifindex)))
    1890           0 :                         link_dirty(bound_to);
    1891             :         }
    1892             : 
    1893           0 :         return;
    1894             : }
    1895             : 
    1896           0 : static void link_free_bound_by_list(Link *link) {
    1897             :         Link *bound_by;
    1898             :         Iterator i;
    1899             : 
    1900           0 :         HASHMAP_FOREACH (bound_by, link->bound_by_links, i) {
    1901           0 :                 hashmap_remove(link->bound_by_links, INT_TO_PTR(bound_by->ifindex));
    1902             : 
    1903           0 :                 if (hashmap_remove(bound_by->bound_to_links, INT_TO_PTR(link->ifindex))) {
    1904           0 :                         link_dirty(bound_by);
    1905           0 :                         link_handle_bound_to_list(bound_by);
    1906             :                 }
    1907             :         }
    1908             : 
    1909           0 :         return;
    1910             : }
    1911             : 
    1912           0 : static void link_free_carrier_maps(Link *link) {
    1913           0 :         bool list_updated = false;
    1914             : 
    1915           0 :         assert(link);
    1916             : 
    1917           0 :         if (!hashmap_isempty(link->bound_to_links)) {
    1918           0 :                 link_free_bound_to_list(link);
    1919           0 :                 list_updated = true;
    1920             :         }
    1921             : 
    1922           0 :         if (!hashmap_isempty(link->bound_by_links)) {
    1923           0 :                 link_free_bound_by_list(link);
    1924           0 :                 list_updated = true;
    1925             :         }
    1926             : 
    1927           0 :         if (list_updated)
    1928           0 :                 link_dirty(link);
    1929             : 
    1930           0 :         return;
    1931             : }
    1932             : 
    1933           0 : static int link_append_to_master(Link *link, NetDev *netdev) {
    1934             :         Link *master;
    1935             :         int r;
    1936             : 
    1937           0 :         assert(link);
    1938           0 :         assert(netdev);
    1939             : 
    1940           0 :         r = link_get(link->manager, netdev->ifindex, &master);
    1941           0 :         if (r < 0)
    1942           0 :                 return r;
    1943             : 
    1944           0 :         r = set_ensure_allocated(&master->slaves, NULL);
    1945           0 :         if (r < 0)
    1946           0 :                 return r;
    1947             : 
    1948           0 :         r = set_put(master->slaves, link);
    1949           0 :         if (r < 0)
    1950           0 :                 return r;
    1951           0 :         if (r == 0)
    1952           0 :                 return 0;
    1953             : 
    1954           0 :         link_ref(link);
    1955           0 :         return 0;
    1956             : }
    1957             : 
    1958           0 : static void link_drop_from_master(Link *link, NetDev *netdev) {
    1959             :         Link *master;
    1960             : 
    1961           0 :         assert(link);
    1962             : 
    1963           0 :         if (!link->manager || !netdev)
    1964           0 :                 return;
    1965             : 
    1966           0 :         if (link_get(link->manager, netdev->ifindex, &master) < 0)
    1967           0 :                 return;
    1968             : 
    1969           0 :         link_unref(set_remove(master->slaves, link));
    1970             : }
    1971             : 
    1972           0 : static void link_detach_from_manager(Link *link) {
    1973           0 :         if (!link || !link->manager)
    1974           0 :                 return;
    1975             : 
    1976           0 :         link_unref(set_remove(link->manager->links_requesting_uuid, link));
    1977           0 :         link_clean(link);
    1978             : 
    1979             :         /* The following must be called at last. */
    1980           0 :         assert_se(hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)) == link);
    1981           0 :         link_unref(link);
    1982             : }
    1983             : 
    1984           0 : void link_drop(Link *link) {
    1985           0 :         if (!link || link->state == LINK_STATE_LINGER)
    1986           0 :                 return;
    1987             : 
    1988           0 :         link_set_state(link, LINK_STATE_LINGER);
    1989             : 
    1990           0 :         link_free_carrier_maps(link);
    1991             : 
    1992           0 :         if (link->network) {
    1993           0 :                 link_drop_from_master(link, link->network->bridge);
    1994           0 :                 link_drop_from_master(link, link->network->bond);
    1995             :         }
    1996             : 
    1997           0 :         log_link_debug(link, "Link removed");
    1998             : 
    1999           0 :         (void) unlink(link->state_file);
    2000           0 :         link_detach_from_manager(link);
    2001             : }
    2002             : 
    2003           0 : static int link_joined(Link *link) {
    2004             :         int r;
    2005             : 
    2006           0 :         assert(link);
    2007           0 :         assert(link->network);
    2008             : 
    2009           0 :         if (!hashmap_isempty(link->bound_to_links)) {
    2010           0 :                 r = link_handle_bound_to_list(link);
    2011           0 :                 if (r < 0)
    2012           0 :                         return r;
    2013           0 :         } else if (!(link->flags & IFF_UP)) {
    2014           0 :                 r = link_up(link);
    2015           0 :                 if (r < 0) {
    2016           0 :                         link_enter_failed(link);
    2017           0 :                         return r;
    2018             :                 }
    2019             :         }
    2020             : 
    2021           0 :         if (link->network->bridge) {
    2022           0 :                 r = link_set_bridge(link);
    2023           0 :                 if (r < 0)
    2024           0 :                         log_link_error_errno(link, r, "Could not set bridge message: %m");
    2025             : 
    2026           0 :                 r = link_append_to_master(link, link->network->bridge);
    2027           0 :                 if (r < 0)
    2028           0 :                         log_link_error_errno(link, r, "Failed to add to bridge master's slave list: %m");
    2029             :         }
    2030             : 
    2031           0 :         if (link->network->bond) {
    2032           0 :                 r = link_set_bond(link);
    2033           0 :                 if (r < 0)
    2034           0 :                         log_link_error_errno(link, r, "Could not set bond message: %m");
    2035             : 
    2036           0 :                 r = link_append_to_master(link, link->network->bond);
    2037           0 :                 if (r < 0)
    2038           0 :                         log_link_error_errno(link, r, "Failed to add to bond master's slave list: %m");
    2039             :         }
    2040             : 
    2041           0 :         if (link->network->use_br_vlan &&
    2042           0 :             (link->network->bridge || streq_ptr("bridge", link->kind))) {
    2043           0 :                 r = link_set_bridge_vlan(link);
    2044           0 :                 if (r < 0)
    2045           0 :                         log_link_error_errno(link, r, "Could not set bridge vlan: %m");
    2046             :         }
    2047             : 
    2048             :         /* Skip setting up addresses until it gets carrier,
    2049             :            or it would try to set addresses twice,
    2050             :            which is bad for non-idempotent steps. */
    2051           0 :         if (!link_has_carrier(link) && !link->network->configure_without_carrier)
    2052           0 :                 return 0;
    2053             : 
    2054           0 :         link_set_state(link, LINK_STATE_CONFIGURING);
    2055           0 :         return link_request_set_addresses(link);
    2056             : }
    2057             : 
    2058           0 : static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    2059             :         int r;
    2060             : 
    2061           0 :         assert(link);
    2062           0 :         assert(link->network);
    2063           0 :         assert(link->enslaving > 0);
    2064             : 
    2065           0 :         link->enslaving--;
    2066             : 
    2067           0 :         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
    2068           0 :                 return 1;
    2069             : 
    2070           0 :         r = sd_netlink_message_get_errno(m);
    2071           0 :         if (r < 0 && r != -EEXIST) {
    2072           0 :                 log_link_error_errno(link, r, "Could not join netdev: %m");
    2073           0 :                 link_enter_failed(link);
    2074           0 :                 return 1;
    2075             :         }
    2076             : 
    2077           0 :         log_link_debug(link, "Joined netdev");
    2078             : 
    2079           0 :         if (link->enslaving == 0) {
    2080           0 :                 r = link_joined(link);
    2081           0 :                 if (r < 0)
    2082           0 :                         link_enter_failed(link);
    2083             :         }
    2084             : 
    2085           0 :         return 1;
    2086             : }
    2087             : 
    2088           0 : static int link_enter_join_netdev(Link *link) {
    2089             :         NetDev *netdev;
    2090             :         Iterator i;
    2091             :         int r;
    2092             : 
    2093           0 :         assert(link);
    2094           0 :         assert(link->network);
    2095           0 :         assert(link->state == LINK_STATE_INITIALIZED);
    2096             : 
    2097           0 :         link_set_state(link, LINK_STATE_CONFIGURING);
    2098             : 
    2099           0 :         link_dirty(link);
    2100           0 :         link->enslaving = 0;
    2101             : 
    2102           0 :         if (link->network->bond) {
    2103           0 :                 if (link->network->bond->state == NETDEV_STATE_READY &&
    2104           0 :                     link->network->bond->ifindex == link->master_ifindex)
    2105           0 :                         return link_joined(link);
    2106             : 
    2107           0 :                 log_struct(LOG_DEBUG,
    2108             :                            LOG_LINK_INTERFACE(link),
    2109             :                            LOG_NETDEV_INTERFACE(link->network->bond),
    2110             :                            LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bond->ifname));
    2111             : 
    2112           0 :                 link->enslaving++;
    2113             : 
    2114           0 :                 r = netdev_join(link->network->bond, link, netdev_join_handler);
    2115           0 :                 if (r < 0) {
    2116           0 :                         log_struct_errno(LOG_WARNING, r,
    2117             :                                          LOG_LINK_INTERFACE(link),
    2118             :                                          LOG_NETDEV_INTERFACE(link->network->bond),
    2119             :                                          LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bond->ifname));
    2120           0 :                         link_enter_failed(link);
    2121           0 :                         return r;
    2122             :                 }
    2123             :         }
    2124             : 
    2125           0 :         if (link->network->bridge) {
    2126           0 :                 log_struct(LOG_DEBUG,
    2127             :                            LOG_LINK_INTERFACE(link),
    2128             :                            LOG_NETDEV_INTERFACE(link->network->bridge),
    2129             :                            LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->bridge->ifname));
    2130             : 
    2131           0 :                 link->enslaving++;
    2132             : 
    2133           0 :                 r = netdev_join(link->network->bridge, link, netdev_join_handler);
    2134           0 :                 if (r < 0) {
    2135           0 :                         log_struct_errno(LOG_WARNING, r,
    2136             :                                          LOG_LINK_INTERFACE(link),
    2137             :                                          LOG_NETDEV_INTERFACE(link->network->bridge),
    2138             :                                          LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->bridge->ifname));
    2139           0 :                         link_enter_failed(link);
    2140           0 :                         return r;
    2141             :                 }
    2142             :         }
    2143             : 
    2144           0 :         if (link->network->vrf) {
    2145           0 :                 log_struct(LOG_DEBUG,
    2146             :                            LOG_LINK_INTERFACE(link),
    2147             :                            LOG_NETDEV_INTERFACE(link->network->vrf),
    2148             :                            LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname));
    2149             : 
    2150           0 :                 link->enslaving++;
    2151             : 
    2152           0 :                 r = netdev_join(link->network->vrf, link, netdev_join_handler);
    2153           0 :                 if (r < 0) {
    2154           0 :                         log_struct_errno(LOG_WARNING, r,
    2155             :                                          LOG_LINK_INTERFACE(link),
    2156             :                                          LOG_NETDEV_INTERFACE(link->network->vrf),
    2157             :                                          LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname));
    2158           0 :                         link_enter_failed(link);
    2159           0 :                         return r;
    2160             :                 }
    2161             :         }
    2162             : 
    2163           0 :         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
    2164             : 
    2165           0 :                 if (netdev->ifindex > 0)
    2166             :                         /* Assume already enslaved. */
    2167           0 :                         continue;
    2168             : 
    2169           0 :                 if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
    2170           0 :                         continue;
    2171             : 
    2172           0 :                 log_struct(LOG_DEBUG,
    2173             :                            LOG_LINK_INTERFACE(link),
    2174             :                            LOG_NETDEV_INTERFACE(netdev),
    2175             :                            LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
    2176             : 
    2177           0 :                 link->enslaving++;
    2178             : 
    2179           0 :                 r = netdev_join(netdev, link, netdev_join_handler);
    2180           0 :                 if (r < 0) {
    2181           0 :                         log_struct_errno(LOG_WARNING, r,
    2182             :                                          LOG_LINK_INTERFACE(link),
    2183             :                                          LOG_NETDEV_INTERFACE(netdev),
    2184             :                                          LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
    2185           0 :                         link_enter_failed(link);
    2186           0 :                         return r;
    2187             :                 }
    2188             :         }
    2189             : 
    2190           0 :         if (link->enslaving == 0)
    2191           0 :                 return link_joined(link);
    2192             : 
    2193           0 :         return 0;
    2194             : }
    2195             : 
    2196           0 : static int link_set_ipv4_forward(Link *link) {
    2197             :         int r;
    2198             : 
    2199           0 :         if (!link_ipv4_forward_enabled(link))
    2200           0 :                 return 0;
    2201             : 
    2202             :         /* We propagate the forwarding flag from one interface to the
    2203             :          * global setting one way. This means: as long as at least one
    2204             :          * interface was configured at any time that had IP forwarding
    2205             :          * enabled the setting will stay on for good. We do this
    2206             :          * primarily to keep IPv4 and IPv6 packet forwarding behaviour
    2207             :          * somewhat in sync (see below). */
    2208             : 
    2209           0 :         r = sysctl_write_ip_property(AF_INET, NULL, "ip_forward", "1");
    2210           0 :         if (r < 0)
    2211           0 :                 log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
    2212             : 
    2213           0 :         return 0;
    2214             : }
    2215             : 
    2216           0 : static int link_set_ipv6_forward(Link *link) {
    2217             :         int r;
    2218             : 
    2219           0 :         if (!link_ipv6_forward_enabled(link))
    2220           0 :                 return 0;
    2221             : 
    2222             :         /* On Linux, the IPv6 stack does not know a per-interface
    2223             :          * packet forwarding setting: either packet forwarding is on
    2224             :          * for all, or off for all. We hence don't bother with a
    2225             :          * per-interface setting, but simply propagate the interface
    2226             :          * flag, if it is set, to the global flag, one-way. Note that
    2227             :          * while IPv4 would allow a per-interface flag, we expose the
    2228             :          * same behaviour there and also propagate the setting from
    2229             :          * one to all, to keep things simple (see above). */
    2230             : 
    2231           0 :         r = sysctl_write_ip_property(AF_INET6, "all", "forwarding", "1");
    2232           0 :         if (r < 0)
    2233           0 :                 log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
    2234             : 
    2235           0 :         return 0;
    2236             : }
    2237             : 
    2238           0 : static int link_set_ipv6_privacy_extensions(Link *link) {
    2239             :         IPv6PrivacyExtensions s;
    2240             :         int r;
    2241             : 
    2242           0 :         s = link_ipv6_privacy_extensions(link);
    2243           0 :         if (s < 0)
    2244           0 :                 return 0;
    2245             : 
    2246           0 :         r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "use_tempaddr", (int) link->network->ipv6_privacy_extensions);
    2247           0 :         if (r < 0)
    2248           0 :                 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
    2249             : 
    2250           0 :         return 0;
    2251             : }
    2252             : 
    2253           0 : static int link_set_ipv6_accept_ra(Link *link) {
    2254             :         int r;
    2255             : 
    2256             :         /* Make this a NOP if IPv6 is not available */
    2257           0 :         if (!socket_ipv6_is_supported())
    2258           0 :                 return 0;
    2259             : 
    2260           0 :         if (link->flags & IFF_LOOPBACK)
    2261           0 :                 return 0;
    2262             : 
    2263           0 :         if (!link->network)
    2264           0 :                 return 0;
    2265             : 
    2266           0 :         r = sysctl_write_ip_property(AF_INET6, link->ifname, "accept_ra", "0");
    2267           0 :         if (r < 0)
    2268           0 :                 log_link_warning_errno(link, r, "Cannot disable kernel IPv6 accept_ra for interface: %m");
    2269             : 
    2270           0 :         return 0;
    2271             : }
    2272             : 
    2273           0 : static int link_set_ipv6_dad_transmits(Link *link) {
    2274             :         int r;
    2275             : 
    2276             :         /* Make this a NOP if IPv6 is not available */
    2277           0 :         if (!socket_ipv6_is_supported())
    2278           0 :                 return 0;
    2279             : 
    2280           0 :         if (link->flags & IFF_LOOPBACK)
    2281           0 :                 return 0;
    2282             : 
    2283           0 :         if (!link->network)
    2284           0 :                 return 0;
    2285             : 
    2286           0 :         if (link->network->ipv6_dad_transmits < 0)
    2287           0 :                 return 0;
    2288             : 
    2289           0 :         r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "dad_transmits", link->network->ipv6_dad_transmits);
    2290           0 :         if (r < 0)
    2291           0 :                 log_link_warning_errno(link, r, "Cannot set IPv6 dad transmits for interface: %m");
    2292             : 
    2293           0 :         return 0;
    2294             : }
    2295             : 
    2296           0 : static int link_set_ipv6_hop_limit(Link *link) {
    2297             :         int r;
    2298             : 
    2299             :         /* Make this a NOP if IPv6 is not available */
    2300           0 :         if (!socket_ipv6_is_supported())
    2301           0 :                 return 0;
    2302             : 
    2303           0 :         if (link->flags & IFF_LOOPBACK)
    2304           0 :                 return 0;
    2305             : 
    2306           0 :         if (!link->network)
    2307           0 :                 return 0;
    2308             : 
    2309           0 :         if (link->network->ipv6_hop_limit < 0)
    2310           0 :                 return 0;
    2311             : 
    2312           0 :         r = sysctl_write_ip_property_int(AF_INET6, link->ifname, "hop_limit", link->network->ipv6_hop_limit);
    2313           0 :         if (r < 0)
    2314           0 :                 log_link_warning_errno(link, r, "Cannot set IPv6 hop limit for interface: %m");
    2315             : 
    2316           0 :         return 0;
    2317             : }
    2318             : 
    2319           0 : static int link_set_ipv6_mtu(Link *link) {
    2320             :         int r;
    2321             : 
    2322             :         /* Make this a NOP if IPv6 is not available */
    2323           0 :         if (!socket_ipv6_is_supported())
    2324           0 :                 return 0;
    2325             : 
    2326           0 :         if (link->flags & IFF_LOOPBACK)
    2327           0 :                 return 0;
    2328             : 
    2329           0 :         if (link->network->ipv6_mtu == 0)
    2330           0 :                 return 0;
    2331             : 
    2332           0 :         r = sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", link->network->ipv6_mtu);
    2333           0 :         if (r < 0)
    2334           0 :                 log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface: %m");
    2335             : 
    2336           0 :         return 0;
    2337             : }
    2338             : 
    2339           0 : static bool link_is_static_address_configured(Link *link, Address *address) {
    2340             :         Address *net_address;
    2341             : 
    2342           0 :         assert(link);
    2343           0 :         assert(address);
    2344             : 
    2345           0 :         if (!link->network)
    2346           0 :                 return false;
    2347             : 
    2348           0 :         LIST_FOREACH(addresses, net_address, link->network->static_addresses)
    2349           0 :                 if (address_equal(net_address, address))
    2350           0 :                         return true;
    2351             : 
    2352           0 :         return false;
    2353             : }
    2354             : 
    2355           0 : static bool link_is_neighbor_configured(Link *link, Neighbor *neighbor) {
    2356             :         Neighbor *net_neighbor;
    2357             : 
    2358           0 :         assert(link);
    2359           0 :         assert(neighbor);
    2360             : 
    2361           0 :         if (!link->network)
    2362           0 :                 return false;
    2363             : 
    2364           0 :         LIST_FOREACH(neighbors, net_neighbor, link->network->neighbors)
    2365           0 :                 if (neighbor_equal(net_neighbor, neighbor))
    2366           0 :                         return true;
    2367             : 
    2368           0 :         return false;
    2369             : }
    2370             : 
    2371           0 : static bool link_is_static_route_configured(Link *link, Route *route) {
    2372             :         Route *net_route;
    2373             : 
    2374           0 :         assert(link);
    2375           0 :         assert(route);
    2376             : 
    2377           0 :         if (!link->network)
    2378           0 :                 return false;
    2379             : 
    2380           0 :         LIST_FOREACH(routes, net_route, link->network->static_routes)
    2381           0 :                 if (route_equal(net_route, route))
    2382           0 :                         return true;
    2383             : 
    2384           0 :         return false;
    2385             : }
    2386             : 
    2387           0 : static bool link_address_is_dynamic(Link *link, Address *address) {
    2388             :         Route *route;
    2389             :         Iterator i;
    2390             : 
    2391           0 :         assert(link);
    2392           0 :         assert(address);
    2393             : 
    2394           0 :         if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
    2395           0 :                 return true;
    2396             : 
    2397             :         /* Even when the address is leased from a DHCP server, networkd assign the address
    2398             :          * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
    2399             :          * corresponding routes with RTPROT_DHCP. */
    2400           0 :         SET_FOREACH(route, link->routes_foreign, i) {
    2401           0 :                 if (route->protocol != RTPROT_DHCP)
    2402           0 :                         continue;
    2403             : 
    2404           0 :                 if (address->family != route->family)
    2405           0 :                         continue;
    2406             : 
    2407           0 :                 if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
    2408           0 :                         return true;
    2409             :         }
    2410             : 
    2411           0 :         return false;
    2412             : }
    2413             : 
    2414           0 : static int link_drop_foreign_config(Link *link) {
    2415             :         Address *address;
    2416             :         Neighbor *neighbor;
    2417             :         Route *route;
    2418             :         Iterator i;
    2419             :         int r;
    2420             : 
    2421           0 :         SET_FOREACH(address, link->addresses_foreign, i) {
    2422             :                 /* we consider IPv6LL addresses to be managed by the kernel */
    2423           0 :                 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
    2424           0 :                         continue;
    2425             : 
    2426           0 :                 if (link_address_is_dynamic(link, address)) {
    2427           0 :                         if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
    2428           0 :                                 continue;
    2429           0 :                 } else if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
    2430           0 :                         continue;
    2431             : 
    2432           0 :                 if (link_is_static_address_configured(link, address)) {
    2433           0 :                         r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
    2434           0 :                         if (r < 0)
    2435           0 :                                 return log_link_error_errno(link, r, "Failed to add address: %m");
    2436             :                 } else {
    2437           0 :                         r = address_remove(address, link, NULL);
    2438           0 :                         if (r < 0)
    2439           0 :                                 return r;
    2440             :                 }
    2441             :         }
    2442             : 
    2443           0 :         SET_FOREACH(neighbor, link->neighbors_foreign, i) {
    2444           0 :                 if (link_is_neighbor_configured(link, neighbor)) {
    2445           0 :                         r = neighbor_add(link, neighbor->family, &neighbor->in_addr, &neighbor->lladdr, neighbor->lladdr_size, NULL);
    2446           0 :                         if (r < 0)
    2447           0 :                                 return r;
    2448             :                 } else {
    2449           0 :                         r = neighbor_remove(neighbor, link, NULL);
    2450           0 :                         if (r < 0)
    2451           0 :                                 return r;
    2452             :                 }
    2453             :         }
    2454             : 
    2455           0 :         SET_FOREACH(route, link->routes_foreign, i) {
    2456             :                 /* do not touch routes managed by the kernel */
    2457           0 :                 if (route->protocol == RTPROT_KERNEL)
    2458           0 :                         continue;
    2459             : 
    2460             :                 /* do not touch multicast route added by kernel */
    2461             :                 /* FIXME: Why the kernel adds this route with protocol RTPROT_BOOT??? We need to investigate that.
    2462             :                  * https://tools.ietf.org/html/rfc4862#section-5.4 may explain why. */
    2463           0 :                 if (route->protocol == RTPROT_BOOT &&
    2464           0 :                     route->family == AF_INET6 &&
    2465           0 :                     route->dst_prefixlen == 8 &&
    2466           0 :                     in_addr_equal(AF_INET6, &route->dst, &(union in_addr_union) { .in6 = {{{ 0xff,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }}} }))
    2467           0 :                         continue;
    2468             : 
    2469           0 :                 if (route->protocol == RTPROT_STATIC &&
    2470           0 :                     FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
    2471           0 :                         continue;
    2472             : 
    2473           0 :                 if (route->protocol == RTPROT_DHCP &&
    2474           0 :                     FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
    2475           0 :                         continue;
    2476             : 
    2477           0 :                 if (link_is_static_route_configured(link, route)) {
    2478           0 :                         r = route_add(link, route->family, &route->dst, route->dst_prefixlen, &route->gw, route->tos, route->priority, route->table, NULL);
    2479           0 :                         if (r < 0)
    2480           0 :                                 return r;
    2481             :                 } else {
    2482           0 :                         r = route_remove(route, link, NULL);
    2483           0 :                         if (r < 0)
    2484           0 :                                 return r;
    2485             :                 }
    2486             :         }
    2487             : 
    2488           0 :         return 0;
    2489             : }
    2490             : 
    2491           0 : static int link_drop_config(Link *link) {
    2492             :         Address *address, *pool_address;
    2493             :         Neighbor *neighbor;
    2494             :         Route *route;
    2495             :         Iterator i;
    2496             :         int r;
    2497             : 
    2498           0 :         SET_FOREACH(address, link->addresses, i) {
    2499             :                 /* we consider IPv6LL addresses to be managed by the kernel */
    2500           0 :                 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
    2501           0 :                         continue;
    2502             : 
    2503           0 :                 r = address_remove(address, link, NULL);
    2504           0 :                 if (r < 0)
    2505           0 :                         return r;
    2506             : 
    2507             :                 /* If this address came from an address pool, clean up the pool */
    2508           0 :                 LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
    2509           0 :                         if (address_equal(address, pool_address)) {
    2510           0 :                                 LIST_REMOVE(addresses, link->pool_addresses, pool_address);
    2511           0 :                                 address_free(pool_address);
    2512           0 :                                 break;
    2513             :                         }
    2514             :                 }
    2515             :         }
    2516             : 
    2517           0 :         SET_FOREACH(neighbor, link->neighbors, i) {
    2518           0 :                 r = neighbor_remove(neighbor, link, NULL);
    2519           0 :                 if (r < 0)
    2520           0 :                         return r;
    2521             :         }
    2522             : 
    2523           0 :         SET_FOREACH(route, link->routes, i) {
    2524             :                 /* do not touch routes managed by the kernel */
    2525           0 :                 if (route->protocol == RTPROT_KERNEL)
    2526           0 :                         continue;
    2527             : 
    2528           0 :                 r = route_remove(route, link, NULL);
    2529           0 :                 if (r < 0)
    2530           0 :                         return r;
    2531             :         }
    2532             : 
    2533           0 :         ndisc_flush(link);
    2534             : 
    2535           0 :         return 0;
    2536             : }
    2537             : 
    2538           0 : static int link_configure(Link *link) {
    2539             :         int r;
    2540             : 
    2541           0 :         assert(link);
    2542           0 :         assert(link->network);
    2543           0 :         assert(link->state == LINK_STATE_INITIALIZED);
    2544             : 
    2545           0 :         if (link->iftype == ARPHRD_CAN)
    2546           0 :                 return link_configure_can(link);
    2547             : 
    2548             :         /* Drop foreign config, but ignore loopback or critical devices.
    2549             :          * We do not want to remove loopback address or addresses used for root NFS. */
    2550           0 :         if (!(link->flags & IFF_LOOPBACK) &&
    2551           0 :             link->network->keep_configuration != KEEP_CONFIGURATION_YES) {
    2552           0 :                 r = link_drop_foreign_config(link);
    2553           0 :                 if (r < 0)
    2554           0 :                         return r;
    2555             :         }
    2556             : 
    2557           0 :         r = link_set_proxy_arp(link);
    2558           0 :         if (r < 0)
    2559           0 :                return r;
    2560             : 
    2561           0 :         r = ipv6_proxy_ndp_addresses_configure(link);
    2562           0 :         if (r < 0)
    2563           0 :                 return r;
    2564             : 
    2565           0 :         r = link_set_ipv4_forward(link);
    2566           0 :         if (r < 0)
    2567           0 :                 return r;
    2568             : 
    2569           0 :         r = link_set_ipv6_forward(link);
    2570           0 :         if (r < 0)
    2571           0 :                 return r;
    2572             : 
    2573           0 :         r = link_set_ipv6_privacy_extensions(link);
    2574           0 :         if (r < 0)
    2575           0 :                 return r;
    2576             : 
    2577           0 :         r = link_set_ipv6_accept_ra(link);
    2578           0 :         if (r < 0)
    2579           0 :                 return r;
    2580             : 
    2581           0 :         r = link_set_ipv6_dad_transmits(link);
    2582           0 :         if (r < 0)
    2583           0 :                 return r;
    2584             : 
    2585           0 :         r = link_set_ipv6_hop_limit(link);
    2586           0 :         if (r < 0)
    2587           0 :                 return r;
    2588             : 
    2589           0 :         r = link_set_flags(link);
    2590           0 :         if (r < 0)
    2591           0 :                 return r;
    2592             : 
    2593           0 :         r = link_set_ipv6_mtu(link);
    2594           0 :         if (r < 0)
    2595           0 :                 return r;
    2596             : 
    2597           0 :         if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) {
    2598           0 :                 r = ipv4ll_configure(link);
    2599           0 :                 if (r < 0)
    2600           0 :                         return r;
    2601             :         }
    2602             : 
    2603           0 :         if (link_dhcp4_enabled(link)) {
    2604           0 :                 r = dhcp4_set_promote_secondaries(link);
    2605           0 :                 if (r < 0)
    2606           0 :                         return r;
    2607             : 
    2608           0 :                 r = dhcp4_configure(link);
    2609           0 :                 if (r < 0)
    2610           0 :                         return r;
    2611             :         }
    2612             : 
    2613           0 :         if (link_dhcp4_server_enabled(link)) {
    2614           0 :                 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
    2615           0 :                 if (r < 0)
    2616           0 :                         return r;
    2617             : 
    2618           0 :                 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
    2619           0 :                 if (r < 0)
    2620           0 :                         return r;
    2621             :         }
    2622             : 
    2623           0 :         if (link_dhcp6_enabled(link) ||
    2624           0 :             link_ipv6_accept_ra_enabled(link)) {
    2625           0 :                 r = dhcp6_configure(link);
    2626           0 :                 if (r < 0)
    2627           0 :                         return r;
    2628             :         }
    2629             : 
    2630           0 :         if (link_ipv6_accept_ra_enabled(link)) {
    2631           0 :                 r = ndisc_configure(link);
    2632           0 :                 if (r < 0)
    2633           0 :                         return r;
    2634             :         }
    2635             : 
    2636           0 :         if (link_radv_enabled(link)) {
    2637           0 :                 r = radv_configure(link);
    2638           0 :                 if (r < 0)
    2639           0 :                         return r;
    2640             :         }
    2641             : 
    2642           0 :         if (link_lldp_rx_enabled(link)) {
    2643           0 :                 r = link_lldp_rx_configure(link);
    2644           0 :                 if (r < 0)
    2645           0 :                         return r;
    2646             :         }
    2647             : 
    2648           0 :         r = link_configure_mtu(link);
    2649           0 :         if (r < 0)
    2650           0 :                 return r;
    2651             : 
    2652           0 :         r = link_configure_addrgen_mode(link);
    2653           0 :         if (r < 0)
    2654           0 :                 return r;
    2655             : 
    2656           0 :         return link_configure_after_setting_mtu(link);
    2657             : }
    2658             : 
    2659           0 : static int link_configure_after_setting_mtu(Link *link) {
    2660             :         int r;
    2661             : 
    2662           0 :         assert(link);
    2663           0 :         assert(link->network);
    2664           0 :         assert(link->state == LINK_STATE_INITIALIZED);
    2665             : 
    2666           0 :         if (link->setting_mtu)
    2667           0 :                 return 0;
    2668             : 
    2669           0 :         if (link_has_carrier(link) || link->network->configure_without_carrier) {
    2670           0 :                 r = link_acquire_conf(link);
    2671           0 :                 if (r < 0)
    2672           0 :                         return r;
    2673             :         }
    2674             : 
    2675           0 :         return link_enter_join_netdev(link);
    2676             : }
    2677             : 
    2678           0 : static int duid_set_uuid(DUID *duid, sd_id128_t uuid) {
    2679           0 :         assert(duid);
    2680             : 
    2681           0 :         if (duid->raw_data_len > 0)
    2682           0 :                 return 0;
    2683             : 
    2684           0 :         if (duid->type != DUID_TYPE_UUID)
    2685           0 :                 return -EINVAL;
    2686             : 
    2687           0 :         memcpy(&duid->raw_data, &uuid, sizeof(sd_id128_t));
    2688           0 :         duid->raw_data_len = sizeof(sd_id128_t);
    2689             : 
    2690           0 :         return 1;
    2691             : }
    2692             : 
    2693           0 : int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
    2694           0 :         Manager *manager = userdata;
    2695             :         const sd_bus_error *e;
    2696             :         const void *a;
    2697             :         size_t sz;
    2698             :         DUID *duid;
    2699             :         Link *link;
    2700             :         int r;
    2701             : 
    2702           0 :         assert(m);
    2703           0 :         assert(manager);
    2704             : 
    2705           0 :         e = sd_bus_message_get_error(m);
    2706           0 :         if (e) {
    2707           0 :                 log_error_errno(sd_bus_error_get_errno(e),
    2708             :                                 "Could not get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %s",
    2709             :                                 e->message);
    2710           0 :                 goto configure;
    2711             :         }
    2712             : 
    2713           0 :         r = sd_bus_message_read_array(m, 'y', &a, &sz);
    2714           0 :         if (r < 0)
    2715           0 :                 goto configure;
    2716             : 
    2717           0 :         if (sz != sizeof(sd_id128_t)) {
    2718           0 :                 log_error("Invalid product UUID. Falling back to use machine-app-specific ID as DUID-UUID.");
    2719           0 :                 goto configure;
    2720             :         }
    2721             : 
    2722           0 :         memcpy(&manager->product_uuid, a, sz);
    2723           0 :         while ((duid = set_steal_first(manager->duids_requesting_uuid)))
    2724           0 :                 (void) duid_set_uuid(duid, manager->product_uuid);
    2725             : 
    2726           0 :         manager->duids_requesting_uuid = set_free(manager->duids_requesting_uuid);
    2727             : 
    2728           0 : configure:
    2729           0 :         while ((link = set_steal_first(manager->links_requesting_uuid))) {
    2730           0 :                 link_unref(link);
    2731             : 
    2732           0 :                 r = link_configure(link);
    2733           0 :                 if (r < 0)
    2734           0 :                         link_enter_failed(link);
    2735             :         }
    2736             : 
    2737           0 :         manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
    2738             : 
    2739             :         /* To avoid calling GetProductUUID() bus method so frequently, set the flag below
    2740             :          * even if the method fails. */
    2741           0 :         manager->has_product_uuid = true;
    2742             : 
    2743           0 :         return 1;
    2744             : }
    2745             : 
    2746           0 : static bool link_requires_uuid(Link *link) {
    2747             :         const DUID *duid;
    2748             : 
    2749           0 :         assert(link);
    2750           0 :         assert(link->manager);
    2751           0 :         assert(link->network);
    2752             : 
    2753           0 :         duid = link_get_duid(link);
    2754           0 :         if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
    2755           0 :                 return false;
    2756             : 
    2757           0 :         if (link_dhcp4_enabled(link) && IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
    2758           0 :                 return true;
    2759             : 
    2760           0 :         if (link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link))
    2761           0 :                 return true;
    2762             : 
    2763           0 :         return false;
    2764             : }
    2765             : 
    2766           0 : static int link_configure_duid(Link *link) {
    2767             :         Manager *m;
    2768             :         DUID *duid;
    2769             :         int r;
    2770             : 
    2771           0 :         assert(link);
    2772           0 :         assert(link->manager);
    2773           0 :         assert(link->network);
    2774             : 
    2775           0 :         m = link->manager;
    2776           0 :         duid = link_get_duid(link);
    2777             : 
    2778           0 :         if (!link_requires_uuid(link))
    2779           0 :                 return 1;
    2780             : 
    2781           0 :         if (m->has_product_uuid) {
    2782           0 :                 (void) duid_set_uuid(duid, m->product_uuid);
    2783           0 :                 return 1;
    2784             :         }
    2785             : 
    2786           0 :         if (!m->links_requesting_uuid) {
    2787           0 :                 r = manager_request_product_uuid(m, link);
    2788           0 :                 if (r < 0) {
    2789           0 :                         if (r == -ENOMEM)
    2790           0 :                                 return r;
    2791             : 
    2792           0 :                         log_link_warning_errno(link, r,
    2793             :                                                "Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
    2794           0 :                         return 1;
    2795             :                 }
    2796             :         } else {
    2797           0 :                 r = set_put(m->links_requesting_uuid, link);
    2798           0 :                 if (r < 0)
    2799           0 :                         return log_oom();
    2800             : 
    2801           0 :                 r = set_put(m->duids_requesting_uuid, duid);
    2802           0 :                 if (r < 0)
    2803           0 :                         return log_oom();
    2804             : 
    2805           0 :                 link_ref(link);
    2806             :         }
    2807             : 
    2808           0 :         return 0;
    2809             : }
    2810             : 
    2811           0 : static int link_initialized_and_synced(Link *link) {
    2812             :         Network *network;
    2813             :         int r;
    2814             : 
    2815           0 :         assert(link);
    2816           0 :         assert(link->ifname);
    2817           0 :         assert(link->manager);
    2818             : 
    2819             :         /* We may get called either from the asynchronous netlink callback,
    2820             :          * or directly for link_add() if running in a container. See link_add(). */
    2821           0 :         if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED))
    2822           0 :                 return 0;
    2823             : 
    2824           0 :         log_link_debug(link, "Link state is up-to-date");
    2825           0 :         link_set_state(link, LINK_STATE_INITIALIZED);
    2826             : 
    2827           0 :         r = link_new_bound_by_list(link);
    2828           0 :         if (r < 0)
    2829           0 :                 return r;
    2830             : 
    2831           0 :         r = link_handle_bound_by_list(link);
    2832           0 :         if (r < 0)
    2833           0 :                 return r;
    2834             : 
    2835           0 :         if (!link->network) {
    2836           0 :                 r = network_get(link->manager, link->sd_device, link->ifname,
    2837           0 :                                 &link->mac, &network);
    2838           0 :                 if (r == -ENOENT) {
    2839           0 :                         link_enter_unmanaged(link);
    2840           0 :                         return 0;
    2841           0 :                 } else if (r == 0 && network->unmanaged) {
    2842           0 :                         link_enter_unmanaged(link);
    2843           0 :                         return 0;
    2844           0 :                 } else if (r < 0)
    2845           0 :                         return r;
    2846             : 
    2847           0 :                 if (link->flags & IFF_LOOPBACK) {
    2848           0 :                         if (network->link_local != ADDRESS_FAMILY_NO)
    2849           0 :                                 log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
    2850             : 
    2851           0 :                         if (network->dhcp != ADDRESS_FAMILY_NO)
    2852           0 :                                 log_link_debug(link, "Ignoring DHCP clients for loopback link");
    2853             : 
    2854           0 :                         if (network->dhcp_server)
    2855           0 :                                 log_link_debug(link, "Ignoring DHCP server for loopback link");
    2856             :                 }
    2857             : 
    2858           0 :                 r = network_apply(network, link);
    2859           0 :                 if (r < 0)
    2860           0 :                         return r;
    2861             :         }
    2862             : 
    2863           0 :         r = link_new_bound_to_list(link);
    2864           0 :         if (r < 0)
    2865           0 :                 return r;
    2866             : 
    2867             :         /* link_configure_duid() returns 0 if it requests product UUID. In that case,
    2868             :          * link_configure() is called later asynchronously. */
    2869           0 :         r = link_configure_duid(link);
    2870           0 :         if (r <= 0)
    2871           0 :                 return r;
    2872             : 
    2873           0 :         r = link_configure(link);
    2874           0 :         if (r < 0)
    2875           0 :                 return r;
    2876             : 
    2877           0 :         return 0;
    2878             : }
    2879             : 
    2880           0 : static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
    2881             :         int r;
    2882             : 
    2883           0 :         r = link_initialized_and_synced(link);
    2884           0 :         if (r < 0)
    2885           0 :                 link_enter_failed(link);
    2886           0 :         return 1;
    2887             : }
    2888             : 
    2889           6 : int link_initialized(Link *link, sd_device *device) {
    2890           6 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
    2891             :         int r;
    2892             : 
    2893           6 :         assert(link);
    2894           6 :         assert(link->manager);
    2895           6 :         assert(link->manager->rtnl);
    2896           6 :         assert(device);
    2897             : 
    2898           6 :         if (link->state != LINK_STATE_PENDING)
    2899           0 :                 return 0;
    2900             : 
    2901           6 :         if (link->sd_device)
    2902           0 :                 return 0;
    2903             : 
    2904           6 :         log_link_debug(link, "udev initialized link");
    2905           6 :         link_set_state(link, LINK_STATE_INITIALIZED);
    2906             : 
    2907           6 :         link->sd_device = sd_device_ref(device);
    2908             : 
    2909             :         /* udev has initialized the link, but we don't know if we have yet
    2910             :          * processed the NEWLINK messages with the latest state. Do a GETLINK,
    2911             :          * when it returns we know that the pending NEWLINKs have already been
    2912             :          * processed and that we are up-to-date */
    2913             : 
    2914           6 :         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
    2915             :                                      link->ifindex);
    2916           6 :         if (r < 0)
    2917           0 :                 return r;
    2918             : 
    2919           6 :         r = netlink_call_async(link->manager->rtnl, NULL, req, link_initialized_handler,
    2920             :                                link_netlink_destroy_callback, link);
    2921           6 :         if (r < 0)
    2922           0 :                 return r;
    2923             : 
    2924           6 :         link_ref(link);
    2925             : 
    2926           6 :         return 0;
    2927             : }
    2928             : 
    2929           6 : static int link_load(Link *link) {
    2930           6 :         _cleanup_free_ char *network_file = NULL,
    2931           6 :                             *addresses = NULL,
    2932           6 :                             *routes = NULL,
    2933           6 :                             *dhcp4_address = NULL,
    2934           6 :                             *ipv4ll_address = NULL;
    2935             :         union in_addr_union address;
    2936             :         union in_addr_union route_dst;
    2937             :         const char *p;
    2938             :         int r;
    2939             : 
    2940           6 :         assert(link);
    2941             : 
    2942           6 :         r = parse_env_file(NULL, link->state_file,
    2943             :                            "NETWORK_FILE", &network_file,
    2944             :                            "ADDRESSES", &addresses,
    2945             :                            "ROUTES", &routes,
    2946             :                            "DHCP4_ADDRESS", &dhcp4_address,
    2947             :                            "IPV4LL_ADDRESS", &ipv4ll_address);
    2948           6 :         if (r < 0 && r != -ENOENT)
    2949           0 :                 return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
    2950             : 
    2951           6 :         if (network_file) {
    2952             :                 Network *network;
    2953             :                 char *suffix;
    2954             : 
    2955             :                 /* drop suffix */
    2956           0 :                 suffix = strrchr(network_file, '.');
    2957           0 :                 if (!suffix) {
    2958           0 :                         log_link_debug(link, "Failed to get network name from %s", network_file);
    2959           0 :                         goto network_file_fail;
    2960             :                 }
    2961           0 :                 *suffix = '\0';
    2962             : 
    2963           0 :                 r = network_get_by_name(link->manager, basename(network_file), &network);
    2964           0 :                 if (r < 0) {
    2965           0 :                         log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
    2966           0 :                         goto network_file_fail;
    2967             :                 }
    2968             : 
    2969           0 :                 r = network_apply(network, link);
    2970           0 :                 if (r < 0)
    2971           0 :                         return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
    2972             :         }
    2973             : 
    2974           6 : network_file_fail:
    2975             : 
    2976           6 :         if (addresses) {
    2977           0 :                 p = addresses;
    2978             : 
    2979           0 :                 for (;;) {
    2980           0 :                         _cleanup_free_ char *address_str = NULL;
    2981             :                         char *prefixlen_str;
    2982             :                         int family;
    2983             :                         unsigned char prefixlen;
    2984             : 
    2985           0 :                         r = extract_first_word(&p, &address_str, NULL, 0);
    2986           0 :                         if (r < 0) {
    2987           0 :                                 log_link_debug_errno(link, r, "Failed to extract next address string: %m");
    2988           0 :                                 continue;
    2989             :                         }
    2990           0 :                         if (r == 0)
    2991           0 :                                 break;
    2992             : 
    2993           0 :                         prefixlen_str = strchr(address_str, '/');
    2994           0 :                         if (!prefixlen_str) {
    2995           0 :                                 log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
    2996           0 :                                 continue;
    2997             :                         }
    2998             : 
    2999           0 :                         *prefixlen_str++ = '\0';
    3000             : 
    3001           0 :                         r = sscanf(prefixlen_str, "%hhu", &prefixlen);
    3002           0 :                         if (r != 1) {
    3003           0 :                                 log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
    3004           0 :                                 continue;
    3005             :                         }
    3006             : 
    3007           0 :                         r = in_addr_from_string_auto(address_str, &family, &address);
    3008           0 :                         if (r < 0) {
    3009           0 :                                 log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
    3010           0 :                                 continue;
    3011             :                         }
    3012             : 
    3013           0 :                         r = address_add(link, family, &address, prefixlen, NULL);
    3014           0 :                         if (r < 0)
    3015           0 :                                 return log_link_error_errno(link, r, "Failed to add address: %m");
    3016             :                 }
    3017             :         }
    3018             : 
    3019           6 :         if (routes) {
    3020           0 :                 p = routes;
    3021             : 
    3022           0 :                 for (;;) {
    3023             :                         Route *route;
    3024           0 :                         _cleanup_free_ char *route_str = NULL;
    3025           0 :                         _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
    3026             :                         usec_t lifetime;
    3027             :                         char *prefixlen_str;
    3028             :                         int family;
    3029             :                         unsigned char prefixlen, tos, table;
    3030             :                         uint32_t priority;
    3031             : 
    3032           0 :                         r = extract_first_word(&p, &route_str, NULL, 0);
    3033           0 :                         if (r < 0) {
    3034           0 :                                 log_link_debug_errno(link, r, "Failed to extract next route string: %m");
    3035           0 :                                 continue;
    3036             :                         }
    3037           0 :                         if (r == 0)
    3038           0 :                                 break;
    3039             : 
    3040           0 :                         prefixlen_str = strchr(route_str, '/');
    3041           0 :                         if (!prefixlen_str) {
    3042           0 :                                 log_link_debug(link, "Failed to parse route %s", route_str);
    3043           0 :                                 continue;
    3044             :                         }
    3045             : 
    3046           0 :                         *prefixlen_str++ = '\0';
    3047             : 
    3048           0 :                         r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%hhu/"USEC_FMT, &prefixlen, &tos, &priority, &table, &lifetime);
    3049           0 :                         if (r != 5) {
    3050           0 :                                 log_link_debug(link,
    3051             :                                                "Failed to parse destination prefix length, tos, priority, table or expiration %s",
    3052             :                                                prefixlen_str);
    3053           0 :                                 continue;
    3054             :                         }
    3055             : 
    3056           0 :                         r = in_addr_from_string_auto(route_str, &family, &route_dst);
    3057           0 :                         if (r < 0) {
    3058           0 :                                 log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
    3059           0 :                                 continue;
    3060             :                         }
    3061             : 
    3062           0 :                         r = route_add(link, family, &route_dst, prefixlen, NULL, tos, priority, table, &route);
    3063           0 :                         if (r < 0)
    3064           0 :                                 return log_link_error_errno(link, r, "Failed to add route: %m");
    3065             : 
    3066           0 :                         if (lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
    3067           0 :                                 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
    3068             :                                                       0, route_expire_handler, route);
    3069           0 :                                 if (r < 0)
    3070           0 :                                         log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
    3071             :                         }
    3072             : 
    3073           0 :                         route->lifetime = lifetime;
    3074           0 :                         sd_event_source_unref(route->expire);
    3075           0 :                         route->expire = TAKE_PTR(expire);
    3076             :                 }
    3077             :         }
    3078             : 
    3079           6 :         if (dhcp4_address) {
    3080           0 :                 r = in_addr_from_string(AF_INET, dhcp4_address, &address);
    3081           0 :                 if (r < 0) {
    3082           0 :                         log_link_debug_errno(link, r, "Failed to parse DHCPv4 address %s: %m", dhcp4_address);
    3083           0 :                         goto dhcp4_address_fail;
    3084             :                 }
    3085             : 
    3086           0 :                 r = sd_dhcp_client_new(&link->dhcp_client, link->network ? link->network->dhcp_anonymize : 0);
    3087           0 :                 if (r < 0)
    3088           0 :                         return log_link_error_errno(link, r, "Failed to create DHCPv4 client: %m");
    3089             : 
    3090           0 :                 r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in);
    3091           0 :                 if (r < 0)
    3092           0 :                         return log_link_error_errno(link, r, "Failed to set initial DHCPv4 address %s: %m", dhcp4_address);
    3093             :         }
    3094             : 
    3095           6 : dhcp4_address_fail:
    3096             : 
    3097           6 :         if (ipv4ll_address) {
    3098           0 :                 r = in_addr_from_string(AF_INET, ipv4ll_address, &address);
    3099           0 :                 if (r < 0) {
    3100           0 :                         log_link_debug_errno(link, r, "Failed to parse IPv4LL address %s: %m", ipv4ll_address);
    3101           0 :                         goto ipv4ll_address_fail;
    3102             :                 }
    3103             : 
    3104           0 :                 r = sd_ipv4ll_new(&link->ipv4ll);
    3105           0 :                 if (r < 0)
    3106           0 :                         return log_link_error_errno(link, r, "Failed to create IPv4LL client: %m");
    3107             : 
    3108           0 :                 r = sd_ipv4ll_set_address(link->ipv4ll, &address.in);
    3109           0 :                 if (r < 0)
    3110           0 :                         return log_link_error_errno(link, r, "Failed to set initial IPv4LL address %s: %m", ipv4ll_address);
    3111             :         }
    3112             : 
    3113           6 : ipv4ll_address_fail:
    3114             : 
    3115           6 :         return 0;
    3116             : }
    3117             : 
    3118           6 : int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
    3119           6 :         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
    3120             :         char ifindex_str[2 + DECIMAL_STR_MAX(int)];
    3121             :         Link *link;
    3122             :         int r;
    3123             : 
    3124           6 :         assert(m);
    3125           6 :         assert(m->rtnl);
    3126           6 :         assert(message);
    3127           6 :         assert(ret);
    3128             : 
    3129           6 :         r = link_new(m, message, ret);
    3130           6 :         if (r < 0)
    3131           0 :                 return r;
    3132             : 
    3133           6 :         link = *ret;
    3134             : 
    3135           6 :         log_link_debug(link, "Link %d added", link->ifindex);
    3136             : 
    3137           6 :         r = link_load(link);
    3138           6 :         if (r < 0)
    3139           0 :                 return r;
    3140             : 
    3141           6 :         if (detect_container() <= 0) {
    3142             :                 /* not in a container, udev will be around */
    3143           6 :                 sprintf(ifindex_str, "n%d", link->ifindex);
    3144           6 :                 r = sd_device_new_from_device_id(&device, ifindex_str);
    3145           6 :                 if (r < 0) {
    3146           0 :                         log_link_warning_errno(link, r, "Could not find device: %m");
    3147           0 :                         goto failed;
    3148             :                 }
    3149             : 
    3150           6 :                 r = sd_device_get_is_initialized(device);
    3151           6 :                 if (r < 0) {
    3152           0 :                         log_link_warning_errno(link, r, "Could not determine whether the device is initialized or not: %m");
    3153           0 :                         goto failed;
    3154             :                 }
    3155           6 :                 if (r == 0) {
    3156             :                         /* not yet ready */
    3157           0 :                         log_link_debug(link, "link pending udev initialization...");
    3158           0 :                         return 0;
    3159             :                 }
    3160             : 
    3161           6 :                 r = device_is_renaming(device);
    3162           6 :                 if (r < 0) {
    3163           0 :                         log_link_warning_errno(link, r, "Failed to determine the device is renamed or not: %m");
    3164           0 :                         goto failed;
    3165             :                 }
    3166           6 :                 if (r > 0) {
    3167           0 :                         log_link_debug(link, "Interface is under renaming, pending initialization.");
    3168           0 :                         return 0;
    3169             :                 }
    3170             : 
    3171           6 :                 r = link_initialized(link, device);
    3172           6 :                 if (r < 0)
    3173           0 :                         goto failed;
    3174             :         } else {
    3175           0 :                 r = link_initialized_and_synced(link);
    3176           0 :                 if (r < 0)
    3177           0 :                         goto failed;
    3178             :         }
    3179             : 
    3180           6 :         return 0;
    3181           0 : failed:
    3182           0 :         link_enter_failed(link);
    3183           0 :         return r;
    3184             : }
    3185             : 
    3186           0 : int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
    3187             :         int r;
    3188             : 
    3189           0 :         assert(link);
    3190             : 
    3191           0 :         log_link_info(link, "Gained IPv6LL");
    3192             : 
    3193           0 :         link->ipv6ll_address = *address;
    3194           0 :         link_check_ready(link);
    3195             : 
    3196           0 :         if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
    3197           0 :                 r = link_acquire_ipv6_conf(link);
    3198           0 :                 if (r < 0) {
    3199           0 :                         link_enter_failed(link);
    3200           0 :                         return r;
    3201             :                 }
    3202             :         }
    3203             : 
    3204           0 :         return 0;
    3205             : }
    3206             : 
    3207           0 : static int link_carrier_gained(Link *link) {
    3208             :         int r;
    3209             : 
    3210           0 :         assert(link);
    3211             : 
    3212           0 :         if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
    3213           0 :                 r = link_acquire_conf(link);
    3214           0 :                 if (r < 0) {
    3215           0 :                         link_enter_failed(link);
    3216           0 :                         return r;
    3217             :                 }
    3218             : 
    3219           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
    3220           0 :                 r = link_request_set_addresses(link);
    3221           0 :                 if (r < 0)
    3222           0 :                         return r;
    3223             :         }
    3224             : 
    3225           0 :         r = link_handle_bound_by_list(link);
    3226           0 :         if (r < 0)
    3227           0 :                 return r;
    3228             : 
    3229           0 :         return 0;
    3230             : }
    3231             : 
    3232           0 : static int link_carrier_lost(Link *link) {
    3233             :         int r;
    3234             : 
    3235           0 :         assert(link);
    3236             : 
    3237           0 :         if (link->network && link->network->ignore_carrier_loss)
    3238           0 :                 return 0;
    3239             : 
    3240             :         /* Some devices reset itself while setting the MTU. This causes the DHCP client fall into a loop.
    3241             :          * setting_mtu keep track whether the device got reset because of setting MTU and does not drop the
    3242             :          * configuration and stop the clients as well. */
    3243           0 :         if (link->setting_mtu)
    3244           0 :                 return 0;
    3245             : 
    3246           0 :         r = link_stop_clients(link, false);
    3247           0 :         if (r < 0) {
    3248           0 :                 link_enter_failed(link);
    3249           0 :                 return r;
    3250             :         }
    3251             : 
    3252           0 :         if (link_dhcp4_server_enabled(link))
    3253           0 :                 (void) sd_dhcp_server_stop(link->dhcp_server);
    3254             : 
    3255           0 :         r = link_drop_config(link);
    3256           0 :         if (r < 0)
    3257           0 :                 return r;
    3258             : 
    3259           0 :         if (!IN_SET(link->state, LINK_STATE_UNMANAGED, LINK_STATE_PENDING)) {
    3260           0 :                 log_link_debug(link, "State is %s, dropping config", link_state_to_string(link->state));
    3261           0 :                 r = link_drop_foreign_config(link);
    3262           0 :                 if (r < 0)
    3263           0 :                         return r;
    3264             :         }
    3265             : 
    3266           0 :         r = link_handle_bound_by_list(link);
    3267           0 :         if (r < 0)
    3268           0 :                 return r;
    3269             : 
    3270           0 :         return 0;
    3271             : }
    3272             : 
    3273           0 : int link_carrier_reset(Link *link) {
    3274             :         int r;
    3275             : 
    3276           0 :         assert(link);
    3277             : 
    3278           0 :         if (link_has_carrier(link)) {
    3279           0 :                 r = link_carrier_lost(link);
    3280           0 :                 if (r < 0)
    3281           0 :                         return r;
    3282             : 
    3283           0 :                 r = link_carrier_gained(link);
    3284           0 :                 if (r < 0)
    3285           0 :                         return r;
    3286             : 
    3287           0 :                 log_link_info(link, "Reset carrier");
    3288             :         }
    3289             : 
    3290           0 :         return 0;
    3291             : }
    3292             : 
    3293           6 : int link_update(Link *link, sd_netlink_message *m) {
    3294             :         struct ether_addr mac;
    3295             :         const char *ifname;
    3296             :         uint32_t mtu;
    3297             :         bool had_carrier, carrier_gained, carrier_lost;
    3298             :         int old_master, r;
    3299             : 
    3300           6 :         assert(link);
    3301           6 :         assert(link->ifname);
    3302           6 :         assert(m);
    3303             : 
    3304           6 :         if (link->state == LINK_STATE_LINGER) {
    3305           0 :                 log_link_info(link, "Link re-added");
    3306           0 :                 link_set_state(link, LINK_STATE_CONFIGURING);
    3307             : 
    3308           0 :                 r = link_new_carrier_maps(link);
    3309           0 :                 if (r < 0)
    3310           0 :                         return r;
    3311             :         }
    3312             : 
    3313           6 :         r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname);
    3314           6 :         if (r >= 0 && !streq(ifname, link->ifname)) {
    3315           0 :                 Manager *manager = link->manager;
    3316             : 
    3317           0 :                 log_link_info(link, "Interface name change detected, %s has been renamed to %s.", link->ifname, ifname);
    3318             : 
    3319           0 :                 link_drop(link);
    3320           0 :                 r = link_add(manager, m, &link);
    3321           0 :                 if (r < 0)
    3322           0 :                         return r;
    3323             :         }
    3324             : 
    3325           6 :         r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
    3326           6 :         if (r >= 0 && mtu > 0) {
    3327           6 :                 link->mtu = mtu;
    3328           6 :                 if (link->original_mtu == 0) {
    3329           6 :                         link->original_mtu = mtu;
    3330           6 :                         log_link_debug(link, "Saved original MTU: %" PRIu32, link->original_mtu);
    3331             :                 }
    3332             : 
    3333           6 :                 if (link->dhcp_client) {
    3334           0 :                         r = sd_dhcp_client_set_mtu(link->dhcp_client,
    3335           0 :                                                    link->mtu);
    3336           0 :                         if (r < 0)
    3337           0 :                                 return log_link_warning_errno(link, r, "Could not update MTU in DHCP client: %m");
    3338             :                 }
    3339             : 
    3340           6 :                 if (link->radv) {
    3341           0 :                         r = sd_radv_set_mtu(link->radv, link->mtu);
    3342           0 :                         if (r < 0)
    3343           0 :                                 return log_link_warning_errno(link, r, "Could not set MTU for Router Advertisement: %m");
    3344             :                 }
    3345             :         }
    3346             : 
    3347             :         /* The kernel may broadcast NEWLINK messages without the MAC address
    3348             :            set, simply ignore them. */
    3349           6 :         r = sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
    3350           6 :         if (r >= 0) {
    3351           5 :                 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
    3352             :                            ETH_ALEN)) {
    3353             : 
    3354           0 :                         memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
    3355             :                                ETH_ALEN);
    3356             : 
    3357           0 :                         log_link_debug(link, "MAC address: "
    3358             :                                        "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
    3359             :                                        mac.ether_addr_octet[0],
    3360             :                                        mac.ether_addr_octet[1],
    3361             :                                        mac.ether_addr_octet[2],
    3362             :                                        mac.ether_addr_octet[3],
    3363             :                                        mac.ether_addr_octet[4],
    3364             :                                        mac.ether_addr_octet[5]);
    3365             : 
    3366           0 :                         if (link->ipv4ll) {
    3367           0 :                                 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
    3368           0 :                                 if (r < 0)
    3369           0 :                                         return log_link_warning_errno(link, r, "Could not update MAC address in IPv4LL client: %m");
    3370             :                         }
    3371             : 
    3372           0 :                         if (link->dhcp_client) {
    3373           0 :                                 r = sd_dhcp_client_set_mac(link->dhcp_client,
    3374           0 :                                                            (const uint8_t *) &link->mac,
    3375             :                                                            sizeof (link->mac),
    3376             :                                                            ARPHRD_ETHER);
    3377           0 :                                 if (r < 0)
    3378           0 :                                         return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
    3379             : 
    3380           0 :                                 r = dhcp4_set_client_identifier(link);
    3381           0 :                                 if (r < 0)
    3382           0 :                                         return r;
    3383             :                         }
    3384             : 
    3385           0 :                         if (link->dhcp6_client) {
    3386           0 :                                 const DUID* duid = link_get_duid(link);
    3387             : 
    3388           0 :                                 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
    3389           0 :                                                             (const uint8_t *) &link->mac,
    3390             :                                                             sizeof (link->mac),
    3391             :                                                             ARPHRD_ETHER);
    3392           0 :                                 if (r < 0)
    3393           0 :                                         return log_link_warning_errno(link, r, "Could not update MAC address in DHCPv6 client: %m");
    3394             : 
    3395           0 :                                 if (link->network->iaid_set) {
    3396           0 :                                         r = sd_dhcp6_client_set_iaid(link->dhcp6_client,
    3397           0 :                                                                      link->network->iaid);
    3398           0 :                                         if (r < 0)
    3399           0 :                                                 return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
    3400             :                                 }
    3401             : 
    3402           0 :                                 r = sd_dhcp6_client_set_duid(link->dhcp6_client,
    3403           0 :                                                              duid->type,
    3404           0 :                                                              duid->raw_data_len > 0 ? duid->raw_data : NULL,
    3405           0 :                                                              duid->raw_data_len);
    3406           0 :                                 if (r < 0)
    3407           0 :                                         return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
    3408             :                         }
    3409             : 
    3410           0 :                         if (link->radv) {
    3411           0 :                                 r = sd_radv_set_mac(link->radv, &link->mac);
    3412           0 :                                 if (r < 0)
    3413           0 :                                         return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
    3414             :                         }
    3415             : 
    3416           0 :                         if (link->ndisc) {
    3417           0 :                                 r = sd_ndisc_set_mac(link->ndisc, &link->mac);
    3418           0 :                                 if (r < 0)
    3419           0 :                                         return log_link_warning_errno(link, r, "Could not update MAC for ndisc: %m");
    3420             :                         }
    3421             :                 }
    3422             :         }
    3423             : 
    3424           6 :         old_master = link->master_ifindex;
    3425           6 :         (void) sd_netlink_message_read_u32(m, IFLA_MASTER, (uint32_t *) &link->master_ifindex);
    3426             : 
    3427           6 :         had_carrier = link_has_carrier(link);
    3428             : 
    3429           6 :         r = link_update_flags(link, m, old_master != link->master_ifindex);
    3430           6 :         if (r < 0)
    3431           0 :                 return r;
    3432             : 
    3433           6 :         r = link_update_lldp(link);
    3434           6 :         if (r < 0)
    3435           0 :                 return r;
    3436             : 
    3437           6 :         carrier_gained = !had_carrier && link_has_carrier(link);
    3438           6 :         carrier_lost = had_carrier && !link_has_carrier(link);
    3439             : 
    3440           6 :         if (carrier_gained) {
    3441           0 :                 log_link_info(link, "Gained carrier");
    3442             : 
    3443           0 :                 r = link_carrier_gained(link);
    3444           0 :                 if (r < 0)
    3445           0 :                         return r;
    3446           6 :         } else if (carrier_lost) {
    3447           0 :                 log_link_info(link, "Lost carrier");
    3448             : 
    3449           0 :                 r = link_carrier_lost(link);
    3450           0 :                 if (r < 0)
    3451           0 :                         return r;
    3452             :         }
    3453             : 
    3454           6 :         return 0;
    3455             : }
    3456             : 
    3457           0 : static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
    3458           0 :         bool space = false;
    3459             :         Iterator i;
    3460             :         Link *link;
    3461             : 
    3462           0 :         assert(f);
    3463           0 :         assert(prefix);
    3464             : 
    3465           0 :         if (hashmap_isempty(h))
    3466           0 :                 return;
    3467             : 
    3468           0 :         fputs(prefix, f);
    3469           0 :         HASHMAP_FOREACH(link, h, i) {
    3470           0 :                 if (space)
    3471           0 :                         fputc(' ', f);
    3472             : 
    3473           0 :                 fprintf(f, "%i", link->ifindex);
    3474           0 :                 space = true;
    3475             :         }
    3476             : 
    3477           0 :         fputc('\n', f);
    3478             : }
    3479             : 
    3480           0 : static void link_save_dns(FILE *f, struct in_addr_data *dns, unsigned n_dns, bool *space) {
    3481             :         unsigned j;
    3482             :         int r;
    3483             : 
    3484           0 :         for (j = 0; j < n_dns; j++) {
    3485           0 :                 _cleanup_free_ char *b = NULL;
    3486             : 
    3487           0 :                 r = in_addr_to_string(dns[j].family, &dns[j].address, &b);
    3488           0 :                 if (r < 0) {
    3489           0 :                         log_debug_errno(r, "Failed to format address, ignoring: %m");
    3490           0 :                         continue;
    3491             :                 }
    3492             : 
    3493           0 :                 if (*space)
    3494           0 :                         fputc(' ', f);
    3495           0 :                 fputs(b, f);
    3496           0 :                 *space = true;
    3497             :         }
    3498           0 : }
    3499             : 
    3500           0 : int link_save(Link *link) {
    3501           0 :         _cleanup_free_ char *temp_path = NULL;
    3502           0 :         _cleanup_fclose_ FILE *f = NULL;
    3503             :         const char *admin_state, *oper_state, *carrier_state, *address_state;
    3504             :         Address *a;
    3505             :         Route *route;
    3506             :         Iterator i;
    3507             :         int r;
    3508             : 
    3509           0 :         assert(link);
    3510           0 :         assert(link->state_file);
    3511           0 :         assert(link->lease_file);
    3512           0 :         assert(link->manager);
    3513             : 
    3514           0 :         if (link->state == LINK_STATE_LINGER) {
    3515           0 :                 (void) unlink(link->state_file);
    3516           0 :                 return 0;
    3517             :         }
    3518             : 
    3519           0 :         link_lldp_save(link);
    3520             : 
    3521           0 :         admin_state = link_state_to_string(link->state);
    3522           0 :         assert(admin_state);
    3523             : 
    3524           0 :         oper_state = link_operstate_to_string(link->operstate);
    3525           0 :         assert(oper_state);
    3526             : 
    3527           0 :         carrier_state = link_carrier_state_to_string(link->carrier_state);
    3528           0 :         assert(carrier_state);
    3529             : 
    3530           0 :         address_state = link_address_state_to_string(link->address_state);
    3531           0 :         assert(address_state);
    3532             : 
    3533           0 :         r = fopen_temporary(link->state_file, &f, &temp_path);
    3534           0 :         if (r < 0)
    3535           0 :                 goto fail;
    3536             : 
    3537           0 :         (void) fchmod(fileno(f), 0644);
    3538             : 
    3539           0 :         fprintf(f,
    3540             :                 "# This is private data. Do not parse.\n"
    3541             :                 "ADMIN_STATE=%s\n"
    3542             :                 "OPER_STATE=%s\n"
    3543             :                 "CARRIER_STATE=%s\n"
    3544             :                 "ADDRESS_STATE=%s\n",
    3545             :                 admin_state, oper_state, carrier_state, address_state);
    3546             : 
    3547           0 :         if (link->network) {
    3548           0 :                 char **dhcp6_domains = NULL, **dhcp_domains = NULL;
    3549           0 :                 const char *dhcp_domainname = NULL, *p;
    3550           0 :                 sd_dhcp6_lease *dhcp6_lease = NULL;
    3551             :                 bool space;
    3552             : 
    3553           0 :                 fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
    3554           0 :                         yes_no(link->network->required_for_online));
    3555             : 
    3556           0 :                 fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s\n",
    3557           0 :                         strempty(link_operstate_to_string(link->network->required_operstate_for_online)));
    3558             : 
    3559           0 :                 if (link->dhcp6_client) {
    3560           0 :                         r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
    3561           0 :                         if (r < 0 && r != -ENOMSG)
    3562           0 :                                 log_link_debug(link, "No DHCPv6 lease");
    3563             :                 }
    3564             : 
    3565           0 :                 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
    3566             : 
    3567           0 :                 fputs("DNS=", f);
    3568           0 :                 space = false;
    3569             : 
    3570           0 :                 if (link->n_dns != (unsigned) -1)
    3571           0 :                         link_save_dns(f, link->dns, link->n_dns, &space);
    3572             :                 else
    3573           0 :                         link_save_dns(f, link->network->dns, link->network->n_dns, &space);
    3574             : 
    3575           0 :                 if (link->network->dhcp_use_dns &&
    3576           0 :                     link->dhcp_lease) {
    3577             :                         const struct in_addr *addresses;
    3578             : 
    3579           0 :                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
    3580           0 :                         if (r > 0)
    3581           0 :                                 if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
    3582           0 :                                         space = true;
    3583             :                 }
    3584             : 
    3585           0 :                 if (link->network->dhcp6_use_dns && dhcp6_lease) {
    3586             :                         struct in6_addr *in6_addrs;
    3587             : 
    3588           0 :                         r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs);
    3589           0 :                         if (r > 0) {
    3590           0 :                                 if (space)
    3591           0 :                                         fputc(' ', f);
    3592           0 :                                 serialize_in6_addrs(f, in6_addrs, r);
    3593           0 :                                 space = true;
    3594             :                         }
    3595             :                 }
    3596             : 
    3597             :                 /* Make sure to flush out old entries before we use the NDISC data */
    3598           0 :                 ndisc_vacuum(link);
    3599             : 
    3600           0 :                 if (link->network->ipv6_accept_ra_use_dns && link->ndisc_rdnss) {
    3601             :                         NDiscRDNSS *dd;
    3602             : 
    3603           0 :                         SET_FOREACH(dd, link->ndisc_rdnss, i) {
    3604           0 :                                 if (space)
    3605           0 :                                         fputc(' ', f);
    3606             : 
    3607           0 :                                 serialize_in6_addrs(f, &dd->address, 1);
    3608           0 :                                 space = true;
    3609             :                         }
    3610             :                 }
    3611             : 
    3612           0 :                 fputc('\n', f);
    3613             : 
    3614           0 :                 fputs("NTP=", f);
    3615           0 :                 space = false;
    3616           0 :                 fputstrv(f, link->ntp ?: link->network->ntp, NULL, &space);
    3617             : 
    3618           0 :                 if (link->network->dhcp_use_ntp &&
    3619           0 :                     link->dhcp_lease) {
    3620             :                         const struct in_addr *addresses;
    3621             : 
    3622           0 :                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
    3623           0 :                         if (r > 0)
    3624           0 :                                 if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
    3625           0 :                                         space = true;
    3626             :                 }
    3627             : 
    3628           0 :                 if (link->network->dhcp6_use_ntp && dhcp6_lease) {
    3629             :                         struct in6_addr *in6_addrs;
    3630             :                         char **hosts;
    3631             : 
    3632           0 :                         r = sd_dhcp6_lease_get_ntp_addrs(dhcp6_lease,
    3633             :                                                          &in6_addrs);
    3634           0 :                         if (r > 0) {
    3635           0 :                                 if (space)
    3636           0 :                                         fputc(' ', f);
    3637           0 :                                 serialize_in6_addrs(f, in6_addrs, r);
    3638           0 :                                 space = true;
    3639             :                         }
    3640             : 
    3641           0 :                         r = sd_dhcp6_lease_get_ntp_fqdn(dhcp6_lease, &hosts);
    3642           0 :                         if (r > 0)
    3643           0 :                                 fputstrv(f, hosts, NULL, &space);
    3644             :                 }
    3645             : 
    3646           0 :                 fputc('\n', f);
    3647             : 
    3648           0 :                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
    3649           0 :                         if (link->dhcp_lease) {
    3650           0 :                                 (void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
    3651           0 :                                 (void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
    3652             :                         }
    3653           0 :                         if (dhcp6_lease)
    3654           0 :                                 (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
    3655             :                 }
    3656             : 
    3657           0 :                 fputs("DOMAINS=", f);
    3658           0 :                 space = false;
    3659           0 :                 ORDERED_SET_FOREACH(p, link->search_domains ?: link->network->search_domains, i)
    3660           0 :                         fputs_with_space(f, p, NULL, &space);
    3661             : 
    3662           0 :                 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
    3663           0 :                         if (dhcp_domainname)
    3664           0 :                                 fputs_with_space(f, dhcp_domainname, NULL, &space);
    3665           0 :                         if (dhcp_domains)
    3666           0 :                                 fputstrv(f, dhcp_domains, NULL, &space);
    3667           0 :                         if (dhcp6_domains)
    3668           0 :                                 fputstrv(f, dhcp6_domains, NULL, &space);
    3669             :                 }
    3670             : 
    3671           0 :                 if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_YES) {
    3672             :                         NDiscDNSSL *dd;
    3673             : 
    3674           0 :                         SET_FOREACH(dd, link->ndisc_dnssl, i)
    3675           0 :                                 fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
    3676             :                 }
    3677             : 
    3678           0 :                 fputc('\n', f);
    3679             : 
    3680           0 :                 fputs("ROUTE_DOMAINS=", f);
    3681           0 :                 space = false;
    3682           0 :                 ORDERED_SET_FOREACH(p, link->route_domains ?: link->network->route_domains, i)
    3683           0 :                         fputs_with_space(f, p, NULL, &space);
    3684             : 
    3685           0 :                 if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
    3686           0 :                         if (dhcp_domainname)
    3687           0 :                                 fputs_with_space(f, dhcp_domainname, NULL, &space);
    3688           0 :                         if (dhcp_domains)
    3689           0 :                                 fputstrv(f, dhcp_domains, NULL, &space);
    3690           0 :                         if (dhcp6_domains)
    3691           0 :                                 fputstrv(f, dhcp6_domains, NULL, &space);
    3692             :                 }
    3693             : 
    3694           0 :                 if (link->network->ipv6_accept_ra_use_domains == DHCP_USE_DOMAINS_ROUTE) {
    3695             :                         NDiscDNSSL *dd;
    3696             : 
    3697           0 :                         SET_FOREACH(dd, link->ndisc_dnssl, i)
    3698           0 :                                 fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
    3699             :                 }
    3700             : 
    3701           0 :                 fputc('\n', f);
    3702             : 
    3703           0 :                 fprintf(f, "LLMNR=%s\n",
    3704           0 :                         resolve_support_to_string(link->llmnr >= 0 ? link->llmnr : link->network->llmnr));
    3705           0 :                 fprintf(f, "MDNS=%s\n",
    3706           0 :                         resolve_support_to_string(link->mdns >= 0 ? link->mdns : link->network->mdns));
    3707           0 :                 if (link->dns_default_route >= 0)
    3708           0 :                         fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->dns_default_route));
    3709           0 :                 else if (link->network->dns_default_route >= 0)
    3710           0 :                         fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(link->network->dns_default_route));
    3711             : 
    3712           0 :                 if (link->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
    3713           0 :                         fprintf(f, "DNS_OVER_TLS=%s\n",
    3714             :                                 dns_over_tls_mode_to_string(link->dns_over_tls_mode));
    3715           0 :                 else if (link->network->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
    3716           0 :                         fprintf(f, "DNS_OVER_TLS=%s\n",
    3717           0 :                                 dns_over_tls_mode_to_string(link->network->dns_over_tls_mode));
    3718             : 
    3719           0 :                 if (link->dnssec_mode != _DNSSEC_MODE_INVALID)
    3720           0 :                         fprintf(f, "DNSSEC=%s\n",
    3721             :                                 dnssec_mode_to_string(link->dnssec_mode));
    3722           0 :                 else if (link->network->dnssec_mode != _DNSSEC_MODE_INVALID)
    3723           0 :                         fprintf(f, "DNSSEC=%s\n",
    3724           0 :                                 dnssec_mode_to_string(link->network->dnssec_mode));
    3725             : 
    3726           0 :                 if (!set_isempty(link->dnssec_negative_trust_anchors)) {
    3727             :                         const char *n;
    3728             : 
    3729           0 :                         fputs("DNSSEC_NTA=", f);
    3730           0 :                         space = false;
    3731           0 :                         SET_FOREACH(n, link->dnssec_negative_trust_anchors, i)
    3732           0 :                                 fputs_with_space(f, n, NULL, &space);
    3733           0 :                         fputc('\n', f);
    3734           0 :                 } else if (!set_isempty(link->network->dnssec_negative_trust_anchors)) {
    3735             :                         const char *n;
    3736             : 
    3737           0 :                         fputs("DNSSEC_NTA=", f);
    3738           0 :                         space = false;
    3739           0 :                         SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i)
    3740           0 :                                 fputs_with_space(f, n, NULL, &space);
    3741           0 :                         fputc('\n', f);
    3742             :                 }
    3743             : 
    3744           0 :                 fputs("ADDRESSES=", f);
    3745           0 :                 space = false;
    3746           0 :                 SET_FOREACH(a, link->addresses, i) {
    3747           0 :                         _cleanup_free_ char *address_str = NULL;
    3748             : 
    3749           0 :                         r = in_addr_to_string(a->family, &a->in_addr, &address_str);
    3750           0 :                         if (r < 0)
    3751           0 :                                 goto fail;
    3752             : 
    3753           0 :                         fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
    3754           0 :                         space = true;
    3755             :                 }
    3756           0 :                 fputc('\n', f);
    3757             : 
    3758           0 :                 fputs("ROUTES=", f);
    3759           0 :                 space = false;
    3760           0 :                 SET_FOREACH(route, link->routes, i) {
    3761           0 :                         _cleanup_free_ char *route_str = NULL;
    3762             : 
    3763           0 :                         r = in_addr_to_string(route->family, &route->dst, &route_str);
    3764           0 :                         if (r < 0)
    3765           0 :                                 goto fail;
    3766             : 
    3767           0 :                         fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%"PRIu32"/"USEC_FMT,
    3768           0 :                                 space ? " " : "", route_str,
    3769           0 :                                 route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime);
    3770           0 :                         space = true;
    3771             :                 }
    3772             : 
    3773           0 :                 fputc('\n', f);
    3774             :         }
    3775             : 
    3776           0 :         print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
    3777           0 :         print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
    3778             : 
    3779           0 :         if (link->dhcp_lease) {
    3780             :                 struct in_addr address;
    3781           0 :                 const char *tz = NULL;
    3782             : 
    3783           0 :                 assert(link->network);
    3784             : 
    3785           0 :                 r = sd_dhcp_lease_get_timezone(link->dhcp_lease, &tz);
    3786           0 :                 if (r >= 0)
    3787           0 :                         fprintf(f, "TIMEZONE=%s\n", tz);
    3788             : 
    3789           0 :                 r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
    3790           0 :                 if (r >= 0) {
    3791           0 :                         fputs("DHCP4_ADDRESS=", f);
    3792           0 :                         serialize_in_addrs(f, &address, 1, false, NULL);
    3793           0 :                         fputc('\n', f);
    3794             :                 }
    3795             : 
    3796           0 :                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
    3797           0 :                 if (r < 0)
    3798           0 :                         goto fail;
    3799             : 
    3800           0 :                 fprintf(f,
    3801             :                         "DHCP_LEASE=%s\n",
    3802             :                         link->lease_file);
    3803             :         } else
    3804           0 :                 (void) unlink(link->lease_file);
    3805             : 
    3806           0 :         if (link->ipv4ll) {
    3807             :                 struct in_addr address;
    3808             : 
    3809           0 :                 r = sd_ipv4ll_get_address(link->ipv4ll, &address);
    3810           0 :                 if (r >= 0) {
    3811           0 :                         fputs("IPV4LL_ADDRESS=", f);
    3812           0 :                         serialize_in_addrs(f, &address, 1, false, NULL);
    3813           0 :                         fputc('\n', f);
    3814             :                 }
    3815             :         }
    3816             : 
    3817           0 :         r = fflush_and_check(f);
    3818           0 :         if (r < 0)
    3819           0 :                 goto fail;
    3820             : 
    3821           0 :         if (rename(temp_path, link->state_file) < 0) {
    3822           0 :                 r = -errno;
    3823           0 :                 goto fail;
    3824             :         }
    3825             : 
    3826           0 :         return 0;
    3827             : 
    3828           0 : fail:
    3829           0 :         (void) unlink(link->state_file);
    3830           0 :         if (temp_path)
    3831           0 :                 (void) unlink(temp_path);
    3832             : 
    3833           0 :         return log_link_error_errno(link, r, "Failed to save link data to %s: %m", link->state_file);
    3834             : }
    3835             : 
    3836             : /* The serialized state in /run is no longer up-to-date. */
    3837           5 : void link_dirty(Link *link) {
    3838             :         int r;
    3839             : 
    3840           5 :         assert(link);
    3841             : 
    3842             :         /* mark manager dirty as link is dirty */
    3843           5 :         manager_dirty(link->manager);
    3844             : 
    3845           5 :         r = set_ensure_allocated(&link->manager->dirty_links, NULL);
    3846           5 :         if (r < 0)
    3847             :                 /* allocation errors are ignored */
    3848           0 :                 return;
    3849             : 
    3850           5 :         r = set_put(link->manager->dirty_links, link);
    3851           5 :         if (r <= 0)
    3852             :                 /* don't take another ref if the link was already dirty */
    3853           0 :                 return;
    3854             : 
    3855           5 :         link_ref(link);
    3856             : }
    3857             : 
    3858             : /* The serialized state in /run is up-to-date */
    3859           0 : void link_clean(Link *link) {
    3860           0 :         assert(link);
    3861           0 :         assert(link->manager);
    3862             : 
    3863           0 :         link_unref(set_remove(link->manager->dirty_links, link));
    3864           0 : }
    3865             : 
    3866             : static const char* const link_state_table[_LINK_STATE_MAX] = {
    3867             :         [LINK_STATE_PENDING] = "pending",
    3868             :         [LINK_STATE_INITIALIZED] = "initialized",
    3869             :         [LINK_STATE_CONFIGURING] = "configuring",
    3870             :         [LINK_STATE_CONFIGURED] = "configured",
    3871             :         [LINK_STATE_UNMANAGED] = "unmanaged",
    3872             :         [LINK_STATE_FAILED] = "failed",
    3873             :         [LINK_STATE_LINGER] = "linger",
    3874             : };
    3875             : 
    3876          12 : DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);

Generated by: LCOV version 1.14