]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce helper function to enumerate information using netlink
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 29 Sep 2020 07:44:41 +0000 (16:44 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Oct 2020 17:39:13 +0000 (02:39 +0900)
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd.c
src/network/test-network.c

index faea2356b5ef465479755e75d1d8aeaf487cb90b..2dc6ef09338e4b47cb9e503458070fb913f9cdd0 100644 (file)
@@ -1689,33 +1689,41 @@ bool manager_should_reload(Manager *m) {
         return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
 }
 
-int manager_rtnl_enumerate_links(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *link;
+static int manager_enumerate_internal(
+                Manager *m,
+                sd_netlink_message *req,
+                int (*process)(sd_netlink *, sd_netlink_message *, Manager *),
+                const char *name) {
+
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *reply = NULL;
         int r;
 
         assert(m);
         assert(m->rtnl);
-
-        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
-        if (r < 0)
-                return r;
+        assert(req);
+        assert(process);
 
         r = sd_netlink_message_request_dump(req, true);
         if (r < 0)
                 return r;
 
         r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0)
+        if (r < 0) {
+                if (r == -EOPNOTSUPP && name) {
+                        log_debug_errno(r, "%s are not supported by the kernel. Ignoring.", name);
+                        return 0;
+                }
+
                 return r;
+        }
 
-        for (link = reply; link; link = sd_netlink_message_next(link)) {
+        for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) {
                 int k;
 
                 m->enumerating = true;
 
-                k = manager_rtnl_process_link(m->rtnl, link, m);
-                if (k < 0)
+                k = process(m->rtnl, reply_one, m);
+                if (k < 0 && r >= 0)
                         r = k;
 
                 m->enumerating = false;
@@ -1724,44 +1732,36 @@ int manager_rtnl_enumerate_links(Manager *m) {
         return r;
 }
 
-int manager_rtnl_enumerate_addresses(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *addr;
+static int manager_enumerate_links(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
         assert(m);
         assert(m->rtnl);
 
-        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
-        if (r < 0)
-                return r;
-
-        r = sd_netlink_message_request_dump(req, true);
-        if (r < 0)
-                return r;
-
-        r = sd_netlink_call(m->rtnl, req, 0, &reply);
+        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
         if (r < 0)
                 return r;
 
-        for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
-                int k;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_link, NULL);
+}
 
-                m->enumerating = true;
+static int manager_enumerate_addresses(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
 
-                k = manager_rtnl_process_address(m->rtnl, addr, m);
-                if (k < 0)
-                        r = k;
+        assert(m);
+        assert(m->rtnl);
 
-                m->enumerating = false;
-        }
+        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
+        if (r < 0)
+                return r;
 
-        return r;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_address, NULL);
 }
 
-int manager_rtnl_enumerate_neighbors(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *neigh;
+static int manager_enumerate_neighbors(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
         assert(m);
@@ -1771,32 +1771,11 @@ int manager_rtnl_enumerate_neighbors(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = sd_netlink_message_request_dump(req, true);
-        if (r < 0)
-                return r;
-
-        r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0)
-                return r;
-
-        for (neigh = reply; neigh; neigh = sd_netlink_message_next(neigh)) {
-                int k;
-
-                m->enumerating = true;
-
-                k = manager_rtnl_process_neighbor(m->rtnl, neigh, m);
-                if (k < 0)
-                        r = k;
-
-                m->enumerating = false;
-        }
-
-        return r;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_neighbor, NULL);
 }
 
-int manager_rtnl_enumerate_routes(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *route;
+static int manager_enumerate_routes(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
         assert(m);
@@ -1809,32 +1788,11 @@ int manager_rtnl_enumerate_routes(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = sd_netlink_message_request_dump(req, true);
-        if (r < 0)
-                return r;
-
-        r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0)
-                return r;
-
-        for (route = reply; route; route = sd_netlink_message_next(route)) {
-                int k;
-
-                m->enumerating = true;
-
-                k = manager_rtnl_process_route(m->rtnl, route, m);
-                if (k < 0)
-                        r = k;
-
-                m->enumerating = false;
-        }
-
-        return r;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_route, NULL);
 }
 
-int manager_rtnl_enumerate_rules(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *rule;
+static int manager_enumerate_rules(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
         assert(m);
@@ -1844,38 +1802,11 @@ int manager_rtnl_enumerate_rules(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = sd_netlink_message_request_dump(req, true);
-        if (r < 0)
-                return r;
-
-        r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0) {
-                if (r == -EOPNOTSUPP) {
-                        log_debug("FIB Rules are not supported by the kernel. Ignoring.");
-                        return 0;
-                }
-
-                return r;
-        }
-
-        for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
-                int k;
-
-                m->enumerating = true;
-
-                k = manager_rtnl_process_rule(m->rtnl, rule, m);
-                if (k < 0)
-                        r = k;
-
-                m->enumerating = false;
-        }
-
-        return r;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_rule, "Routing policy rules");
 }
 
