LCOV - code coverage report
Current view: top level - network - networkd-manager.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 185 1220 15.2 %
Date: 2019-08-23 13:36:53 Functions: 12 40 30.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 83 1301 6.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <netinet/in.h>
       4                 :            : #include <sys/socket.h>
       5                 :            : #include <unistd.h>
       6                 :            : #include <linux/if.h>
       7                 :            : #include <linux/fib_rules.h>
       8                 :            : 
       9                 :            : #include "sd-daemon.h"
      10                 :            : #include "sd-netlink.h"
      11                 :            : 
      12                 :            : #include "alloc-util.h"
      13                 :            : #include "bus-util.h"
      14                 :            : #include "conf-parser.h"
      15                 :            : #include "def.h"
      16                 :            : #include "device-private.h"
      17                 :            : #include "device-util.h"
      18                 :            : #include "dns-domain.h"
      19                 :            : #include "fd-util.h"
      20                 :            : #include "fileio.h"
      21                 :            : #include "local-addresses.h"
      22                 :            : #include "netlink-util.h"
      23                 :            : #include "network-internal.h"
      24                 :            : #include "networkd-dhcp6.h"
      25                 :            : #include "networkd-link-bus.h"
      26                 :            : #include "networkd-manager-bus.h"
      27                 :            : #include "networkd-manager.h"
      28                 :            : #include "networkd-network-bus.h"
      29                 :            : #include "networkd-speed-meter.h"
      30                 :            : #include "ordered-set.h"
      31                 :            : #include "path-util.h"
      32                 :            : #include "set.h"
      33                 :            : #include "strv.h"
      34                 :            : #include "sysctl-util.h"
      35                 :            : #include "tmpfile-util.h"
      36                 :            : #include "udev-util.h"
      37                 :            : #include "virt.h"
      38                 :            : 
      39                 :            : /* use 8 MB for receive socket kernel queue. */
      40                 :            : #define RCVBUF_SIZE    (8*1024*1024)
      41                 :            : 
      42                 :          4 : static int setup_default_address_pool(Manager *m) {
      43                 :            :         AddressPool *p;
      44                 :            :         int r;
      45                 :            : 
      46         [ -  + ]:          4 :         assert(m);
      47                 :            : 
      48                 :            :         /* Add in the well-known private address ranges. */
      49                 :            : 
      50                 :          4 :         r = address_pool_new_from_string(m, &p, AF_INET6, "fd00::", 8);
      51         [ -  + ]:          4 :         if (r < 0)
      52                 :          0 :                 return r;
      53                 :            : 
      54                 :          4 :         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
      55         [ -  + ]:          4 :         if (r < 0)
      56                 :          0 :                 return r;
      57                 :            : 
      58                 :          4 :         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
      59         [ -  + ]:          4 :         if (r < 0)
      60                 :          0 :                 return r;
      61                 :            : 
      62                 :          4 :         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
      63         [ -  + ]:          4 :         if (r < 0)
      64                 :          0 :                 return r;
      65                 :            : 
      66                 :          4 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :          0 : static int manager_reset_all(Manager *m) {
      70                 :            :         Link *link;
      71                 :            :         Iterator i;
      72                 :            :         int r;
      73                 :            : 
      74         [ #  # ]:          0 :         assert(m);
      75                 :            : 
      76         [ #  # ]:          0 :         HASHMAP_FOREACH(link, m->links, i) {
      77                 :          0 :                 r = link_carrier_reset(link);
      78         [ #  # ]:          0 :                 if (r < 0)
      79   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "Could not reset carrier: %m");
      80                 :            :         }
      81                 :            : 
      82                 :          0 :         return 0;
      83                 :            : }
      84                 :            : 
      85                 :          0 : static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
      86                 :          0 :         Manager *m = userdata;
      87                 :            :         int b, r;
      88                 :            : 
      89         [ #  # ]:          0 :         assert(message);
      90         [ #  # ]:          0 :         assert(m);
      91                 :            : 
      92                 :          0 :         r = sd_bus_message_read(message, "b", &b);
      93         [ #  # ]:          0 :         if (r < 0) {
      94         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
      95                 :          0 :                 return 0;
      96                 :            :         }
      97                 :            : 
      98         [ #  # ]:          0 :         if (b)
      99                 :          0 :                 return 0;
     100                 :            : 
     101         [ #  # ]:          0 :         log_debug("Coming back from suspend, resetting all connections...");
     102                 :            : 
     103                 :          0 :         (void) manager_reset_all(m);
     104                 :            : 
     105                 :          0 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :          0 : static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
     109                 :          0 :         Manager *m = userdata;
     110                 :            : 
     111         [ #  # ]:          0 :         assert(message);
     112         [ #  # ]:          0 :         assert(m);
     113                 :            : 
     114                 :            :         /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
     115         [ #  # ]:          0 :         if (m->dynamic_hostname)
     116                 :          0 :                 (void) manager_set_hostname(m, m->dynamic_hostname);
     117         [ #  # ]:          0 :         if (m->dynamic_timezone)
     118                 :          0 :                 (void) manager_set_timezone(m, m->dynamic_timezone);
     119         [ #  # ]:          0 :         if (m->links_requesting_uuid)
     120                 :          0 :                 (void) manager_request_product_uuid(m, NULL);
     121                 :            : 
     122                 :          0 :         return 0;
     123                 :            : }
     124                 :            : 
     125                 :          0 : int manager_connect_bus(Manager *m) {
     126                 :            :         int r;
     127                 :            : 
     128         [ #  # ]:          0 :         assert(m);
     129                 :            : 
     130         [ #  # ]:          0 :         if (m->bus)
     131                 :          0 :                 return 0;
     132                 :            : 
     133                 :          0 :         r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
     134         [ #  # ]:          0 :         if (r < 0)
     135         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to connect to bus: %m");
     136                 :            : 
     137                 :          0 :         r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
     138         [ #  # ]:          0 :         if (r < 0)
     139         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add manager object vtable: %m");
     140                 :            : 
     141                 :          0 :         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
     142         [ #  # ]:          0 :         if (r < 0)
     143         [ #  # ]:          0 :                return log_error_errno(r, "Failed to add link object vtable: %m");
     144                 :            : 
     145                 :          0 :         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m);
     146         [ #  # ]:          0 :         if (r < 0)
     147         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add link enumerator: %m");
     148                 :            : 
     149                 :          0 :         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
     150         [ #  # ]:          0 :         if (r < 0)
     151         [ #  # ]:          0 :                return log_error_errno(r, "Failed to add network object vtable: %m");
     152                 :            : 
     153                 :          0 :         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m);
     154         [ #  # ]:          0 :         if (r < 0)
     155         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to add network enumerator: %m");
     156                 :            : 
     157                 :          0 :         r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
     158         [ #  # ]:          0 :         if (r < 0)
     159         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request name: %m");
     160                 :            : 
     161                 :          0 :         r = sd_bus_attach_event(m->bus, m->event, 0);
     162         [ #  # ]:          0 :         if (r < 0)
     163         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
     164                 :            : 
     165                 :          0 :         r = sd_bus_match_signal_async(
     166                 :            :                         m->bus,
     167                 :            :                         NULL,
     168                 :            :                         "org.freedesktop.DBus.Local",
     169                 :            :                         NULL,
     170                 :            :                         "org.freedesktop.DBus.Local",
     171                 :            :                         "Connected",
     172                 :            :                         on_connected, NULL, m);
     173         [ #  # ]:          0 :         if (r < 0)
     174         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to request match on Connected signal: %m");
     175                 :            : 
     176                 :          0 :         r = sd_bus_match_signal_async(
     177                 :            :                         m->bus,
     178                 :            :                         NULL,
     179                 :            :                         "org.freedesktop.login1",
     180                 :            :                         "/org/freedesktop/login1",
     181                 :            :                         "org.freedesktop.login1.Manager",
     182                 :            :                         "PrepareForSleep",
     183                 :            :                         match_prepare_for_sleep, NULL, m);
     184         [ #  # ]:          0 :         if (r < 0)
     185         [ #  # ]:          0 :                 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
     186                 :            : 
     187                 :          0 :         return 0;
     188                 :            : }
     189                 :            : 
     190                 :          0 : static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
     191                 :          0 :         Manager *m = userdata;
     192                 :            :         DeviceAction action;
     193                 :          0 :         Link *link = NULL;
     194                 :            :         int r, ifindex;
     195                 :            : 
     196         [ #  # ]:          0 :         assert(m);
     197         [ #  # ]:          0 :         assert(device);
     198                 :            : 
     199                 :          0 :         r = device_get_action(device, &action);
     200         [ #  # ]:          0 :         if (r < 0) {
     201   [ #  #  #  #  :          0 :                 log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
                   #  # ]
     202                 :          0 :                 return 0;
     203                 :            :         }
     204                 :            : 
     205   [ #  #  #  # ]:          0 :         if (!IN_SET(action, DEVICE_ACTION_ADD, DEVICE_ACTION_CHANGE, DEVICE_ACTION_MOVE)) {
     206   [ #  #  #  #  :          0 :                 log_device_debug(device, "Ignoring udev %s event for device.", device_action_to_string(action));
                   #  # ]
     207                 :          0 :                 return 0;
     208                 :            :         }
     209                 :            : 
     210                 :          0 :         r = sd_device_get_ifindex(device, &ifindex);
     211         [ #  # ]:          0 :         if (r < 0) {
     212   [ #  #  #  #  :          0 :                 log_device_debug_errno(device, r, "Ignoring udev ADD event for device without ifindex or with invalid ifindex: %m");
                   #  # ]
     213                 :          0 :                 return 0;
     214                 :            :         }
     215                 :            : 
     216                 :          0 :         r = device_is_renaming(device);
     217         [ #  # ]:          0 :         if (r < 0) {
     218   [ #  #  #  #  :          0 :                 log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
                   #  # ]
     219                 :            :                                        device_action_to_string(action));
     220                 :          0 :                 return 0;
     221                 :            :         }
     222         [ #  # ]:          0 :         if (r > 0) {
     223   [ #  #  #  #  :          0 :                 log_device_debug(device, "Interface is under renaming, wait for the interface to be renamed: %m");
                   #  # ]
     224                 :          0 :                 return 0;
     225                 :            :         }
     226                 :            : 
     227                 :          0 :         r = link_get(m, ifindex, &link);
     228         [ #  # ]:          0 :         if (r < 0) {
     229         [ #  # ]:          0 :                 if (r != -ENODEV)
     230         [ #  # ]:          0 :                         log_debug_errno(r, "Failed to get link from ifindex %i, ignoring: %m", ifindex);
     231                 :          0 :                 return 0;
     232                 :            :         }
     233                 :            : 
     234                 :          0 :         (void) link_initialized(link, device);
     235                 :            : 
     236                 :          0 :         return 0;
     237                 :            : }
     238                 :            : 
     239                 :          4 : static int manager_connect_udev(Manager *m) {
     240                 :            :         int r;
     241                 :            : 
     242                 :            :         /* udev does not initialize devices inside containers,
     243                 :            :          * so we rely on them being already initialized before
     244                 :            :          * entering the container */
     245         [ -  + ]:          4 :         if (detect_container() > 0)
     246                 :          0 :                 return 0;
     247                 :            : 
     248                 :          4 :         r = sd_device_monitor_new(&m->device_monitor);
     249         [ -  + ]:          4 :         if (r < 0)
     250         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to initialize device monitor: %m");
     251                 :            : 
     252                 :          4 :         r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
     253         [ -  + ]:          4 :         if (r < 0)
     254         [ #  # ]:          0 :                 return log_error_errno(r, "Could not add device monitor filter: %m");
     255                 :            : 
     256                 :          4 :         r = sd_device_monitor_attach_event(m->device_monitor, m->event);
     257         [ -  + ]:          4 :         if (r < 0)
     258         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to attach event to device monitor: %m");
     259                 :            : 
     260                 :          4 :         r = sd_device_monitor_start(m->device_monitor, manager_udev_process_link, m);
     261         [ -  + ]:          4 :         if (r < 0)
     262         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to start device monitor: %m");
     263                 :            : 
     264                 :          4 :         return 0;
     265                 :            : }
     266                 :            : 
     267                 :          0 : int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     268                 :          0 :         Manager *m = userdata;
     269                 :          0 :         Link *link = NULL;
     270                 :            :         uint16_t type;
     271                 :          0 :         uint32_t ifindex, priority = 0;
     272                 :            :         unsigned char protocol, scope, tos, table, rt_type;
     273                 :            :         int family;
     274                 :            :         unsigned char dst_prefixlen, src_prefixlen;
     275                 :          0 :         union in_addr_union dst = IN_ADDR_NULL, gw = IN_ADDR_NULL, src = IN_ADDR_NULL, prefsrc = IN_ADDR_NULL;
     276                 :          0 :         Route *route = NULL;
     277                 :            :         int r;
     278                 :            : 
     279         [ #  # ]:          0 :         assert(rtnl);
     280         [ #  # ]:          0 :         assert(message);
     281         [ #  # ]:          0 :         assert(m);
     282                 :            : 
     283         [ #  # ]:          0 :         if (sd_netlink_message_is_error(message)) {
     284                 :          0 :                 r = sd_netlink_message_get_errno(message);
     285         [ #  # ]:          0 :                 if (r < 0)
     286         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: failed to receive route message, ignoring: %m");
     287                 :            : 
     288                 :          0 :                 return 0;
     289                 :            :         }
     290                 :            : 
     291                 :          0 :         r = sd_netlink_message_get_type(message, &type);
     292         [ #  # ]:          0 :         if (r < 0) {
     293         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
     294                 :          0 :                 return 0;
     295   [ #  #  #  # ]:          0 :         } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)) {
     296         [ #  # ]:          0 :                 log_warning("rtnl: received unexpected message type %u when processing route, ignoring.", type);
     297                 :          0 :                 return 0;
     298                 :            :         }
     299                 :            : 
     300                 :          0 :         r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
     301         [ #  # ]:          0 :         if (r == -ENODATA) {
     302         [ #  # ]:          0 :                 log_debug("rtnl: received route message without ifindex, ignoring");
     303                 :          0 :                 return 0;
     304         [ #  # ]:          0 :         } else if (r < 0) {
     305         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get ifindex from route message, ignoring: %m");
     306                 :          0 :                 return 0;
     307         [ #  # ]:          0 :         } else if (ifindex <= 0) {
     308         [ #  # ]:          0 :                 log_warning("rtnl: received route message with invalid ifindex %d, ignoring.", ifindex);
     309                 :          0 :                 return 0;
     310                 :            :         }
     311                 :            : 
     312                 :          0 :         r = link_get(m, ifindex, &link);
     313   [ #  #  #  # ]:          0 :         if (r < 0 || !link) {
     314                 :            :                 /* when enumerating we might be out of sync, but we will
     315                 :            :                  * get the route again, so just ignore it */
     316         [ #  # ]:          0 :                 if (!m->enumerating)
     317         [ #  # ]:          0 :                         log_warning("rtnl: received route message for link (%d) we do not know about, ignoring", ifindex);
     318                 :          0 :                 return 0;
     319                 :            :         }
     320                 :            : 
     321                 :          0 :         r = sd_rtnl_message_route_get_family(message, &family);
     322   [ #  #  #  #  :          0 :         if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
                   #  # ]
     323   [ #  #  #  # ]:          0 :                 log_link_warning(link, "rtnl: received route message with invalid family, ignoring");
     324                 :          0 :                 return 0;
     325                 :            :         }
     326                 :            : 
     327                 :          0 :         r = sd_rtnl_message_route_get_protocol(message, &protocol);
     328         [ #  # ]:          0 :         if (r < 0) {
     329         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: received route message with invalid route protocol: %m");
     330                 :          0 :                 return 0;
     331                 :            :         }
     332                 :            : 
     333      [ #  #  # ]:          0 :         switch (family) {
     334                 :          0 :         case AF_INET:
     335                 :          0 :                 r = sd_netlink_message_read_in_addr(message, RTA_DST, &dst.in);
     336   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     337   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
     338                 :          0 :                         return 0;
     339                 :            :                 }
     340                 :            : 
     341                 :          0 :                 r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &gw.in);
     342   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     343   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
     344                 :          0 :                         return 0;
     345                 :            :                 }
     346                 :            : 
     347                 :          0 :                 r = sd_netlink_message_read_in_addr(message, RTA_SRC, &src.in);
     348   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     349   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
     350                 :          0 :                         return 0;
     351                 :            :                 }
     352                 :            : 
     353                 :          0 :                 r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &prefsrc.in);
     354   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     355   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
     356                 :          0 :                         return 0;
     357                 :            :                 }
     358                 :            : 
     359                 :          0 :                 break;
     360                 :            : 
     361                 :          0 :         case AF_INET6:
     362                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, RTA_DST, &dst.in6);
     363   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     364   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
     365                 :          0 :                         return 0;
     366                 :            :                 }
     367                 :            : 
     368                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &gw.in6);
     369   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     370   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid gateway, ignoring: %m");
     371                 :          0 :                         return 0;
     372                 :            :                 }
     373                 :            : 
     374                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &src.in6);
     375   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     376   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid source, ignoring: %m");
     377                 :          0 :                         return 0;
     378                 :            :                 }
     379                 :            : 
     380                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &prefsrc.in6);
     381   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     382   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received route message without valid preferred source, ignoring: %m");
     383                 :          0 :                         return 0;
     384                 :            :                 }
     385                 :            : 
     386                 :          0 :                 break;
     387                 :            : 
     388                 :          0 :         default:
     389                 :          0 :                 assert_not_reached("Received route message with unsupported address family");
     390                 :            :                 return 0;
     391                 :            :         }
     392                 :            : 
     393                 :          0 :         r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen);
     394         [ #  # ]:          0 :         if (r < 0) {
     395   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid destination prefixlen, ignoring: %m");
     396                 :          0 :                 return 0;
     397                 :            :         }
     398                 :            : 
     399                 :          0 :         r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen);
     400         [ #  # ]:          0 :         if (r < 0) {
     401   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid source prefixlen, ignoring: %m");
     402                 :          0 :                 return 0;
     403                 :            :         }
     404                 :            : 
     405                 :          0 :         r = sd_rtnl_message_route_get_scope(message, &scope);
     406         [ #  # ]:          0 :         if (r < 0) {
     407   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid scope, ignoring: %m");
     408                 :          0 :                 return 0;
     409                 :            :         }
     410                 :            : 
     411                 :          0 :         r = sd_rtnl_message_route_get_tos(message, &tos);
     412         [ #  # ]:          0 :         if (r < 0) {
     413   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid tos, ignoring: %m");
     414                 :          0 :                 return 0;
     415                 :            :         }
     416                 :            : 
     417                 :          0 :         r = sd_rtnl_message_route_get_type(message, &rt_type);
     418         [ #  # ]:          0 :         if (r < 0) {
     419   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid type, ignoring: %m");
     420                 :          0 :                 return 0;
     421                 :            :         }
     422                 :            : 
     423                 :          0 :         r = sd_rtnl_message_route_get_table(message, &table);
     424         [ #  # ]:          0 :         if (r < 0) {
     425   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid table, ignoring: %m");
     426                 :          0 :                 return 0;
     427                 :            :         }
     428                 :            : 
     429                 :          0 :         r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority);
     430   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
     431   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received route message with invalid priority, ignoring: %m");
     432                 :          0 :                 return 0;
     433                 :            :         }
     434                 :            : 
     435                 :          0 :         (void) route_get(link, family, &dst, dst_prefixlen, &gw, tos, priority, table, &route);
     436                 :            : 
     437         [ #  # ]:          0 :         if (DEBUG_LOGGING) {
     438                 :          0 :                 _cleanup_free_ char *buf_dst = NULL, *buf_dst_prefixlen = NULL,
     439                 :          0 :                         *buf_src = NULL, *buf_gw = NULL, *buf_prefsrc = NULL;
     440                 :            :                 char buf_scope[ROUTE_SCOPE_STR_MAX], buf_table[ROUTE_TABLE_STR_MAX],
     441                 :            :                         buf_protocol[ROUTE_PROTOCOL_STR_MAX];
     442                 :            : 
     443         [ #  # ]:          0 :                 if (!in_addr_is_null(family, &dst)) {
     444                 :          0 :                         (void) in_addr_to_string(family, &dst, &buf_dst);
     445                 :          0 :                         (void) asprintf(&buf_dst_prefixlen, "/%u", dst_prefixlen);
     446                 :            :                 }
     447         [ #  # ]:          0 :                 if (!in_addr_is_null(family, &src))
     448                 :          0 :                         (void) in_addr_to_string(family, &src, &buf_src);
     449         [ #  # ]:          0 :                 if (!in_addr_is_null(family, &gw))
     450                 :          0 :                         (void) in_addr_to_string(family, &gw, &buf_gw);
     451         [ #  # ]:          0 :                 if (!in_addr_is_null(family, &prefsrc))
     452                 :          0 :                         (void) in_addr_to_string(family, &prefsrc, &buf_prefsrc);
     453                 :            : 
     454   [ #  #  #  #  :          0 :                 log_link_debug(link,
          #  #  #  #  #  
                #  #  # ]
     455                 :            :                                "%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
     456                 :            :                                type == RTM_DELROUTE ? "Forgetting" : route ? "Updating remembered" : "Remembering",
     457                 :            :                                strna(buf_dst), strempty(buf_dst_prefixlen),
     458                 :            :                                strna(buf_src), strna(buf_gw), strna(buf_prefsrc),
     459                 :            :                                format_route_scope(scope, buf_scope, sizeof buf_scope),
     460                 :            :                                format_route_table(table, buf_table, sizeof buf_table),
     461                 :            :                                format_route_protocol(protocol, buf_protocol, sizeof buf_protocol),
     462                 :            :                                strna(route_type_to_string(rt_type)));
     463                 :            :         }
     464                 :            : 
     465      [ #  #  # ]:          0 :         switch (type) {
     466                 :          0 :         case RTM_NEWROUTE:
     467         [ #  # ]:          0 :                 if (!route) {
     468                 :            :                         /* A route appeared that we did not request */
     469                 :          0 :                         r = route_add_foreign(link, family, &dst, dst_prefixlen, &gw, tos, priority, table, &route);
     470         [ #  # ]:          0 :                         if (r < 0) {
     471   [ #  #  #  # ]:          0 :                                 log_link_warning_errno(link, r, "Failed to remember foreign route, ignoring: %m");
     472                 :          0 :                                 return 0;
     473                 :            :                         }
     474                 :            :                 }
     475                 :            : 
     476                 :          0 :                 route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type);
     477                 :            : 
     478                 :          0 :                 break;
     479                 :            : 
     480                 :          0 :         case RTM_DELROUTE:
     481                 :          0 :                 route_free(route);
     482                 :          0 :                 break;
     483                 :            : 
     484                 :          0 :         default:
     485                 :          0 :                 assert_not_reached("Received route message with invalid RTNL message type");
     486                 :            :         }
     487                 :            : 
     488                 :          0 :         return 1;
     489                 :            : }
     490                 :            : 
     491                 :          0 : static int manager_rtnl_process_neighbor_lladdr(sd_netlink_message *message, union lladdr_union *lladdr, size_t *size, char **str) {
     492                 :            :         int r;
     493                 :            : 
     494         [ #  # ]:          0 :         assert(message);
     495         [ #  # ]:          0 :         assert(lladdr);
     496         [ #  # ]:          0 :         assert(size);
     497         [ #  # ]:          0 :         assert(str);
     498                 :            : 
     499                 :          0 :         *str = NULL;
     500                 :            : 
     501                 :          0 :         r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in6), &lladdr->ip.in6);
     502         [ #  # ]:          0 :         if (r >= 0) {
     503                 :          0 :                 *size = sizeof(lladdr->ip.in6);
     504         [ #  # ]:          0 :                 if (in_addr_to_string(AF_INET6, &lladdr->ip, str) < 0)
     505         [ #  # ]:          0 :                         log_warning_errno(r, "Could not print lower address: %m");
     506                 :          0 :                 return r;
     507                 :            :         }
     508                 :            : 
     509                 :          0 :         r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->mac), &lladdr->mac);
     510         [ #  # ]:          0 :         if (r >= 0) {
     511                 :          0 :                 *size = sizeof(lladdr->mac);
     512                 :          0 :                 *str = new(char, ETHER_ADDR_TO_STRING_MAX);
     513         [ #  # ]:          0 :                 if (!*str) {
     514                 :          0 :                         log_oom();
     515                 :          0 :                         return r;
     516                 :            :                 }
     517                 :          0 :                 ether_addr_to_string(&lladdr->mac, *str);
     518                 :          0 :                 return r;
     519                 :            :         }
     520                 :            : 
     521                 :          0 :         r = sd_netlink_message_read(message, NDA_LLADDR, sizeof(lladdr->ip.in), &lladdr->ip.in);
     522         [ #  # ]:          0 :         if (r >= 0) {
     523                 :          0 :                 *size = sizeof(lladdr->ip.in);
     524         [ #  # ]:          0 :                 if (in_addr_to_string(AF_INET, &lladdr->ip, str) < 0)
     525         [ #  # ]:          0 :                         log_warning_errno(r, "Could not print lower address: %m");
     526                 :          0 :                 return r;
     527                 :            :         }
     528                 :            : 
     529                 :          0 :         return r;
     530                 :            : }
     531                 :            : 
     532                 :          0 : int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     533                 :          0 :         Manager *m = userdata;
     534                 :          0 :         Link *link = NULL;
     535                 :          0 :         Neighbor *neighbor = NULL;
     536                 :            :         int ifindex, family, r;
     537                 :            :         uint16_t type, state;
     538                 :          0 :         union in_addr_union in_addr = IN_ADDR_NULL;
     539                 :          0 :         _cleanup_free_ char *addr_str = NULL;
     540                 :            :         union lladdr_union lladdr;
     541                 :          0 :         size_t lladdr_size = 0;
     542                 :          0 :         _cleanup_free_ char *lladdr_str = NULL;
     543                 :            : 
     544         [ #  # ]:          0 :         assert(rtnl);
     545         [ #  # ]:          0 :         assert(message);
     546         [ #  # ]:          0 :         assert(m);
     547                 :            : 
     548         [ #  # ]:          0 :         if (sd_netlink_message_is_error(message)) {
     549                 :          0 :                 r = sd_netlink_message_get_errno(message);
     550         [ #  # ]:          0 :                 if (r < 0)
     551         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: failed to receive neighbor message, ignoring: %m");
     552                 :            : 
     553                 :          0 :                 return 0;
     554                 :            :         }
     555                 :            : 
     556                 :          0 :         r = sd_netlink_message_get_type(message, &type);
     557         [ #  # ]:          0 :         if (r < 0) {
     558         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
     559                 :          0 :                 return 0;
     560   [ #  #  #  # ]:          0 :         } else if (!IN_SET(type, RTM_NEWNEIGH, RTM_DELNEIGH)) {
     561         [ #  # ]:          0 :                 log_warning("rtnl: received unexpected message type %u when processing neighbor, ignoring.", type);
     562                 :          0 :                 return 0;
     563                 :            :         }
     564                 :            : 
     565                 :          0 :         r = sd_rtnl_message_neigh_get_state(message, &state);
     566         [ #  # ]:          0 :         if (r < 0) {
     567   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid state, ignoring: %m");
     568                 :          0 :                 return 0;
     569         [ #  # ]:          0 :         } else if (!FLAGS_SET(state, NUD_PERMANENT)) {
     570         [ #  # ]:          0 :                 log_debug("rtnl: received non-static neighbor, ignoring.");
     571                 :          0 :                 return 0;
     572                 :            :         }
     573                 :            : 
     574                 :          0 :         r = sd_rtnl_message_neigh_get_ifindex(message, &ifindex);
     575         [ #  # ]:          0 :         if (r < 0) {
     576         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
     577                 :          0 :                 return 0;
     578         [ #  # ]:          0 :         } else if (ifindex <= 0) {
     579         [ #  # ]:          0 :                 log_warning("rtnl: received neighbor message with invalid ifindex %d, ignoring.", ifindex);
     580                 :          0 :                 return 0;
     581                 :            :         }
     582                 :            : 
     583                 :          0 :         r = link_get(m, ifindex, &link);
     584   [ #  #  #  # ]:          0 :         if (r < 0 || !link) {
     585                 :            :                 /* when enumerating we might be out of sync, but we will get the neighbor again, so just
     586                 :            :                  * ignore it */
     587         [ #  # ]:          0 :                 if (!m->enumerating)
     588         [ #  # ]:          0 :                         log_warning("rtnl: received neighbor for link '%d' we don't know about, ignoring.", ifindex);
     589                 :          0 :                 return 0;
     590                 :            :         }
     591                 :            : 
     592                 :          0 :         r = sd_rtnl_message_neigh_get_family(message, &family);
     593   [ #  #  #  #  :          0 :         if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
                   #  # ]
     594   [ #  #  #  # ]:          0 :                 log_link_warning(link, "rtnl: received neighbor message with invalid family, ignoring.");
     595                 :          0 :                 return 0;
     596                 :            :         }
     597                 :            : 
     598      [ #  #  # ]:          0 :         switch (family) {
     599                 :          0 :         case AF_INET:
     600                 :          0 :                 r = sd_netlink_message_read_in_addr(message, NDA_DST, &in_addr.in);
     601         [ #  # ]:          0 :                 if (r < 0) {
     602   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m");
     603                 :          0 :                         return 0;
     604                 :            :                 }
     605                 :            : 
     606                 :          0 :                 break;
     607                 :            : 
     608                 :          0 :         case AF_INET6:
     609                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, NDA_DST, &in_addr.in6);
     610         [ #  # ]:          0 :                 if (r < 0) {
     611   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m");
     612                 :          0 :                         return 0;
     613                 :            :                 }
     614                 :            : 
     615                 :          0 :                 break;
     616                 :            : 
     617                 :          0 :         default:
     618                 :          0 :                 assert_not_reached("Received unsupported address family");
     619                 :            :         }
     620                 :            : 
     621         [ #  # ]:          0 :         if (in_addr_to_string(family, &in_addr, &addr_str) < 0)
     622   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "Could not print address: %m");
     623                 :            : 
     624                 :          0 :         r = manager_rtnl_process_neighbor_lladdr(message, &lladdr, &lladdr_size, &lladdr_str);
     625         [ #  # ]:          0 :         if (r < 0) {
     626   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received neighbor message with invalid lladdr, ignoring: %m");
     627                 :          0 :                 return 0;
     628                 :            :         }
     629                 :            : 
     630                 :          0 :         (void) neighbor_get(link, family, &in_addr, &lladdr, lladdr_size, &neighbor);
     631                 :            : 
     632      [ #  #  # ]:          0 :         switch (type) {
     633                 :          0 :         case RTM_NEWNEIGH:
     634         [ #  # ]:          0 :                 if (neighbor)
     635   [ #  #  #  # ]:          0 :                         log_link_debug(link, "Remembering neighbor: %s->%s",
     636                 :            :                                        strnull(addr_str), strnull(lladdr_str));
     637                 :            :                 else {
     638                 :            :                         /* A neighbor appeared that we did not request */
     639                 :          0 :                         r = neighbor_add_foreign(link, family, &in_addr, &lladdr, lladdr_size, &neighbor);
     640         [ #  # ]:          0 :                         if (r < 0) {
     641   [ #  #  #  # ]:          0 :                                 log_link_warning_errno(link, r, "Failed to remember foreign neighbor %s->%s, ignoring: %m",
     642                 :            :                                                        strnull(addr_str), strnull(lladdr_str));
     643                 :          0 :                                 return 0;
     644                 :            :                         } else
     645   [ #  #  #  # ]:          0 :                                 log_link_debug(link, "Remembering foreign neighbor: %s->%s",
     646                 :            :                                                strnull(addr_str), strnull(lladdr_str));
     647                 :            :                 }
     648                 :            : 
     649                 :          0 :                 break;
     650                 :            : 
     651                 :          0 :         case RTM_DELNEIGH:
     652         [ #  # ]:          0 :                 if (neighbor) {
     653   [ #  #  #  # ]:          0 :                         log_link_debug(link, "Forgetting neighbor: %s->%s",
     654                 :            :                                        strnull(addr_str), strnull(lladdr_str));
     655                 :          0 :                         (void) neighbor_free(neighbor);
     656                 :            :                 } else
     657   [ #  #  #  # ]:          0 :                         log_link_info(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.",
     658                 :            :                                       strnull(addr_str), strnull(lladdr_str));
     659                 :            : 
     660                 :          0 :                 break;
     661                 :            : 
     662                 :          0 :         default:
     663                 :          0 :                 assert_not_reached("Received invalid RTNL message type");
     664                 :            :         }
     665                 :            : 
     666                 :          0 :         return 1;
     667                 :            : }
     668                 :            : 
     669                 :          0 : int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     670                 :          0 :         _cleanup_free_ char *buf = NULL;
     671                 :          0 :         Manager *m = userdata;
     672                 :          0 :         Link *link = NULL;
     673                 :            :         uint16_t type;
     674                 :            :         unsigned char flags, prefixlen, scope;
     675                 :          0 :         union in_addr_union in_addr = IN_ADDR_NULL;
     676                 :            :         struct ifa_cacheinfo cinfo;
     677                 :          0 :         Address *address = NULL;
     678                 :            :         char valid_buf[FORMAT_TIMESPAN_MAX];
     679                 :          0 :         const char *valid_str = NULL;
     680                 :            :         int ifindex, family, r;
     681                 :            : 
     682         [ #  # ]:          0 :         assert(rtnl);
     683         [ #  # ]:          0 :         assert(message);
     684         [ #  # ]:          0 :         assert(m);
     685                 :            : 
     686         [ #  # ]:          0 :         if (sd_netlink_message_is_error(message)) {
     687                 :          0 :                 r = sd_netlink_message_get_errno(message);
     688         [ #  # ]:          0 :                 if (r < 0)
     689         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: failed to receive address message, ignoring: %m");
     690                 :            : 
     691                 :          0 :                 return 0;
     692                 :            :         }
     693                 :            : 
     694                 :          0 :         r = sd_netlink_message_get_type(message, &type);
     695         [ #  # ]:          0 :         if (r < 0) {
     696         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
     697                 :          0 :                 return 0;
     698   [ #  #  #  # ]:          0 :         } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
     699         [ #  # ]:          0 :                 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type);
     700                 :          0 :                 return 0;
     701                 :            :         }
     702                 :            : 
     703                 :          0 :         r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
     704         [ #  # ]:          0 :         if (r < 0) {
     705         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
     706                 :          0 :                 return 0;
     707         [ #  # ]:          0 :         } else if (ifindex <= 0) {
     708         [ #  # ]:          0 :                 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex);
     709                 :          0 :                 return 0;
     710                 :            :         }
     711                 :            : 
     712                 :          0 :         r = link_get(m, ifindex, &link);
     713   [ #  #  #  # ]:          0 :         if (r < 0 || !link) {
     714                 :            :                 /* when enumerating we might be out of sync, but we will get the address again, so just
     715                 :            :                  * ignore it */
     716         [ #  # ]:          0 :                 if (!m->enumerating)
     717         [ #  # ]:          0 :                         log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex);
     718                 :          0 :                 return 0;
     719                 :            :         }
     720                 :            : 
     721                 :          0 :         r = sd_rtnl_message_addr_get_family(message, &family);
     722   [ #  #  #  #  :          0 :         if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)) {
                   #  # ]
     723   [ #  #  #  # ]:          0 :                 log_link_warning(link, "rtnl: received address message with invalid family, ignoring.");
     724                 :          0 :                 return 0;
     725                 :            :         }
     726                 :            : 
     727                 :          0 :         r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
     728         [ #  # ]:          0 :         if (r < 0) {
     729   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received address message with invalid prefixlen, ignoring: %m");
     730                 :          0 :                 return 0;
     731                 :            :         }
     732                 :            : 
     733                 :          0 :         r = sd_rtnl_message_addr_get_scope(message, &scope);
     734         [ #  # ]:          0 :         if (r < 0) {
     735   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received address message with invalid scope, ignoring: %m");
     736                 :          0 :                 return 0;
     737                 :            :         }
     738                 :            : 
     739                 :          0 :         r = sd_rtnl_message_addr_get_flags(message, &flags);
     740         [ #  # ]:          0 :         if (r < 0) {
     741   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: received address message with invalid flags, ignoring: %m");
     742                 :          0 :                 return 0;
     743                 :            :         }
     744                 :            : 
     745      [ #  #  # ]:          0 :         switch (family) {
     746                 :          0 :         case AF_INET:
     747                 :          0 :                 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
     748         [ #  # ]:          0 :                 if (r < 0) {
     749   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
     750                 :          0 :                         return 0;
     751                 :            :                 }
     752                 :            : 
     753                 :          0 :                 break;
     754                 :            : 
     755                 :          0 :         case AF_INET6:
     756                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
     757         [ #  # ]:          0 :                 if (r < 0) {
     758   [ #  #  #  # ]:          0 :                         log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
     759                 :          0 :                         return 0;
     760                 :            :                 }
     761                 :            : 
     762                 :          0 :                 break;
     763                 :            : 
     764                 :          0 :         default:
     765                 :          0 :                 assert_not_reached("Received unsupported address family");
     766                 :            :         }
     767                 :            : 
     768                 :          0 :         r = in_addr_to_string(family, &in_addr, &buf);
     769         [ #  # ]:          0 :         if (r < 0)
     770   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "Could not print address: %m");
     771                 :            : 
     772                 :          0 :         r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
     773   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
     774   [ #  #  #  # ]:          0 :                 log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m");
     775                 :          0 :                 return 0;
     776   [ #  #  #  # ]:          0 :         } else if (r >= 0 && cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
     777                 :          0 :                 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
     778                 :          0 :                                             cinfo.ifa_valid * USEC_PER_SEC,
     779                 :            :                                             USEC_PER_SEC);
     780                 :            : 
     781                 :          0 :         (void) address_get(link, family, &in_addr, prefixlen, &address);
     782                 :            : 
     783      [ #  #  # ]:          0 :         switch (type) {
     784                 :          0 :         case RTM_NEWADDR:
     785         [ #  # ]:          0 :                 if (address)
     786   [ #  #  #  #  :          0 :                         log_link_debug(link, "Remembering updated address: %s/%u (valid %s%s)",
             #  #  #  # ]
     787                 :            :                                        strnull(buf), prefixlen,
     788                 :            :                                        valid_str ? "for " : "forever", strempty(valid_str));
     789                 :            :                 else {
     790                 :            :                         /* An address appeared that we did not request */
     791                 :          0 :                         r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
     792         [ #  # ]:          0 :                         if (r < 0) {
     793   [ #  #  #  # ]:          0 :                                 log_link_warning_errno(link, r, "Failed to remember foreign address %s/%u, ignoring: %m",
     794                 :            :                                                        strnull(buf), prefixlen);
     795                 :          0 :                                 return 0;
     796                 :            :                         } else
     797   [ #  #  #  #  :          0 :                                 log_link_debug(link, "Remembering foreign address: %s/%u (valid %s%s)",
             #  #  #  # ]
     798                 :            :                                                strnull(buf), prefixlen,
     799                 :            :                                                valid_str ? "for " : "forever", strempty(valid_str));
     800                 :            :                 }
     801                 :            : 
     802                 :            :                 /* address_update() logs internally, so we don't need to. */
     803                 :          0 :                 (void) address_update(address, flags, scope, &cinfo);
     804                 :            : 
     805                 :          0 :                 break;
     806                 :            : 
     807                 :          0 :         case RTM_DELADDR:
     808         [ #  # ]:          0 :                 if (address) {
     809   [ #  #  #  #  :          0 :                         log_link_debug(link, "Forgetting address: %s/%u (valid %s%s)",
             #  #  #  # ]
     810                 :            :                                        strnull(buf), prefixlen,
     811                 :            :                                        valid_str ? "for " : "forever", strempty(valid_str));
     812                 :          0 :                         (void) address_drop(address);
     813                 :            :                 } else
     814   [ #  #  #  #  :          0 :                         log_link_info(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
             #  #  #  # ]
     815                 :            :                                       strnull(buf), prefixlen,
     816                 :            :                                       valid_str ? "for " : "forever", strempty(valid_str));
     817                 :            : 
     818                 :          0 :                 break;
     819                 :            : 
     820                 :          0 :         default:
     821                 :          0 :                 assert_not_reached("Received invalid RTNL message type");
     822                 :            :         }
     823                 :            : 
     824                 :          0 :         return 1;
     825                 :            : }
     826                 :            : 
     827                 :         28 : static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     828                 :         28 :         Manager *m = userdata;
     829                 :         28 :         Link *link = NULL;
     830                 :         28 :         NetDev *netdev = NULL;
     831                 :            :         uint16_t type;
     832                 :            :         const char *name;
     833                 :            :         int r, ifindex;
     834                 :            : 
     835         [ -  + ]:         28 :         assert(rtnl);
     836         [ -  + ]:         28 :         assert(message);
     837         [ -  + ]:         28 :         assert(m);
     838                 :            : 
     839         [ -  + ]:         28 :         if (sd_netlink_message_is_error(message)) {
     840                 :          0 :                 r = sd_netlink_message_get_errno(message);
     841         [ #  # ]:          0 :                 if (r < 0)
     842         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: Could not receive link message, ignoring: %m");
     843                 :            : 
     844                 :          0 :                 return 0;
     845                 :            :         }
     846                 :            : 
     847                 :         28 :         r = sd_netlink_message_get_type(message, &type);
     848         [ -  + ]:         28 :         if (r < 0) {
     849         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
     850                 :          0 :                 return 0;
     851   [ +  -  -  + ]:         28 :         } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
     852         [ #  # ]:          0 :                 log_warning("rtnl: Received unexpected message type %u when processing link, ignoring.", type);
     853                 :          0 :                 return 0;
     854                 :            :         }
     855                 :            : 
     856                 :         28 :         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
     857         [ -  + ]:         28 :         if (r < 0) {
     858         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
     859                 :          0 :                 return 0;
     860         [ -  + ]:         28 :         } else if (ifindex <= 0) {
     861         [ #  # ]:          0 :                 log_warning("rtnl: received link message with invalid ifindex %d, ignoring.", ifindex);
     862                 :          0 :                 return 0;
     863                 :            :         }
     864                 :            : 
     865                 :         28 :         r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
     866         [ -  + ]:         28 :         if (r < 0) {
     867         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
     868                 :          0 :                 return 0;
     869                 :            :         }
     870                 :            : 
     871                 :         28 :         (void) link_get(m, ifindex, &link);
     872                 :         28 :         (void) netdev_get(m, name, &netdev);
     873                 :            : 
     874      [ +  -  - ]:         28 :         switch (type) {
     875                 :         28 :         case RTM_NEWLINK:
     876         [ +  - ]:         28 :                 if (!link) {
     877                 :            :                         /* link is new, so add it */
     878                 :         28 :                         r = link_add(m, message, &link);
     879         [ -  + ]:         28 :                         if (r < 0) {
     880         [ #  # ]:          0 :                                 log_warning_errno(r, "Could not process new link message, ignoring: %m");
     881                 :          0 :                                 return 0;
     882                 :            :                         }
     883                 :            :                 }
     884                 :            : 
     885         [ -  + ]:         28 :                 if (netdev) {
     886                 :            :                         /* netdev exists, so make sure the ifindex matches */
     887                 :          0 :                         r = netdev_set_ifindex(netdev, message);
     888         [ #  # ]:          0 :                         if (r < 0) {
     889         [ #  # ]:          0 :                                 log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m");
     890                 :          0 :                                 return 0;
     891                 :            :                         }
     892                 :            :                 }
     893                 :            : 
     894                 :         28 :                 r = link_update(link, message);
     895         [ -  + ]:         28 :                 if (r < 0) {
     896         [ #  # ]:          0 :                         log_warning_errno(r, "Could not process link message, ignoring: %m");
     897                 :          0 :                         return 0;
     898                 :            :                 }
     899                 :            : 
     900                 :         28 :                 break;
     901                 :            : 
     902                 :          0 :         case RTM_DELLINK:
     903                 :          0 :                 link_drop(link);
     904                 :          0 :                 netdev_drop(netdev);
     905                 :            : 
     906                 :          0 :                 break;
     907                 :            : 
     908                 :          0 :         default:
     909                 :          0 :                 assert_not_reached("Received link message with invalid RTNL message type.");
     910                 :            :         }
     911                 :            : 
     912                 :         28 :         return 1;
     913                 :            : }
     914                 :            : 
     915                 :          0 : int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     916                 :          0 :         _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
     917                 :          0 :         RoutingPolicyRule *rule = NULL;
     918                 :          0 :         const char *iif = NULL, *oif = NULL;
     919                 :          0 :         Manager *m = userdata;
     920                 :            :         unsigned flags;
     921                 :            :         uint16_t type;
     922                 :            :         int r;
     923                 :            : 
     924         [ #  # ]:          0 :         assert(rtnl);
     925         [ #  # ]:          0 :         assert(message);
     926         [ #  # ]:          0 :         assert(m);
     927                 :            : 
     928         [ #  # ]:          0 :         if (sd_netlink_message_is_error(message)) {
     929                 :          0 :                 r = sd_netlink_message_get_errno(message);
     930         [ #  # ]:          0 :                 if (r < 0)
     931         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: failed to receive rule message, ignoring: %m");
     932                 :            : 
     933                 :          0 :                 return 0;
     934                 :            :         }
     935                 :            : 
     936                 :          0 :         r = sd_netlink_message_get_type(message, &type);
     937         [ #  # ]:          0 :         if (r < 0) {
     938         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
     939                 :          0 :                 return 0;
     940   [ #  #  #  # ]:          0 :         } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)) {
     941         [ #  # ]:          0 :                 log_warning("rtnl: received unexpected message type %u when processing rule, ignoring.", type);
     942                 :          0 :                 return 0;
     943                 :            :         }
     944                 :            : 
     945                 :          0 :         r = routing_policy_rule_new(&tmp);
     946         [ #  # ]:          0 :         if (r < 0) {
     947                 :          0 :                 log_oom();
     948                 :          0 :                 return 0;
     949                 :            :         }
     950                 :            : 
     951                 :          0 :         r = sd_rtnl_message_get_family(message, &tmp->family);
     952         [ #  # ]:          0 :         if (r < 0) {
     953         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m");
     954                 :          0 :                 return 0;
     955   [ #  #  #  # ]:          0 :         } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
     956         [ #  # ]:          0 :                 log_debug("rtnl: received rule message with invalid family %d, ignoring.", tmp->family);
     957                 :          0 :                 return 0;
     958                 :            :         }
     959                 :            : 
     960      [ #  #  # ]:          0 :         switch (tmp->family) {
     961                 :          0 :         case AF_INET:
     962                 :          0 :                 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &tmp->from.in);
     963   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     964         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
     965                 :          0 :                         return 0;
     966         [ #  # ]:          0 :                 } else if (r >= 0) {
     967                 :          0 :                         r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
     968         [ #  # ]:          0 :                         if (r < 0) {
     969         [ #  # ]:          0 :                                 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
     970                 :          0 :                                 return 0;
     971                 :            :                         }
     972                 :            :                 }
     973                 :            : 
     974                 :          0 :                 r = sd_netlink_message_read_in_addr(message, FRA_DST, &tmp->to.in);
     975   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     976         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
     977                 :          0 :                         return 0;
     978         [ #  # ]:          0 :                 } else if (r >= 0) {
     979                 :          0 :                         r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
     980         [ #  # ]:          0 :                         if (r < 0) {
     981         [ #  # ]:          0 :                                 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
     982                 :          0 :                                 return 0;
     983                 :            :                         }
     984                 :            :                 }
     985                 :            : 
     986                 :          0 :                 break;
     987                 :            : 
     988                 :          0 :         case AF_INET6:
     989                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &tmp->from.in6);
     990   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
     991         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
     992                 :          0 :                         return 0;
     993         [ #  # ]:          0 :                 } else if (r >= 0) {
     994                 :          0 :                         r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &tmp->from_prefixlen);
     995         [ #  # ]:          0 :                         if (r < 0) {
     996         [ #  # ]:          0 :                                 log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
     997                 :          0 :                                 return 0;
     998                 :            :                         }
     999                 :            :                 }
    1000                 :            : 
    1001                 :          0 :                 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &tmp->to.in6);
    1002   [ #  #  #  # ]:          0 :                 if (r < 0 && r != -ENODATA) {
    1003         [ #  # ]:          0 :                         log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
    1004                 :          0 :                         return 0;
    1005         [ #  # ]:          0 :                 } else if (r >= 0) {
    1006                 :          0 :                         r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &tmp->to_prefixlen);
    1007         [ #  # ]:          0 :                         if (r < 0) {
    1008         [ #  # ]:          0 :                                 log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
    1009                 :          0 :                                 return 0;
    1010                 :            :                         }
    1011                 :            :                 }
    1012                 :            : 
    1013                 :          0 :                 break;
    1014                 :            : 
    1015                 :          0 :         default:
    1016                 :          0 :                 assert_not_reached("Received rule message with unsupported address family");
    1017                 :            :         }
    1018                 :            : 
    1019   [ #  #  #  # ]:          0 :         if (tmp->from_prefixlen == 0 && tmp->to_prefixlen == 0)
    1020                 :          0 :                 return 0;
    1021                 :            : 
    1022                 :          0 :         r = sd_rtnl_message_routing_policy_rule_get_flags(message, &flags);
    1023         [ #  # ]:          0 :         if (r < 0) {
    1024         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: received rule message without valid flag, ignoring: %m");
    1025                 :          0 :                 return 0;
    1026                 :            :         }
    1027                 :          0 :         tmp->invert_rule = flags & FIB_RULE_INVERT;
    1028                 :            : 
    1029                 :          0 :         r = sd_netlink_message_read_u32(message, FRA_FWMARK, &tmp->fwmark);
    1030   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1031         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m");
    1032                 :          0 :                 return 0;
    1033                 :            :         }
    1034                 :            : 
    1035                 :          0 :         r = sd_netlink_message_read_u32(message, FRA_FWMASK, &tmp->fwmask);
    1036   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1037         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_FWMASK attribute, ignoring: %m");
    1038                 :          0 :                 return 0;
    1039                 :            :         }
    1040                 :            : 
    1041                 :          0 :         r = sd_netlink_message_read_u32(message, FRA_PRIORITY, &tmp->priority);
    1042   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1043         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_PRIORITY attribute, ignoring: %m");
    1044                 :          0 :                 return 0;
    1045                 :            :         }
    1046                 :            : 
    1047                 :          0 :         r = sd_netlink_message_read_u32(message, FRA_TABLE, &tmp->table);
    1048   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1049         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m");
    1050                 :          0 :                 return 0;
    1051                 :            :         }
    1052                 :            : 
    1053                 :          0 :         r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tmp->tos);
    1054   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1055         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m");
    1056                 :          0 :                 return 0;
    1057                 :            :         }
    1058                 :            : 
    1059                 :          0 :         r = sd_netlink_message_read_string(message, FRA_IIFNAME, &iif);
    1060   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1061         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m");
    1062                 :          0 :                 return 0;
    1063                 :            :         }
    1064                 :          0 :         r = free_and_strdup(&tmp->iif, iif);
    1065         [ #  # ]:          0 :         if (r < 0)
    1066                 :          0 :                 return log_oom();
    1067                 :            : 
    1068                 :          0 :         r = sd_netlink_message_read_string(message, FRA_OIFNAME, &oif);
    1069   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1070         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m");
    1071                 :          0 :                 return 0;
    1072                 :            :         }
    1073                 :          0 :         r = free_and_strdup(&tmp->oif, oif);
    1074         [ #  # ]:          0 :         if (r < 0)
    1075                 :          0 :                 return log_oom();
    1076                 :            : 
    1077                 :          0 :         r = sd_netlink_message_read_u8(message, FRA_IP_PROTO, &tmp->protocol);
    1078   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1079         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_IP_PROTO attribute, ignoring: %m");
    1080                 :          0 :                 return 0;
    1081                 :            :         }
    1082                 :            : 
    1083                 :          0 :         r = sd_netlink_message_read(message, FRA_SPORT_RANGE, sizeof(tmp->sport), &tmp->sport);
    1084   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1085         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_SPORT_RANGE attribute, ignoring: %m");
    1086                 :          0 :                 return 0;
    1087                 :            :         }
    1088                 :            : 
    1089                 :          0 :         r = sd_netlink_message_read(message, FRA_DPORT_RANGE, sizeof(tmp->dport), &tmp->dport);
    1090   [ #  #  #  # ]:          0 :         if (r < 0 && r != -ENODATA) {
    1091         [ #  # ]:          0 :                 log_warning_errno(r, "rtnl: could not get FRA_DPORT_RANGE attribute, ignoring: %m");
    1092                 :          0 :                 return 0;
    1093                 :            :         }
    1094                 :            : 
    1095                 :          0 :         (void) routing_policy_rule_get(m, tmp, &rule);
    1096                 :            : 
    1097      [ #  #  # ]:          0 :         switch (type) {
    1098                 :          0 :         case RTM_NEWRULE:
    1099         [ #  # ]:          0 :                 if (!rule) {
    1100                 :          0 :                         r = routing_policy_rule_add_foreign(m, tmp, &rule);
    1101         [ #  # ]:          0 :                         if (r < 0) {
    1102         [ #  # ]:          0 :                                 log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
    1103                 :          0 :                                 return 0;
    1104                 :            :                         }
    1105                 :            :                 }
    1106                 :          0 :                 break;
    1107                 :          0 :         case RTM_DELRULE:
    1108                 :          0 :                 routing_policy_rule_free(rule);
    1109                 :            : 
    1110                 :          0 :                 break;
    1111                 :            : 
    1112                 :          0 :         default:
    1113                 :          0 :                 assert_not_reached("Received invalid RTNL message type");
    1114                 :            :         }
    1115                 :            : 
    1116                 :          0 :         return 1;
    1117                 :            : }
    1118                 :            : 
    1119                 :          4 : static int systemd_netlink_fd(void) {
    1120                 :          4 :         int n, fd, rtnl_fd = -EINVAL;
    1121                 :            : 
    1122                 :          4 :         n = sd_listen_fds(true);
    1123         [ +  - ]:          4 :         if (n <= 0)
    1124                 :          4 :                 return -EINVAL;
    1125                 :            : 
    1126         [ #  # ]:          0 :         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
    1127         [ #  # ]:          0 :                 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
    1128         [ #  # ]:          0 :                         if (rtnl_fd >= 0)
    1129                 :          0 :                                 return -EINVAL;
    1130                 :            : 
    1131                 :          0 :                         rtnl_fd = fd;
    1132                 :            :                 }
    1133                 :            :         }
    1134                 :            : 
    1135                 :          0 :         return rtnl_fd;
    1136                 :            : }
    1137                 :            : 
    1138                 :          4 : static int manager_connect_genl(Manager *m) {
    1139                 :            :         int r;
    1140                 :            : 
    1141         [ -  + ]:          4 :         assert(m);
    1142                 :            : 
    1143                 :          4 :         r = sd_genl_socket_open(&m->genl);
    1144         [ -  + ]:          4 :         if (r < 0)
    1145                 :          0 :                 return r;
    1146                 :            : 
    1147                 :          4 :         r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE);
    1148         [ -  + ]:          4 :         if (r < 0)
    1149                 :          0 :                 return r;
    1150                 :            : 
    1151                 :          4 :         r = sd_netlink_attach_event(m->genl, m->event, 0);
    1152         [ -  + ]:          4 :         if (r < 0)
    1153                 :          0 :                 return r;
    1154                 :            : 
    1155                 :          4 :         return 0;
    1156                 :            : }
    1157                 :            : 
    1158                 :          4 : static int manager_connect_rtnl(Manager *m) {
    1159                 :            :         int fd, r;
    1160                 :            : 
    1161         [ -  + ]:          4 :         assert(m);
    1162                 :            : 
    1163                 :          4 :         fd = systemd_netlink_fd();
    1164         [ +  - ]:          4 :         if (fd < 0)
    1165                 :          4 :                 r = sd_netlink_open(&m->rtnl);
    1166                 :            :         else
    1167                 :          0 :                 r = sd_netlink_open_fd(&m->rtnl, fd);
    1168         [ -  + ]:          4 :         if (r < 0)
    1169                 :          0 :                 return r;
    1170                 :            : 
    1171                 :          4 :         r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
    1172         [ -  + ]:          4 :         if (r < 0)
    1173                 :          0 :                 return r;
    1174                 :            : 
    1175                 :          4 :         r = sd_netlink_attach_event(m->rtnl, m->event, 0);
    1176         [ -  + ]:          4 :         if (r < 0)
    1177                 :          0 :                 return r;
    1178                 :            : 
    1179                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
    1180         [ -  + ]:          4 :         if (r < 0)
    1181                 :          0 :                 return r;
    1182                 :            : 
    1183                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
    1184         [ -  + ]:          4 :         if (r < 0)
    1185                 :          0 :                 return r;
    1186                 :            : 
    1187                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
    1188         [ -  + ]:          4 :         if (r < 0)
    1189                 :          0 :                 return r;
    1190                 :            : 
    1191                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
    1192         [ -  + ]:          4 :         if (r < 0)
    1193                 :          0 :                 return r;
    1194                 :            : 
    1195                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
    1196         [ -  + ]:          4 :         if (r < 0)
    1197                 :          0 :                 return r;
    1198                 :            : 
    1199                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
    1200         [ -  + ]:          4 :         if (r < 0)
    1201                 :          0 :                 return r;
    1202                 :            : 
    1203                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
    1204         [ -  + ]:          4 :         if (r < 0)
    1205                 :          0 :                 return r;
    1206                 :            : 
    1207                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
    1208         [ -  + ]:          4 :         if (r < 0)
    1209                 :          0 :                 return r;
    1210                 :            : 
    1211                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
    1212         [ -  + ]:          4 :         if (r < 0)
    1213                 :          0 :                 return r;
    1214                 :            : 
    1215                 :          4 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
    1216         [ -  + ]:          4 :         if (r < 0)
    1217                 :          0 :                 return r;
    1218                 :            : 
    1219                 :          4 :         return 0;
    1220                 :            : }
    1221                 :            : 
    1222                 :          0 : static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
    1223                 :            :         char *p;
    1224                 :            :         int r;
    1225                 :            : 
    1226         [ #  # ]:          0 :         assert(s);
    1227         [ #  # ]:          0 :         assert(address);
    1228                 :            : 
    1229                 :          0 :         r = in_addr_to_string(address->family, &address->address, &p);
    1230         [ #  # ]:          0 :         if (r < 0)
    1231                 :          0 :                 return r;
    1232                 :            : 
    1233                 :          0 :         r = ordered_set_consume(s, p);
    1234         [ #  # ]:          0 :         if (r == -EEXIST)
    1235                 :          0 :                 return 0;
    1236                 :            : 
    1237                 :          0 :         return r;
    1238                 :            : }
    1239                 :            : 
    1240                 :          0 : static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
    1241                 :          0 :         int r, c = 0;
    1242                 :            :         unsigned i;
    1243                 :            : 
    1244         [ #  # ]:          0 :         assert(s);
    1245   [ #  #  #  # ]:          0 :         assert(addresses || n == 0);
    1246                 :            : 
    1247         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
    1248                 :          0 :                 r = ordered_set_put_in_addr_data(s, addresses+i);
    1249         [ #  # ]:          0 :                 if (r < 0)
    1250                 :          0 :                         return r;
    1251                 :            : 
    1252                 :          0 :                 c += r;
    1253                 :            :         }
    1254                 :            : 
    1255                 :          0 :         return c;
    1256                 :            : }
    1257                 :            : 
    1258                 :          0 : static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
    1259                 :            :         char *p;
    1260                 :            :         int r;
    1261                 :            : 
    1262         [ #  # ]:          0 :         assert(s);
    1263         [ #  # ]:          0 :         assert(address);
    1264                 :            : 
    1265                 :          0 :         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
    1266         [ #  # ]:          0 :         if (r < 0)
    1267                 :          0 :                 return r;
    1268                 :            : 
    1269                 :          0 :         r = ordered_set_consume(s, p);
    1270         [ #  # ]:          0 :         if (r == -EEXIST)
    1271                 :          0 :                 return 0;
    1272                 :            : 
    1273                 :          0 :         return r;
    1274                 :            : }
    1275                 :            : 
    1276                 :          0 : static int ordered_set_put_in4_addrv(OrderedSet *s,
    1277                 :            :                                      const struct in_addr *addresses,
    1278                 :            :                                      size_t n,
    1279                 :            :                                      bool (*predicate)(const struct in_addr *addr)) {
    1280                 :          0 :         int r, c = 0;
    1281                 :            :         size_t i;
    1282                 :            : 
    1283         [ #  # ]:          0 :         assert(s);
    1284   [ #  #  #  # ]:          0 :         assert(n == 0 || addresses);
    1285                 :            : 
    1286         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
    1287   [ #  #  #  # ]:          0 :                 if (predicate && !predicate(&addresses[i]))
    1288                 :          0 :                         continue;
    1289                 :          0 :                 r = ordered_set_put_in4_addr(s, addresses+i);
    1290         [ #  # ]:          0 :                 if (r < 0)
    1291                 :          0 :                         return r;
    1292                 :            : 
    1293                 :          0 :                 c += r;
    1294                 :            :         }
    1295                 :            : 
    1296                 :          0 :         return c;
    1297                 :            : }
    1298                 :            : 
    1299                 :          0 : static int manager_save(Manager *m) {
    1300                 :          0 :         _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *search_domains = NULL, *route_domains = NULL;
    1301                 :            :         Link *link;
    1302                 :            :         Iterator i;
    1303                 :          0 :         _cleanup_free_ char *temp_path = NULL;
    1304                 :          0 :         _cleanup_strv_free_ char **p = NULL;
    1305                 :          0 :         _cleanup_fclose_ FILE *f = NULL;
    1306                 :          0 :         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
    1307                 :          0 :         LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
    1308                 :          0 :         LinkAddressState address_state = LINK_ADDRESS_STATE_OFF;
    1309                 :            :         const char *operstate_str, *carrier_state_str, *address_state_str;
    1310                 :            :         int r;
    1311                 :            : 
    1312         [ #  # ]:          0 :         assert(m);
    1313         [ #  # ]:          0 :         assert(m->state_file);
    1314                 :            : 
    1315                 :            :         /* We add all NTP and DNS server to a set, to filter out duplicates */
    1316                 :          0 :         dns = ordered_set_new(&string_hash_ops);
    1317         [ #  # ]:          0 :         if (!dns)
    1318                 :          0 :                 return -ENOMEM;
    1319                 :            : 
    1320                 :          0 :         ntp = ordered_set_new(&string_hash_ops);
    1321         [ #  # ]:          0 :         if (!ntp)
    1322                 :          0 :                 return -ENOMEM;
    1323                 :            : 
    1324                 :          0 :         search_domains = ordered_set_new(&dns_name_hash_ops);
    1325         [ #  # ]:          0 :         if (!search_domains)
    1326                 :          0 :                 return -ENOMEM;
    1327                 :            : 
    1328                 :          0 :         route_domains = ordered_set_new(&dns_name_hash_ops);
    1329         [ #  # ]:          0 :         if (!route_domains)
    1330                 :          0 :                 return -ENOMEM;
    1331                 :            : 
    1332         [ #  # ]:          0 :         HASHMAP_FOREACH(link, m->links, i) {
    1333         [ #  # ]:          0 :                 if (link->flags & IFF_LOOPBACK)
    1334                 :          0 :                         continue;
    1335                 :            : 
    1336         [ #  # ]:          0 :                 if (link->operstate > operstate)
    1337                 :          0 :                         operstate = link->operstate;
    1338                 :            : 
    1339         [ #  # ]:          0 :                 if (link->carrier_state > carrier_state)
    1340                 :          0 :                         carrier_state = link->carrier_state;
    1341                 :            : 
    1342         [ #  # ]:          0 :                 if (link->address_state > address_state)
    1343                 :          0 :                         address_state = link->address_state;
    1344                 :            : 
    1345         [ #  # ]:          0 :                 if (!link->network)
    1346                 :          0 :                         continue;
    1347                 :            : 
    1348                 :            :                 /* First add the static configured entries */
    1349                 :          0 :                 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
    1350         [ #  # ]:          0 :                 if (r < 0)
    1351                 :          0 :                         return r;
    1352                 :            : 
    1353         [ #  # ]:          0 :                 r = ordered_set_put_strdupv(ntp, link->ntp ?: link->network->ntp);
    1354         [ #  # ]:          0 :                 if (r < 0)
    1355                 :          0 :                         return r;
    1356                 :            : 
    1357         [ #  # ]:          0 :                 r = ordered_set_put_string_set(search_domains, link->search_domains ?: link->network->search_domains);
    1358         [ #  # ]:          0 :                 if (r < 0)
    1359                 :          0 :                         return r;
    1360                 :            : 
    1361         [ #  # ]:          0 :                 r = ordered_set_put_string_set(route_domains, link->route_domains ?: link->network->route_domains);
    1362         [ #  # ]:          0 :                 if (r < 0)
    1363                 :          0 :                         return r;
    1364                 :            : 
    1365         [ #  # ]:          0 :                 if (!link->dhcp_lease)
    1366                 :          0 :                         continue;
    1367                 :            : 
    1368                 :            :                 /* Secondly, add the entries acquired via DHCP */
    1369         [ #  # ]:          0 :                 if (link->network->dhcp_use_dns) {
    1370                 :            :                         const struct in_addr *addresses;
    1371                 :            : 
    1372                 :          0 :                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
    1373         [ #  # ]:          0 :                         if (r > 0) {
    1374                 :          0 :                                 r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local);
    1375         [ #  # ]:          0 :                                 if (r < 0)
    1376                 :          0 :                                         return r;
    1377   [ #  #  #  # ]:          0 :                         } else if (r < 0 && r != -ENODATA)
    1378                 :          0 :                                 return r;
    1379                 :            :                 }
    1380                 :            : 
    1381         [ #  # ]:          0 :                 if (link->network->dhcp_use_ntp) {
    1382                 :            :                         const struct in_addr *addresses;
    1383                 :            : 
    1384                 :          0 :                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
    1385         [ #  # ]:          0 :                         if (r > 0) {
    1386                 :          0 :                                 r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local);
    1387         [ #  # ]:          0 :                                 if (r < 0)
    1388                 :          0 :                                         return r;
    1389   [ #  #  #  # ]:          0 :                         } else if (r < 0 && r != -ENODATA)
    1390                 :          0 :                                 return r;
    1391                 :            :                 }
    1392                 :            : 
    1393         [ #  # ]:          0 :                 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
    1394                 :            :                         const char *domainname;
    1395                 :          0 :                         char **domains = NULL;
    1396                 :            : 
    1397         [ #  # ]:          0 :                         OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
    1398                 :          0 :                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
    1399         [ #  # ]:          0 :                         if (r >= 0) {
    1400                 :          0 :                                 r = ordered_set_put_strdup(target_domains, domainname);
    1401         [ #  # ]:          0 :                                 if (r < 0)
    1402                 :          0 :                                         return r;
    1403         [ #  # ]:          0 :                         } else if (r != -ENODATA)
    1404                 :          0 :                                 return r;
    1405                 :            : 
    1406                 :          0 :                         r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
    1407         [ #  # ]:          0 :                         if (r >= 0) {
    1408                 :          0 :                                 r = ordered_set_put_strdupv(target_domains, domains);
    1409         [ #  # ]:          0 :                                 if (r < 0)
    1410                 :          0 :                                         return r;
    1411         [ #  # ]:          0 :                         } else if (r != -ENODATA)
    1412                 :          0 :                                 return r;
    1413                 :            :                 }
    1414                 :            :         }
    1415                 :            : 
    1416         [ #  # ]:          0 :         if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED)
    1417                 :          0 :                 carrier_state = LINK_CARRIER_STATE_CARRIER;
    1418                 :            : 
    1419                 :          0 :         operstate_str = link_operstate_to_string(operstate);
    1420         [ #  # ]:          0 :         assert(operstate_str);
    1421                 :            : 
    1422                 :          0 :         carrier_state_str = link_carrier_state_to_string(carrier_state);
    1423         [ #  # ]:          0 :         assert(carrier_state_str);
    1424                 :            : 
    1425                 :          0 :         address_state_str = link_address_state_to_string(address_state);
    1426         [ #  # ]:          0 :         assert(address_state_str);
    1427                 :            : 
    1428                 :          0 :         r = fopen_temporary(m->state_file, &f, &temp_path);
    1429         [ #  # ]:          0 :         if (r < 0)
    1430                 :          0 :                 return r;
    1431                 :            : 
    1432                 :          0 :         (void) fchmod(fileno(f), 0644);
    1433                 :            : 
    1434                 :          0 :         fprintf(f,
    1435                 :            :                 "# This is private data. Do not parse.\n"
    1436                 :            :                 "OPER_STATE=%s\n"
    1437                 :            :                 "CARRIER_STATE=%s\n"
    1438                 :            :                 "ADDRESS_STATE=%s\n",
    1439                 :            :                 operstate_str, carrier_state_str, address_state_str);
    1440                 :            : 
    1441                 :          0 :         ordered_set_print(f, "DNS=", dns);
    1442                 :          0 :         ordered_set_print(f, "NTP=", ntp);
    1443                 :          0 :         ordered_set_print(f, "DOMAINS=", search_domains);
    1444                 :          0 :         ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);
    1445                 :            : 
    1446                 :          0 :         r = routing_policy_serialize_rules(m->rules, f);
    1447         [ #  # ]:          0 :         if (r < 0)
    1448                 :          0 :                 goto fail;
    1449                 :            : 
    1450                 :          0 :         r = fflush_and_check(f);
    1451         [ #  # ]:          0 :         if (r < 0)
    1452                 :          0 :                 goto fail;
    1453                 :            : 
    1454         [ #  # ]:          0 :         if (rename(temp_path, m->state_file) < 0) {
    1455                 :          0 :                 r = -errno;
    1456                 :          0 :                 goto fail;
    1457                 :            :         }
    1458                 :            : 
    1459         [ #  # ]:          0 :         if (m->operational_state != operstate) {
    1460                 :          0 :                 m->operational_state = operstate;
    1461         [ #  # ]:          0 :                 if (strv_extend(&p, "OperationalState") < 0)
    1462                 :          0 :                         log_oom();
    1463                 :            :         }
    1464                 :            : 
    1465         [ #  # ]:          0 :         if (m->carrier_state != carrier_state) {
    1466                 :          0 :                 m->carrier_state = carrier_state;
    1467         [ #  # ]:          0 :                 if (strv_extend(&p, "CarrierState") < 0)
    1468                 :          0 :                         log_oom();
    1469                 :            :         }
    1470                 :            : 
    1471         [ #  # ]:          0 :         if (m->address_state != address_state) {
    1472                 :          0 :                 m->address_state = address_state;
    1473         [ #  # ]:          0 :                 if (strv_extend(&p, "AddressState") < 0)
    1474                 :          0 :                         log_oom();
    1475                 :            :         }
    1476                 :            : 
    1477         [ #  # ]:          0 :         if (p) {
    1478                 :          0 :                 r = manager_send_changed_strv(m, p);
    1479         [ #  # ]:          0 :                 if (r < 0)
    1480         [ #  # ]:          0 :                         log_error_errno(r, "Could not emit changed properties: %m");
    1481                 :            :         }
    1482                 :            : 
    1483                 :          0 :         m->dirty = false;
    1484                 :            : 
    1485                 :          0 :         return 0;
    1486                 :            : 
    1487                 :          0 : fail:
    1488                 :          0 :         (void) unlink(m->state_file);
    1489                 :          0 :         (void) unlink(temp_path);
    1490                 :            : 
    1491         [ #  # ]:          0 :         return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file);
    1492                 :            : }
    1493                 :            : 
    1494                 :          0 : static int manager_dirty_handler(sd_event_source *s, void *userdata) {
    1495                 :          0 :         Manager *m = userdata;
    1496                 :            :         Link *link;
    1497                 :            :         Iterator i;
    1498                 :            : 
    1499         [ #  # ]:          0 :         assert(m);
    1500                 :            : 
    1501         [ #  # ]:          0 :         if (m->dirty)
    1502                 :          0 :                 manager_save(m);
    1503                 :            : 
    1504         [ #  # ]:          0 :         SET_FOREACH(link, m->dirty_links, i)
    1505         [ #  # ]:          0 :                 if (link_save(link) >= 0)
    1506                 :          0 :                         link_clean(link);
    1507                 :            : 
    1508                 :          0 :         return 1;
    1509                 :            : }
    1510                 :            : 
    1511                 :          4 : int manager_new(Manager **ret) {
    1512                 :          4 :         _cleanup_(manager_freep) Manager *m = NULL;
    1513                 :            :         int r;
    1514                 :            : 
    1515                 :          4 :         m = new(Manager, 1);
    1516         [ -  + ]:          4 :         if (!m)
    1517                 :          0 :                 return -ENOMEM;
    1518                 :            : 
    1519                 :          4 :         *m = (Manager) {
    1520                 :            :                 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
    1521                 :            :         };
    1522                 :            : 
    1523                 :          4 :         m->state_file = strdup("/run/systemd/netif/state");
    1524         [ -  + ]:          4 :         if (!m->state_file)
    1525                 :          0 :                 return -ENOMEM;
    1526                 :            : 
    1527                 :          4 :         r = sd_event_default(&m->event);
    1528         [ -  + ]:          4 :         if (r < 0)
    1529                 :          0 :                 return r;
    1530                 :            : 
    1531                 :          4 :         (void) sd_event_set_watchdog(m->event, true);
    1532                 :          4 :         (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
    1533                 :          4 :         (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
    1534                 :            : 
    1535                 :          4 :         r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
    1536         [ -  + ]:          4 :         if (r < 0)
    1537                 :          0 :                 return r;
    1538                 :            : 
    1539                 :          4 :         r = manager_connect_rtnl(m);
    1540         [ -  + ]:          4 :         if (r < 0)
    1541                 :          0 :                 return r;
    1542                 :            : 
    1543                 :          4 :         r = manager_connect_genl(m);
    1544         [ -  + ]:          4 :         if (r < 0)
    1545                 :          0 :                 return r;
    1546                 :            : 
    1547                 :          4 :         r = manager_connect_udev(m);
    1548         [ -  + ]:          4 :         if (r < 0)
    1549                 :          0 :                 return r;
    1550                 :            : 
    1551                 :          4 :         r = sd_resolve_default(&m->resolve);
    1552         [ -  + ]:          4 :         if (r < 0)
    1553                 :          0 :                 return r;
    1554                 :            : 
    1555                 :          4 :         r = sd_resolve_attach_event(m->resolve, m->event, 0);
    1556         [ -  + ]:          4 :         if (r < 0)
    1557                 :          0 :                 return r;
    1558                 :            : 
    1559                 :          4 :         r = setup_default_address_pool(m);
    1560         [ -  + ]:          4 :         if (r < 0)
    1561                 :          0 :                 return r;
    1562                 :            : 
    1563                 :          4 :         m->duid.type = DUID_TYPE_EN;
    1564                 :            : 
    1565                 :          4 :         (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
    1566                 :            : 
    1567                 :          4 :         *ret = TAKE_PTR(m);
    1568                 :            : 
    1569                 :          4 :         return 0;
    1570                 :            : }
    1571                 :            : 
    1572                 :          4 : void manager_free(Manager *m) {
    1573                 :            :         struct in6_addr *a;
    1574                 :            :         AddressPool *pool;
    1575                 :            :         Link *link;
    1576                 :            : 
    1577         [ -  + ]:          4 :         if (!m)
    1578                 :          0 :                 return;
    1579                 :            : 
    1580                 :          4 :         free(m->state_file);
    1581                 :            : 
    1582         [ -  + ]:          4 :         while ((a = hashmap_first_key(m->dhcp6_prefixes)))
    1583                 :          0 :                 (void) dhcp6_prefix_remove(m, a);
    1584                 :          4 :         m->dhcp6_prefixes = hashmap_free(m->dhcp6_prefixes);
    1585                 :            : 
    1586         [ +  + ]:         32 :         while ((link = hashmap_steal_first(m->links))) {
    1587         [ -  + ]:         28 :                 if (link->dhcp6_client)
    1588                 :          0 :                         (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
    1589                 :            : 
    1590                 :         28 :                 (void) link_stop_clients(link, true);
    1591                 :            : 
    1592                 :         28 :                 link_unref(link);
    1593                 :            :         }
    1594                 :            : 
    1595         [ +  + ]:         28 :         m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
    1596         [ -  + ]:          4 :         m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
    1597         [ -  + ]:          4 :         m->links = hashmap_free_with_destructor(m->links, link_unref);
    1598                 :            : 
    1599                 :          4 :         m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
    1600         [ +  + ]:         12 :         m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
    1601                 :            : 
    1602         [ -  + ]:          4 :         m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
    1603                 :            : 
    1604         [ +  + ]:         20 :         while ((pool = m->address_pools))
    1605                 :         16 :                 address_pool_free(pool);
    1606                 :            : 
    1607                 :            :         /* routing_policy_rule_free() access m->rules and m->rules_foreign.
    1608                 :            :          * So, it is necessary to set NULL after the sets are freed. */
    1609         [ -  + ]:          4 :         m->rules = set_free_with_destructor(m->rules, routing_policy_rule_free);
    1610         [ -  + ]:          4 :         m->rules_foreign = set_free_with_destructor(m->rules_foreign, routing_policy_rule_free);
    1611         [ -  + ]:          4 :         set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
    1612                 :            : 
    1613                 :          4 :         sd_netlink_unref(m->rtnl);
    1614                 :          4 :         sd_netlink_unref(m->genl);
    1615                 :          4 :         sd_resolve_unref(m->resolve);
    1616                 :            : 
    1617                 :          4 :         sd_event_source_unref(m->speed_meter_event_source);
    1618                 :          4 :         sd_event_unref(m->event);
    1619                 :            : 
    1620                 :          4 :         sd_device_monitor_unref(m->device_monitor);
    1621                 :            : 
    1622                 :          4 :         bus_verify_polkit_async_registry_free(m->polkit_registry);
    1623                 :          4 :         sd_bus_flush_close_unref(m->bus);
    1624                 :            : 
    1625                 :          4 :         free(m->dynamic_timezone);
    1626                 :          4 :         free(m->dynamic_hostname);
    1627                 :            : 
    1628                 :          4 :         free(m);
    1629                 :            : }
    1630                 :            : 
    1631                 :          0 : int manager_start(Manager *m) {
    1632                 :            :         Link *link;
    1633                 :            :         Iterator i;
    1634                 :            :         int r;
    1635                 :            : 
    1636         [ #  # ]:          0 :         assert(m);
    1637                 :            : 
    1638                 :          0 :         r = manager_start_speed_meter(m);
    1639         [ #  # ]:          0 :         if (r < 0)
    1640         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to initialize speed meter: %m");
    1641                 :            : 
    1642                 :            :         /* The dirty handler will deal with future serialization, but the first one
    1643                 :            :            must be done explicitly. */
    1644                 :            : 
    1645                 :          0 :         manager_save(m);
    1646                 :            : 
    1647         [ #  # ]:          0 :         HASHMAP_FOREACH(link, m->links, i)
    1648                 :          0 :                 link_save(link);
    1649                 :            : 
    1650                 :          0 :         return 0;
    1651                 :            : }
    1652                 :            : 
    1653                 :          4 : int manager_load_config(Manager *m) {
    1654                 :            :         int r;
    1655                 :            : 
    1656                 :            :         /* update timestamp */
    1657                 :          4 :         paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, true);
    1658                 :            : 
    1659                 :          4 :         r = netdev_load(m);
    1660         [ -  + ]:          4 :         if (r < 0)
    1661                 :          0 :                 return r;
    1662                 :            : 
    1663                 :          4 :         r = network_load(m);
    1664         [ -  + ]:          4 :         if (r < 0)
    1665                 :          0 :                 return r;
    1666                 :            : 
    1667                 :          4 :         return 0;
    1668                 :            : }
    1669                 :            : 
    1670                 :          4 : bool manager_should_reload(Manager *m) {
    1671                 :          4 :         return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
    1672                 :            : }
    1673                 :            : 
    1674                 :          4 : int manager_rtnl_enumerate_links(Manager *m) {
    1675                 :          4 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1676                 :            :         sd_netlink_message *link;
    1677                 :            :         int r;
    1678                 :            : 
    1679         [ -  + ]:          4 :         assert(m);
    1680         [ -  + ]:          4 :         assert(m->rtnl);
    1681                 :            : 
    1682                 :          4 :         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
    1683         [ -  + ]:          4 :         if (r < 0)
    1684                 :          0 :                 return r;
    1685                 :            : 
    1686                 :          4 :         r = sd_netlink_message_request_dump(req, true);
    1687         [ -  + ]:          4 :         if (r < 0)
    1688                 :          0 :                 return r;
    1689                 :            : 
    1690                 :          4 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1691         [ -  + ]:          4 :         if (r < 0)
    1692                 :          0 :                 return r;
    1693                 :            : 
    1694         [ +  + ]:         32 :         for (link = reply; link; link = sd_netlink_message_next(link)) {
    1695                 :            :                 int k;
    1696                 :            : 
    1697                 :         28 :                 m->enumerating = true;
    1698                 :            : 
    1699                 :         28 :                 k = manager_rtnl_process_link(m->rtnl, link, m);
    1700         [ -  + ]:         28 :                 if (k < 0)
    1701                 :          0 :                         r = k;
    1702                 :            : 
    1703                 :         28 :                 m->enumerating = false;
    1704                 :            :         }
    1705                 :            : 
    1706                 :          4 :         return r;
    1707                 :            : }
    1708                 :            : 
    1709                 :          0 : int manager_rtnl_enumerate_addresses(Manager *m) {
    1710                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1711                 :            :         sd_netlink_message *addr;
    1712                 :            :         int r;
    1713                 :            : 
    1714         [ #  # ]:          0 :         assert(m);
    1715         [ #  # ]:          0 :         assert(m->rtnl);
    1716                 :            : 
    1717                 :          0 :         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
    1718         [ #  # ]:          0 :         if (r < 0)
    1719                 :          0 :                 return r;
    1720                 :            : 
    1721                 :          0 :         r = sd_netlink_message_request_dump(req, true);
    1722         [ #  # ]:          0 :         if (r < 0)
    1723                 :          0 :                 return r;
    1724                 :            : 
    1725                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1726         [ #  # ]:          0 :         if (r < 0)
    1727                 :          0 :                 return r;
    1728                 :            : 
    1729         [ #  # ]:          0 :         for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
    1730                 :            :                 int k;
    1731                 :            : 
    1732                 :          0 :                 m->enumerating = true;
    1733                 :            : 
    1734                 :          0 :                 k = manager_rtnl_process_address(m->rtnl, addr, m);
    1735         [ #  # ]:          0 :                 if (k < 0)
    1736                 :          0 :                         r = k;
    1737                 :            : 
    1738                 :          0 :                 m->enumerating = false;
    1739                 :            :         }
    1740                 :            : 
    1741                 :          0 :         return r;
    1742                 :            : }
    1743                 :            : 
    1744                 :          0 : int manager_rtnl_enumerate_neighbors(Manager *m) {
    1745                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1746                 :            :         sd_netlink_message *neigh;
    1747                 :            :         int r;
    1748                 :            : 
    1749         [ #  # ]:          0 :         assert(m);
    1750         [ #  # ]:          0 :         assert(m->rtnl);
    1751                 :            : 
    1752                 :          0 :         r = sd_rtnl_message_new_neigh(m->rtnl, &req, RTM_GETNEIGH, 0, AF_UNSPEC);
    1753         [ #  # ]:          0 :         if (r < 0)
    1754                 :          0 :                 return r;
    1755                 :            : 
    1756                 :          0 :         r = sd_netlink_message_request_dump(req, true);
    1757         [ #  # ]:          0 :         if (r < 0)
    1758                 :          0 :                 return r;
    1759                 :            : 
    1760                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1761         [ #  # ]:          0 :         if (r < 0)
    1762                 :          0 :                 return r;
    1763                 :            : 
    1764         [ #  # ]:          0 :         for (neigh = reply; neigh; neigh = sd_netlink_message_next(neigh)) {
    1765                 :            :                 int k;
    1766                 :            : 
    1767                 :          0 :                 m->enumerating = true;
    1768                 :            : 
    1769                 :          0 :                 k = manager_rtnl_process_neighbor(m->rtnl, neigh, m);
    1770         [ #  # ]:          0 :                 if (k < 0)
    1771                 :          0 :                         r = k;
    1772                 :            : 
    1773                 :          0 :                 m->enumerating = false;
    1774                 :            :         }
    1775                 :            : 
    1776                 :          0 :         return r;
    1777                 :            : }
    1778                 :            : 
    1779                 :          0 : int manager_rtnl_enumerate_routes(Manager *m) {
    1780                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1781                 :            :         sd_netlink_message *route;
    1782                 :            :         int r;
    1783                 :            : 
    1784         [ #  # ]:          0 :         assert(m);
    1785         [ #  # ]:          0 :         assert(m->rtnl);
    1786                 :            : 
    1787                 :          0 :         r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
    1788         [ #  # ]:          0 :         if (r < 0)
    1789                 :          0 :                 return r;
    1790                 :            : 
    1791                 :          0 :         r = sd_netlink_message_request_dump(req, true);
    1792         [ #  # ]:          0 :         if (r < 0)
    1793                 :          0 :                 return r;
    1794                 :            : 
    1795                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1796         [ #  # ]:          0 :         if (r < 0)
    1797                 :          0 :                 return r;
    1798                 :            : 
    1799         [ #  # ]:          0 :         for (route = reply; route; route = sd_netlink_message_next(route)) {
    1800                 :            :                 int k;
    1801                 :            : 
    1802                 :          0 :                 m->enumerating = true;
    1803                 :            : 
    1804                 :          0 :                 k = manager_rtnl_process_route(m->rtnl, route, m);
    1805         [ #  # ]:          0 :                 if (k < 0)
    1806                 :          0 :                         r = k;
    1807                 :            : 
    1808                 :          0 :                 m->enumerating = false;
    1809                 :            :         }
    1810                 :            : 
    1811                 :          0 :         return r;
    1812                 :            : }
    1813                 :            : 
    1814                 :          0 : int manager_rtnl_enumerate_rules(Manager *m) {
    1815                 :          0 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1816                 :            :         sd_netlink_message *rule;
    1817                 :            :         int r;
    1818                 :            : 
    1819         [ #  # ]:          0 :         assert(m);
    1820         [ #  # ]:          0 :         assert(m->rtnl);
    1821                 :            : 
    1822                 :          0 :         r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
    1823         [ #  # ]:          0 :         if (r < 0)
    1824                 :          0 :                 return r;
    1825                 :            : 
    1826                 :          0 :         r = sd_netlink_message_request_dump(req, true);
    1827         [ #  # ]:          0 :         if (r < 0)
    1828                 :          0 :                 return r;
    1829                 :            : 
    1830                 :          0 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1831         [ #  # ]:          0 :         if (r < 0) {
    1832         [ #  # ]:          0 :                 if (r == -EOPNOTSUPP) {
    1833         [ #  # ]:          0 :                         log_debug("FIB Rules are not supported by the kernel. Ignoring.");
    1834                 :          0 :                         return 0;
    1835                 :            :                 }
    1836                 :            : 
    1837                 :          0 :                 return r;
    1838                 :            :         }
    1839                 :            : 
    1840         [ #  # ]:          0 :         for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
    1841                 :            :                 int k;
    1842                 :            : 
    1843                 :          0 :                 m->enumerating = true;
    1844                 :            : 
    1845                 :          0 :                 k = manager_rtnl_process_rule(m->rtnl, rule, m);
    1846         [ #  # ]:          0 :                 if (k < 0)
    1847                 :          0 :                         r = k;
    1848                 :            : 
    1849                 :          0 :                 m->enumerating = false;
    1850                 :            :         }
    1851                 :            : 
    1852                 :          0 :         return r;
    1853                 :            : }
    1854                 :            : 
    1855                 :          0 : int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
    1856                 :            :         AddressPool *p;
    1857                 :            :         int r;
    1858                 :            : 
    1859         [ #  # ]:          0 :         assert(m);
    1860         [ #  # ]:          0 :         assert(prefixlen > 0);
    1861         [ #  # ]:          0 :         assert(found);
    1862                 :            : 
    1863         [ #  # ]:          0 :         LIST_FOREACH(address_pools, p, m->address_pools) {
    1864         [ #  # ]:          0 :                 if (p->family != family)
    1865                 :          0 :                         continue;
    1866                 :            : 
    1867                 :          0 :                 r = address_pool_acquire(p, prefixlen, found);
    1868         [ #  # ]:          0 :                 if (r != 0)
    1869                 :          0 :                         return r;
    1870                 :            :         }
    1871                 :            : 
    1872                 :          0 :         return 0;
    1873                 :            : }
    1874                 :            : 
    1875                 :          0 : Link* manager_find_uplink(Manager *m, Link *exclude) {
    1876                 :          0 :         _cleanup_free_ struct local_address *gateways = NULL;
    1877                 :            :         int n, i;
    1878                 :            : 
    1879         [ #  # ]:          0 :         assert(m);
    1880                 :            : 
    1881                 :            :         /* Looks for a suitable "uplink", via black magic: an
    1882                 :            :          * interface that is up and where the default route with the
    1883                 :            :          * highest priority points to. */
    1884                 :            : 
    1885                 :          0 :         n = local_gateways(m->rtnl, 0, AF_UNSPEC, &gateways);
    1886         [ #  # ]:          0 :         if (n < 0) {
    1887         [ #  # ]:          0 :                 log_warning_errno(n, "Failed to determine list of default gateways: %m");
    1888                 :          0 :                 return NULL;
    1889                 :            :         }
    1890                 :            : 
    1891         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
    1892                 :            :                 Link *link;
    1893                 :            : 
    1894                 :          0 :                 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex));
    1895         [ #  # ]:          0 :                 if (!link) {
    1896         [ #  # ]:          0 :                         log_debug("Weird, found a gateway for a link we don't know. Ignoring.");
    1897                 :          0 :                         continue;
    1898                 :            :                 }
    1899                 :            : 
    1900         [ #  # ]:          0 :                 if (link == exclude)
    1901                 :          0 :                         continue;
    1902                 :            : 
    1903         [ #  # ]:          0 :                 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
    1904                 :          0 :                         continue;
    1905                 :            : 
    1906                 :          0 :                 return link;
    1907                 :            :         }
    1908                 :            : 
    1909                 :          0 :         return NULL;
    1910                 :            : }
    1911                 :            : 
    1912                 :         24 : void manager_dirty(Manager *manager) {
    1913         [ -  + ]:         24 :         assert(manager);
    1914                 :            : 
    1915                 :            :         /* the serialized state in /run is no longer up-to-date */
    1916                 :         24 :         manager->dirty = true;
    1917                 :         24 : }
    1918                 :            : 
    1919                 :          0 : static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
    1920                 :          0 :         Manager *manager = userdata;
    1921                 :            :         const sd_bus_error *e;
    1922                 :            : 
    1923         [ #  # ]:          0 :         assert(m);
    1924         [ #  # ]:          0 :         assert(manager);
    1925                 :            : 
    1926                 :          0 :         e = sd_bus_message_get_error(m);
    1927         [ #  # ]:          0 :         if (e)
    1928         [ #  # ]:          0 :                 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message);
    1929                 :            : 
    1930                 :          0 :         return 1;
    1931                 :            : }
    1932                 :            : 
    1933                 :          0 : int manager_set_hostname(Manager *m, const char *hostname) {
    1934                 :            :         int r;
    1935                 :            : 
    1936         [ #  # ]:          0 :         log_debug("Setting transient hostname: '%s'", strna(hostname));
    1937                 :            : 
    1938         [ #  # ]:          0 :         if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
    1939                 :          0 :                 return log_oom();
    1940                 :            : 
    1941   [ #  #  #  # ]:          0 :         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
    1942         [ #  # ]:          0 :                 log_debug("Not connected to system bus, setting hostname later.");
    1943                 :          0 :                 return 0;
    1944                 :            :         }
    1945                 :            : 
    1946                 :          0 :         r = sd_bus_call_method_async(
    1947                 :            :                         m->bus,
    1948                 :            :                         NULL,
    1949                 :            :                         "org.freedesktop.hostname1",
    1950                 :            :                         "/org/freedesktop/hostname1",
    1951                 :            :                         "org.freedesktop.hostname1",
    1952                 :            :                         "SetHostname",
    1953                 :            :                         set_hostname_handler,
    1954                 :            :                         m,
    1955                 :            :                         "sb",
    1956                 :            :                         hostname,
    1957                 :            :                         false);
    1958                 :            : 
    1959         [ #  # ]:          0 :         if (r < 0)
    1960         [ #  # ]:          0 :                 return log_error_errno(r, "Could not set transient hostname: %m");
    1961                 :            : 
    1962                 :          0 :         return 0;
    1963                 :            : }
    1964                 :            : 
    1965                 :          0 : static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
    1966                 :          0 :         Manager *manager = userdata;
    1967                 :            :         const sd_bus_error *e;
    1968                 :            : 
    1969         [ #  # ]:          0 :         assert(m);
    1970         [ #  # ]:          0 :         assert(manager);
    1971                 :            : 
    1972                 :          0 :         e = sd_bus_message_get_error(m);
    1973         [ #  # ]:          0 :         if (e)
    1974         [ #  # ]:          0 :                 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message);
    1975                 :            : 
    1976                 :          0 :         return 1;
    1977                 :            : }
    1978                 :            : 
    1979                 :          0 : int manager_set_timezone(Manager *m, const char *tz) {
    1980                 :            :         int r;
    1981                 :            : 
    1982         [ #  # ]:          0 :         assert(m);
    1983         [ #  # ]:          0 :         assert(tz);
    1984                 :            : 
    1985         [ #  # ]:          0 :         log_debug("Setting system timezone: '%s'", tz);
    1986         [ #  # ]:          0 :         if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
    1987                 :          0 :                 return log_oom();
    1988                 :            : 
    1989   [ #  #  #  # ]:          0 :         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
    1990         [ #  # ]:          0 :                 log_debug("Not connected to system bus, setting timezone later.");
    1991                 :          0 :                 return 0;
    1992                 :            :         }
    1993                 :            : 
    1994                 :          0 :         r = sd_bus_call_method_async(
    1995                 :            :                         m->bus,
    1996                 :            :                         NULL,
    1997                 :            :                         "org.freedesktop.timedate1",
    1998                 :            :                         "/org/freedesktop/timedate1",
    1999                 :            :                         "org.freedesktop.timedate1",
    2000                 :            :                         "SetTimezone",
    2001                 :            :                         set_timezone_handler,
    2002                 :            :                         m,
    2003                 :            :                         "sb",
    2004                 :            :                         tz,
    2005                 :            :                         false);
    2006         [ #  # ]:          0 :         if (r < 0)
    2007         [ #  # ]:          0 :                 return log_error_errno(r, "Could not set timezone: %m");
    2008                 :            : 
    2009                 :          0 :         return 0;
    2010                 :            : }
    2011                 :            : 
    2012                 :          0 : int manager_request_product_uuid(Manager *m, Link *link) {
    2013                 :            :         int r;
    2014                 :            : 
    2015         [ #  # ]:          0 :         assert(m);
    2016                 :            : 
    2017         [ #  # ]:          0 :         if (m->has_product_uuid)
    2018                 :          0 :                 return 0;
    2019                 :            : 
    2020         [ #  # ]:          0 :         log_debug("Requesting product UUID");
    2021                 :            : 
    2022         [ #  # ]:          0 :         if (link) {
    2023                 :            :                 DUID *duid;
    2024                 :            : 
    2025         [ #  # ]:          0 :                 assert_se(duid = link_get_duid(link));
    2026                 :            : 
    2027                 :          0 :                 r = set_ensure_allocated(&m->links_requesting_uuid, NULL);
    2028         [ #  # ]:          0 :                 if (r < 0)
    2029                 :          0 :                         return log_oom();
    2030                 :            : 
    2031                 :          0 :                 r = set_ensure_allocated(&m->duids_requesting_uuid, NULL);
    2032         [ #  # ]:          0 :                 if (r < 0)
    2033                 :          0 :                         return log_oom();
    2034                 :            : 
    2035                 :          0 :                 r = set_put(m->links_requesting_uuid, link);
    2036         [ #  # ]:          0 :                 if (r < 0)
    2037                 :          0 :                         return log_oom();
    2038                 :            : 
    2039                 :          0 :                 r = set_put(m->duids_requesting_uuid, duid);
    2040         [ #  # ]:          0 :                 if (r < 0)
    2041                 :          0 :                         return log_oom();
    2042                 :            : 
    2043                 :          0 :                 link_ref(link);
    2044                 :            :         }
    2045                 :            : 
    2046   [ #  #  #  # ]:          0 :         if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
    2047         [ #  # ]:          0 :                 log_debug("Not connected to system bus, requesting product UUID later.");
    2048                 :          0 :                 return 0;
    2049                 :            :         }
    2050                 :            : 
    2051                 :          0 :         r = sd_bus_call_method_async(
    2052                 :            :                         m->bus,
    2053                 :            :                         NULL,
    2054                 :            :                         "org.freedesktop.hostname1",
    2055                 :            :                         "/org/freedesktop/hostname1",
    2056                 :            :                         "org.freedesktop.hostname1",
    2057                 :            :                         "GetProductUUID",
    2058                 :            :                         get_product_uuid_handler,
    2059                 :            :                         m,
    2060                 :            :                         "b",
    2061                 :            :                         false);
    2062         [ #  # ]:          0 :         if (r < 0)
    2063         [ #  # ]:          0 :                 return log_warning_errno(r, "Failed to get product UUID: %m");
    2064                 :            : 
    2065                 :          0 :         return 0;
    2066                 :            : }

Generated by: LCOV version 1.14