chiark / gitweb /
test: always use assert_se in tests
[elogind.git] / src / network / networkd-manager.c
index 1b3e71ab0eb7ac6a180cb200213c6bb0893355ba..55e5cafd00bcd6a248c2e583903d4cf958706f89 100644 (file)
@@ -27,6 +27,7 @@
 #include "udev-util.h"
 #include "rtnl-util.h"
 #include "mkdir.h"
+#include "virt.h"
 
 const char* const network_dirs[] = {
         "/etc/systemd/network",
@@ -51,7 +52,7 @@ int manager_new(Manager **ret) {
 
         sd_event_set_watchdog(m->event, true);
 
-        r = sd_rtnl_open(RTMGRP_LINK | RTMGRP_IPV4_IFADDR, &m->rtnl);
+        r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
         if (r < 0)
                 return r;
 
@@ -63,9 +64,18 @@ int manager_new(Manager **ret) {
         if (!m->udev)
                 return -ENOMEM;
 
-        m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
-        if (!m->udev_monitor)
-                return -ENOMEM;
+        /* udev does not initialize devices inside containers,
+         * so we rely on them being already initialized before
+         * entering the container */
+        if (detect_container(NULL) > 0) {
+                m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "kernel");
+                if (!m->udev_monitor)
+                        return -ENOMEM;
+        } else {
+                m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
+                if (!m->udev_monitor)
+                        return -ENOMEM;
+        }
 
         m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
         if (!m->links)
@@ -85,9 +95,12 @@ int manager_new(Manager **ret) {
 
 void manager_free(Manager *m) {
         Network *network;
-        Netdev *netdev;
+        NetDev *netdev;
         Link *link;
 
+        if (!m)
+                return;
+
         udev_monitor_unref(m->udev_monitor);
         udev_unref(m->udev);
         sd_bus_unref(m->bus);
@@ -132,30 +145,31 @@ bool manager_should_reload(Manager *m) {
 }
 
 static int manager_process_link(Manager *m, struct udev_device *device) {
-        Link *link;
+        Link *link = NULL;
         int r;
 
-        if (streq_ptr(udev_device_get_action(device), "remove")) {
-                uint64_t ifindex;
+        assert(m);
+        assert(device);
+
+        link_get(m, udev_device_get_ifindex(device), &link);
 
+        if (streq_ptr(udev_device_get_action(device), "remove")) {
                 log_debug("%s: link removed", udev_device_get_sysname(device));
 
-                ifindex = udev_device_get_ifindex(device);
-                link = hashmap_get(m->links, &ifindex);
-                if (!link)
+                if (link)
+                        link_free(link);
+        } else {
+                if (link) {
+                        log_debug("%s: link already exists, ignoring",
+                                  link->ifname);
                         return 0;
+                }
 
-                link_free(link);
-        } else {
                 r = link_add(m, device, &link);
                 if (r < 0) {
-                        if (r == -EEXIST)
-                                log_debug("%s: link already exists, ignoring",
-                                          link->ifname);
-                        else
-                                log_error("%s: could not handle link: %s",
-                                          udev_device_get_sysname(device),
-                                          strerror(-r));
+                        log_error("%s: could not handle link: %s",
+                                  udev_device_get_sysname(device),
+                                  strerror(-r));
                 } else
                         log_debug("%s: link (with ifindex %" PRIu64") added",
                                   link->ifname, link->ifindex);
@@ -179,9 +193,14 @@ int manager_udev_enumerate_links(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = udev_enumerate_add_match_is_initialized(e);
-        if (r < 0)
-                return r;
+        /* udev does not initialize devices inside containers,
+         * so we rely on them being already initialized before
+         * entering the container */
+        if (detect_container(NULL) <= 0) {
+                r = udev_enumerate_add_match_is_initialized(e);
+                if (r < 0)
+                        return r;
+        }
 
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
@@ -233,9 +252,10 @@ int manager_udev_listen(Manager *m) {
         }
 
         r = sd_event_add_io(m->event,
+                        &m->udev_event_source,
                         udev_monitor_get_fd(m->udev_monitor),
                         EPOLLIN, manager_dispatch_link_udev,
-                        m, &m->udev_event_source);
+                        m);
         if (r < 0)
                 return r;
 
@@ -246,9 +266,12 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
         Manager *m = userdata;
         Link *link;
         const char *name;
-        uint64_t ifindex_64;
         int r, ifindex;
 
+        assert(rtnl);
+        assert(message);
+        assert(m);
+
         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
         if (r < 0 || ifindex <= 0) {
                 log_debug("received RTM_NEWLINK message without valid ifindex");
@@ -259,7 +282,7 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
         if (r < 0)
                 log_debug("received RTM_NEWLINK message without valid IFLA_IFNAME");
         else {
-                Netdev *netdev;
+                NetDev *netdev;
 
                 r = netdev_get(m, name, &netdev);
                 if (r >= 0) {
@@ -270,9 +293,8 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
                 }
         }
 
-        ifindex_64 = ifindex;
-        link = hashmap_get(m->links, &ifindex_64);
-        if (!link) {
+        r = link_get(m, ifindex, &link);
+        if (r < 0) {
                 log_debug("received RTM_NEWLINK message for untracked ifindex %d", ifindex);
                 return 0;
         }