-int manager_rtnl_enumerate_nexthop(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        sd_netlink_message *nexthop;
+static int manager_enumerate_nexthop(Manager *m) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
         assert(m);
@@ -1885,33 +1816,37 @@ int manager_rtnl_enumerate_nexthop(Manager *m) {
         if (r < 0)
                 return r;
 
-        r = sd_netlink_message_request_dump(req, true);
-        if (r < 0)
-                return r;
+        return manager_enumerate_internal(m, req, manager_rtnl_process_nexthop, "Nexthop rules");
+}
 
-        r = sd_netlink_call(m->rtnl, req, 0, &reply);
-        if (r < 0) {
-                if (r == -EOPNOTSUPP) {
-                        log_debug("Nexthop are not supported by the kernel. Ignoring.");
-                        return 0;
-                }
+int manager_enumerate(Manager *m) {
+        int r;
 
-                return r;
-        }
+        r = manager_enumerate_links(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate links: %m");
 
-        for (nexthop = reply; nexthop; nexthop = sd_netlink_message_next(nexthop)) {
-                int k;
+        r = manager_enumerate_addresses(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate addresses: %m");
 
-                m->enumerating = true;
+        r = manager_enumerate_neighbors(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate neighbors: %m");
 
-                k = manager_rtnl_process_nexthop(m->rtnl, nexthop, m);
-                if (k < 0)
-                        r = k;
+        r = manager_enumerate_routes(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate routes: %m");
 
-                m->enumerating = false;
-        }
+        r = manager_enumerate_rules(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate routing policy rules: %m");
 
-        return r;
+        r = manager_enumerate_nexthop(m);
+        if (r < 0)
+                return log_error_errno(r, "Could not enumerate nexthop rules: %m");
+
+        return 0;
 }
 
 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
index 1b6b7f785dd0e36583ed4b555191b1a4ccfba13c..602ae919e949352dc73afa8c1419bd55fe06ba63 100644 (file)
@@ -82,12 +82,7 @@ int manager_start(Manager *m);
 int manager_load_config(Manager *m);
 bool manager_should_reload(Manager *m);
 
-int manager_rtnl_enumerate_links(Manager *m);
-int manager_rtnl_enumerate_addresses(Manager *m);
-int manager_rtnl_enumerate_neighbors(Manager *m);
-int manager_rtnl_enumerate_routes(Manager *m);
-int manager_rtnl_enumerate_rules(Manager *m);
-int manager_rtnl_enumerate_nexthop(Manager *m);
+int manager_enumerate(Manager *m);
 
 int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
 
index 445aee16ad0435b4f7361cb6098dac5d859837dc..f78ff9db547024b9071960d4d1a6a4bd39e812f8 100644 (file)
@@ -88,29 +88,9 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return log_error_errno(r, "Could not load configuration files: %m");
 
-        r = manager_rtnl_enumerate_links(m);
+        r = manager_enumerate(m);
         if (r < 0)
-                return log_error_errno(r, "Could not enumerate links: %m");
-
-        r = manager_rtnl_enumerate_addresses(m);
-        if (r < 0)
-                return log_error_errno(r, "Could not enumerate addresses: %m");
-
-        r = manager_rtnl_enumerate_neighbors(m);
-        if (r < 0)
-                return log_error_errno(r, "Could not enumerate neighbors: %m");
-
-        r = manager_rtnl_enumerate_routes(m);
-        if (r < 0)
-                return log_error_errno(r, "Could not enumerate routes: %m");
-
-        r = manager_rtnl_enumerate_rules(m);
-        if (r < 0)
-                return log_error_errno(r, "Could not enumerate rules: %m");
-
-        r = manager_rtnl_enumerate_nexthop(m);
-        if (r < 0)
-                return log_error_errno(r, "Could not enumerate nexthop: %m");
+                return r;
 
         r = manager_start(m);
         if (r < 0)
index 2ac47e72f523b4d4f1fb6fc4c06a6ee67c54d64a..eeb756ca0435f3e0d0807f7576c04f78e9cc3cab 100644 (file)
@@ -252,6 +252,6 @@ int main(void) {
 
         test_network_get(manager, loopback);
 
-        assert_se(manager_rtnl_enumerate_links(manager) >= 0);
+        assert_se(manager_enumerate(manager) >= 0);
         return 0;
 }