LCOV - code coverage report
Current view: top level - network - networkd-manager.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 185 1220 15.2 %
Date: 2019-08-22 15:41:25 Functions: 12 40 30.0 %

          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           1 : static int setup_default_address_pool(Manager *m) {
      43             :         AddressPool *p;
      44             :         int r;
      45             : 
      46           1 :         assert(m);
      47             : 
      48             :         /* Add in the well-known private address ranges. */
      49             : 
      50           1 :         r = address_pool_new_from_string(m, &p, AF_INET6, "fd00::", 8);
      51           1 :         if (r < 0)
      52           0 :                 return r;
      53             : 
      54           1 :         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
      55           1 :         if (r < 0)
      56           0 :                 return r;
      57             : 
      58           1 :         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
      59           1 :         if (r < 0)
      60           0 :                 return r;
      61             : 
      62           1 :         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
      63           1 :         if (r < 0)
      64           0 :                 return r;
      65             : 
      66           1 :         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           1 : 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           1 :         if (detect_container() > 0)
     246           0 :                 return 0;
     247             : 
     248           1 :         r = sd_device_monitor_new(&m->device_monitor);
     249           1 :         if (r < 0)
     250           0 :                 return log_error_errno(r, "Failed to initialize device monitor: %m");
     251             : 
     252           1 :         r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
     253           1 :         if (r < 0)
     254           0 :                 return log_error_errno(r, "Could not add device monitor filter: %m");
     255             : 
     256           1 :         r = sd_device_monitor_attach_event(m->device_monitor, m->event);
     257           1 :         if (r < 0)
     258           0 :                 return log_error_errno(r, "Failed to attach event to device monitor: %m");
     259             : 
     260           1 :         r = sd_device_monitor_start(m->device_monitor, manager_udev_process_link, m);
     261           1 :         if (r < 0)
     262           0 :                 return log_error_errno(r, "Failed to start device monitor: %m");
     263             : 
     264           1 :         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           6 : static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
     828           6 :         Manager *m = userdata;
     829           6 :         Link *link = NULL;
     830           6 :         NetDev *netdev = NULL;
     831             :         uint16_t type;
     832             :         const char *name;
     833             :         int r, ifindex;
     834             : 
     835           6 :         assert(rtnl);
     836           6 :         assert(message);
     837           6 :         assert(m);
     838             : 
     839           6 :         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           6 :         r = sd_netlink_message_get_type(message, &type);
     848           6 :         if (r < 0) {
     849           0 :                 log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
     850           0 :                 return 0;
     851           6 :         } 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           6 :         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
     857           6 :         if (r < 0) {
     858           0 :                 log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
     859           0 :                 return 0;
     860           6 :         } 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           6 :         r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
     866           6 :         if (r < 0) {
     867           0 :                 log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
     868           0 :                 return 0;
     869             :         }
     870             : 
     871           6 :         (void) link_get(m, ifindex, &link);
     872           6 :         (void) netdev_get(m, name, &netdev);
     873             : 
     874           6 :         switch (type) {
     875           6 :         case RTM_NEWLINK:
     876           6 :                 if (!link) {
     877             :                         /* link is new, so add it */
     878           6 :                         r = link_add(m, message, &link);
     879           6 :                         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           6 :                 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           6 :                 r = link_update(link, message);
     895           6 :                 if (r < 0) {
     896           0 :                         log_warning_errno(r, "Could not process link message, ignoring: %m");
     897           0 :                         return 0;
     898             :                 }
     899             : 
     900           6 :                 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           6 :         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           1 : static int systemd_netlink_fd(void) {
    1120           1 :         int n, fd, rtnl_fd = -EINVAL;
    1121             : 
    1122           1 :         n = sd_listen_fds(true);
    1123           1 :         if (n <= 0)
    1124           1 :                 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           1 : static int manager_connect_genl(Manager *m) {
    1139             :         int r;
    1140             : 
    1141           1 :         assert(m);
    1142             : 
    1143           1 :         r = sd_genl_socket_open(&m->genl);
    1144           1 :         if (r < 0)
    1145           0 :                 return r;
    1146             : 
    1147           1 :         r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE);
    1148           1 :         if (r < 0)
    1149           0 :                 return r;
    1150             : 
    1151           1 :         r = sd_netlink_attach_event(m->genl, m->event, 0);
    1152           1 :         if (r < 0)
    1153           0 :                 return r;
    1154             : 
    1155           1 :         return 0;
    1156             : }
    1157             : 
    1158           1 : static int manager_connect_rtnl(Manager *m) {
    1159             :         int fd, r;
    1160             : 
    1161           1 :         assert(m);
    1162             : 
    1163           1 :         fd = systemd_netlink_fd();
    1164           1 :         if (fd < 0)
    1165           1 :                 r = sd_netlink_open(&m->rtnl);
    1166             :         else
    1167           0 :                 r = sd_netlink_open_fd(&m->rtnl, fd);
    1168           1 :         if (r < 0)
    1169           0 :                 return r;
    1170             : 
    1171           1 :         r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
    1172           1 :         if (r < 0)
    1173           0 :                 return r;
    1174             : 
    1175           1 :         r = sd_netlink_attach_event(m->rtnl, m->event, 0);
    1176           1 :         if (r < 0)
    1177           0 :                 return r;
    1178             : 
    1179           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
    1180           1 :         if (r < 0)
    1181           0 :                 return r;
    1182             : 
    1183           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
    1184           1 :         if (r < 0)
    1185           0 :                 return r;
    1186             : 
    1187           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
    1188           1 :         if (r < 0)
    1189           0 :                 return r;
    1190             : 
    1191           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
    1192           1 :         if (r < 0)
    1193           0 :                 return r;
    1194             : 
    1195           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
    1196           1 :         if (r < 0)
    1197           0 :                 return r;
    1198             : 
    1199           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
    1200           1 :         if (r < 0)
    1201           0 :                 return r;
    1202             : 
    1203           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
    1204           1 :         if (r < 0)
    1205           0 :                 return r;
    1206             : 
    1207           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
    1208           1 :         if (r < 0)
    1209           0 :                 return r;
    1210             : 
    1211           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
    1212           1 :         if (r < 0)
    1213           0 :                 return r;
    1214             : 
    1215           1 :         r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
    1216           1 :         if (r < 0)
    1217           0 :                 return r;
    1218             : 
    1219           1 :         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           1 : int manager_new(Manager **ret) {
    1512           1 :         _cleanup_(manager_freep) Manager *m = NULL;
    1513             :         int r;
    1514             : 
    1515           1 :         m = new(Manager, 1);
    1516           1 :         if (!m)
    1517           0 :                 return -ENOMEM;
    1518             : 
    1519           1 :         *m = (Manager) {
    1520             :                 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
    1521             :         };
    1522             : 
    1523           1 :         m->state_file = strdup("/run/systemd/netif/state");
    1524           1 :         if (!m->state_file)
    1525           0 :                 return -ENOMEM;
    1526             : 
    1527           1 :         r = sd_event_default(&m->event);
    1528           1 :         if (r < 0)
    1529           0 :                 return r;
    1530             : 
    1531           1 :         (void) sd_event_set_watchdog(m->event, true);
    1532           1 :         (void) sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
    1533           1 :         (void) sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
    1534             : 
    1535           1 :         r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
    1536           1 :         if (r < 0)
    1537           0 :                 return r;
    1538             : 
    1539           1 :         r = manager_connect_rtnl(m);
    1540           1 :         if (r < 0)
    1541           0 :                 return r;
    1542             : 
    1543           1 :         r = manager_connect_genl(m);
    1544           1 :         if (r < 0)
    1545           0 :                 return r;
    1546             : 
    1547           1 :         r = manager_connect_udev(m);
    1548           1 :         if (r < 0)
    1549           0 :                 return r;
    1550             : 
    1551           1 :         r = sd_resolve_default(&m->resolve);
    1552           1 :         if (r < 0)
    1553           0 :                 return r;
    1554             : 
    1555           1 :         r = sd_resolve_attach_event(m->resolve, m->event, 0);
    1556           1 :         if (r < 0)
    1557           0 :                 return r;
    1558             : 
    1559           1 :         r = setup_default_address_pool(m);
    1560           1 :         if (r < 0)
    1561           0 :                 return r;
    1562             : 
    1563           1 :         m->duid.type = DUID_TYPE_EN;
    1564             : 
    1565           1 :         (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
    1566             : 
    1567           1 :         *ret = TAKE_PTR(m);
    1568             : 
    1569           1 :         return 0;
    1570             : }
    1571             : 
    1572           1 : void manager_free(Manager *m) {
    1573             :         struct in6_addr *a;
    1574             :         AddressPool *pool;
    1575             :         Link *link;
    1576             : 
    1577           1 :         if (!m)
    1578           0 :                 return;
    1579             : 
    1580           1 :         free(m->state_file);
    1581             : 
    1582           1 :         while ((a = hashmap_first_key(m->dhcp6_prefixes)))
    1583           0 :                 (void) dhcp6_prefix_remove(m, a);
    1584           1 :         m->dhcp6_prefixes = hashmap_free(m->dhcp6_prefixes);
    1585             : 
    1586           7 :         while ((link = hashmap_steal_first(m->links))) {
    1587           6 :                 if (link->dhcp6_client)
    1588           0 :                         (void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
    1589             : 
    1590           6 :                 (void) link_stop_clients(link, true);
    1591             : 
    1592           6 :                 link_unref(link);
    1593             :         }
    1594             : 
    1595           6 :         m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
    1596           1 :         m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
    1597           1 :         m->links = hashmap_free_with_destructor(m->links, link_unref);
    1598             : 
    1599           1 :         m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
    1600           3 :         m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
    1601             : 
    1602           1 :         m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
    1603             : 
    1604           5 :         while ((pool = m->address_pools))
    1605           4 :                 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           1 :         m->rules = set_free_with_destructor(m->rules, routing_policy_rule_free);
    1610           1 :         m->rules_foreign = set_free_with_destructor(m->rules_foreign, routing_policy_rule_free);
    1611           1 :         set_free_with_destructor(m->rules_saved, routing_policy_rule_free);
    1612             : 
    1613           1 :         sd_netlink_unref(m->rtnl);
    1614           1 :         sd_netlink_unref(m->genl);
    1615           1 :         sd_resolve_unref(m->resolve);
    1616             : 
    1617           1 :         sd_event_source_unref(m->speed_meter_event_source);
    1618           1 :         sd_event_unref(m->event);
    1619             : 
    1620           1 :         sd_device_monitor_unref(m->device_monitor);
    1621             : 
    1622           1 :         bus_verify_polkit_async_registry_free(m->polkit_registry);
    1623           1 :         sd_bus_flush_close_unref(m->bus);
    1624             : 
    1625           1 :         free(m->dynamic_timezone);
    1626           1 :         free(m->dynamic_hostname);
    1627             : 
    1628           1 :         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           1 : int manager_load_config(Manager *m) {
    1654             :         int r;
    1655             : 
    1656             :         /* update timestamp */
    1657           1 :         paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, true);
    1658             : 
    1659           1 :         r = netdev_load(m);
    1660           1 :         if (r < 0)
    1661           0 :                 return r;
    1662             : 
    1663           1 :         r = network_load(m);
    1664           1 :         if (r < 0)
    1665           0 :                 return r;
    1666             : 
    1667           1 :         return 0;
    1668             : }
    1669             : 
    1670           1 : bool manager_should_reload(Manager *m) {
    1671           1 :         return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
    1672             : }
    1673             : 
    1674           1 : int manager_rtnl_enumerate_links(Manager *m) {
    1675           1 :         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
    1676             :         sd_netlink_message *link;
    1677             :         int r;
    1678             : 
    1679           1 :         assert(m);
    1680           1 :         assert(m->rtnl);
    1681             : 
    1682           1 :         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
    1683           1 :         if (r < 0)
    1684           0 :                 return r;
    1685             : 
    1686           1 :         r = sd_netlink_message_request_dump(req, true);
    1687           1 :         if (r < 0)
    1688           0 :                 return r;
    1689             : 
    1690           1 :         r = sd_netlink_call(m->rtnl, req, 0, &reply);
    1691           1 :         if (r < 0)
    1692           0 :                 return r;
    1693             : 
    1694           7 :         for (link = reply; link; link = sd_netlink_message_next(link)) {
    1695             :                 int k;
    1696             : 
    1697           6 :                 m->enumerating = true;
    1698             : 
    1699           6 :                 k = manager_rtnl_process_link(m->rtnl, link, m);
    1700           6 :                 if (k < 0)
    1701           0 :                         r = k;
    1702             : 
    1703           6 :                 m->enumerating = false;
    1704             :         }
    1705             : 
    1706           1 :         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           5 : void manager_dirty(Manager *manager) {
    1913           5 :         assert(manager);
    1914             : 
    1915             :         /* the serialized state in /run is no longer up-to-date */
    1916           5 :         manager->dirty = true;
    1917           5 : }
    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