]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: split out common part of route or address handlers
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 7 May 2021 08:32:51 +0000 (17:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 May 2021 02:26:06 +0000 (11:26 +0900)
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-ipv4ll.c
src/network/networkd-ndisc.c
src/network/networkd-route.c
src/network/networkd-route.h

index 262cfb47130dc4ac4cef0a652b99502f78832267..7220b108cae381f3865871909098f7f158b85564 100644 (file)
@@ -577,25 +577,6 @@ static void log_address_debug(const Address *address, const char *str, const Lin
                        preferred_str ? "for " : "forever", strempty(preferred_str));
 }
 
-static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
-        int r;
-
-        assert(m);
-        assert(link);
-        assert(link->ifname);
-
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EADDRNOTAVAIL)
-                log_link_message_warning_errno(link, m, r, "Could not drop address");
-        else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
-
-        return 1;
-}
-
 static int address_set_netlink_message(const Address *address, sd_netlink_message *req, Link *link) {
         int r;
 
@@ -627,6 +608,30 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
         return 0;
 }
 
+int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+        int r;
+
+        assert(rtnl);
+        assert(m);
+        assert(link);
+        assert(error_msg);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 0;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0 && r != -EADDRNOTAVAIL)
+                log_link_message_warning_errno(link, m, r, error_msg);
+        else if (r >= 0)
+                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+
+        return 1;
+}
+
+static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        return address_remove_handler_internal(rtnl, m, link, "Could not drop address");
+}
+
 int address_remove(
                 const Address *address,
                 Link *link,
@@ -792,21 +797,14 @@ int link_drop_foreign_addresses(Link *link) {
 static int remove_static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
-        assert(m);
         assert(link);
-        assert(link->ifname);
         assert(link->address_remove_messages > 0);
 
         link->address_remove_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EADDRNOTAVAIL)
-                log_link_message_warning_errno(link, m, r, "Could not drop address");
-        else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_remove_handler_internal(rtnl, m, link, "Could not drop address, ignoring");
+        if (r <= 0)
+                return r;
 
         if (link->address_remove_messages == 0 && link->request_static_addresses) {
                 link_set_state(link, LINK_STATE_CONFIGURING);
@@ -902,6 +900,28 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
         return 1;
 }
 
+int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+        int r;
+
+        assert(rtnl);
+        assert(m);
+        assert(link);
+        assert(error_msg);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 0;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_link_message_warning_errno(link, m, r, error_msg);
+                link_enter_failed(link);
+                return 0;
+        } else if (r >= 0)
+                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+
+        return 1;
+}
+
 static int ipv4_dad_configure(Address *address);
 
 int address_configure(
@@ -1046,24 +1066,14 @@ static int static_address_ready_callback(Address *address) {
 static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
-        assert(rtnl);
-        assert(m);
         assert(link);
-        assert(link->ifname);
         assert(link->address_messages > 0);
 
         link->address_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
+        if (r <= 0)
+                return r;
 
         if (link->address_messages == 0) {
                 Address *a;
index d05d37da3b26b03c9c226dc08c7eb85c3bbb50b0..e6a564714b2b48bb55f181c6e9d55bd089ea528f 100644 (file)
@@ -51,7 +51,9 @@ typedef struct Address {
 int address_new(Address **ret);
 Address *address_free(Address *address);
 int address_get(Link *link, const Address *in, Address **ret);
+int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
 int address_configure(const Address *address, Link *link, link_netlink_message_handler_t callback, Address **ret);
+int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
 int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
 bool address_equal(const Address *a1, const Address *a2);
 bool address_is_ready(const Address *a);
index 01c5fcabd4cee7114dffd176629b504c27ddb0cd..4a347f562785491c60cd5489fac812550bf4cc1e 100644 (file)
@@ -670,21 +670,17 @@ static int dhcp_reset_hostname(Link *link) {
         return 0;
 }
 
-static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
-        assert(m);
         assert(link);
         assert(link->dhcp4_remove_messages > 0);
 
         link->dhcp4_remove_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -ESRCH)
-                log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 route, ignoring");
+        r = link_route_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 route, ignoring");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp4_remove_messages == 0) {
                 r = dhcp4_update_address(link, false);
@@ -695,23 +691,17 @@ static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, L
         return 1;
 }
 
-static int dhcp4_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+static int dhcp4_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
-        assert(m);
         assert(link);
         assert(link->dhcp4_remove_messages > 0);
 
         link->dhcp4_remove_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EADDRNOTAVAIL)
-                log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
-        else
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 address, ignoring");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp4_remove_messages == 0) {
                 r = dhcp4_update_address(link, false);
@@ -729,7 +719,7 @@ static int dhcp4_remove_all(Link *link) {
         assert(link);
 
         SET_FOREACH(route, link->dhcp_routes) {
-                k = route_remove(route, NULL, link, dhcp4_remove_route_handler);
+                k = route_remove(route, NULL, link, dhcp4_route_remove_handler);
                 if (k < 0)
                         r = k;
                 else
@@ -737,7 +727,7 @@ static int dhcp4_remove_all(Link *link) {
         }
 
         if (link->dhcp_address) {
-                k = address_remove(link->dhcp_address, link, dhcp4_remove_address_handler);
+                k = address_remove(link->dhcp_address, link, dhcp4_address_remove_handler);
                 if (k < 0)
                         r = k;
                 else
@@ -958,23 +948,14 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
 
         assert(link);
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
+        if (r <= 0)
+                return r;
 
         if (address_is_ready(link->dhcp_address)) {
                 r = dhcp4_address_ready_callback(link->dhcp_address);
-                if (r < 0) {
+                if (r < 0)
                         link_enter_failed(link);
-                        return 1;
-                }
         } else
                 link->dhcp_address->callback = dhcp4_address_ready_callback;
 
index 7cc912890a01dabb6c3f86ab672519c5c7a621d9..5df1d52af176dc8c8d451bedb85d6d77c8dea98a 100644 (file)
@@ -229,7 +229,7 @@ int dhcp6_pd_remove(Link *link) {
         return r;
 }
 
-static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
+static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(link);
@@ -237,15 +237,9 @@ static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *l
 
         link->dhcp6_pd_route_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Failed to add DHCPv6 Prefix Delegation route");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, "Failed to add DHCPv6 Prefix Delegation route");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp6_pd_route_messages == 0) {
                 log_link_debug(link, "DHCPv6 prefix delegation routes set");
@@ -338,16 +332,9 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
 
         link->dhcp6_pd_address_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 delegated prefix address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 delegated prefix address");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp6_pd_address_messages == 0) {
                 log_link_debug(link, "DHCPv6 delegated prefix addresses set");
@@ -784,7 +771,7 @@ static int dhcp6_remove(Link *link) {
         return r;
 }
 
-static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
+static int dhcp6_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(link);
@@ -792,15 +779,9 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link
 
         link->dhcp6_route_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Failed to add unreachable route for DHCPv6 delegated subnet");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated subnet");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp6_route_messages == 0) {
                 log_link_debug(link, "Unreachable routes for DHCPv6 delegated subnets set");
@@ -1000,16 +981,9 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
 
         link->dhcp6_address_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address");
+        if (r <= 0)
+                return r;
 
         if (link->dhcp6_address_messages == 0) {
                 log_link_debug(link, "DHCPv6 addresses set");
index 5390c537993a8da5bc5220c74e785a2a08ad6f9c..f655a914f46fd2a025cf296b412b2be4a5bbf0fb 100644 (file)
@@ -49,13 +49,9 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
         assert(link);
         assert(!link->ipv4ll_address_configured);
 
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "could not set ipv4ll address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Could not set ipv4ll address");
+        if (r <= 0)
+                return r;
 
         link->ipv4ll_address_configured = true;
         link_check_ready(link);
index 87f55f557ca9c377400133a2c8ba9ea47618754a..2ecd36150cfe2607a557c5bcd11ec72bd503e66a 100644 (file)
@@ -305,15 +305,9 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
 
         link->ndisc_routes_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_error_errno(link, m, r, "Could not set NDisc route");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
+        if (r <= 0)
+                return r;
 
         if (link->ndisc_routes_messages == 0) {
                 log_link_debug(link, "NDisc routes set.");
@@ -402,16 +396,9 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
 
         link->ndisc_addresses_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_error_errno(link, m, r, "Could not set NDisc address");
-                link_enter_failed(link);
-                return 1;
-        } else if (r >= 0)
-                (void) manager_rtnl_process_address(rtnl, m, link->manager);
+        r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
+        if (r <= 0)
+                return r;
 
         if (link->ndisc_addresses_messages == 0) {
                 log_link_debug(link, "NDisc SLAAC addresses set.");
index 0ba1dcfe5cf6f990455537f00396b1e49a517296..07a70db5365f9f8c579b677b849d288942b42f6d 100644 (file)
@@ -882,18 +882,35 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
         return 0;
 }
 
-static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
         int r;
 
         assert(m);
+        assert(link);
+        assert(error_msg);
 
-        /* Note that link may be NULL. */
-        if (link && IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 0;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0 && r != -ESRCH)
+                log_link_message_warning_errno(link, m, r, error_msg);
+
+        return 1;
+}
+
+static int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        return link_route_remove_handler_internal(rtnl, m, link, "Could not drop route, ignoring");
+}
+
+static int manager_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Manager *manager) {
+        int r;
+
+        assert(m);
 
         r = sd_netlink_message_get_errno(m);
         if (r < 0 && r != -ESRCH)
-                log_link_message_warning_errno(link, m, r, "Could not drop route, ignoring");
+                log_message_warning_errno(m, r, "Could not drop route, ignoring");
 
         return 1;
 }
@@ -913,7 +930,6 @@ int route_remove(
 
         if (!manager)
                 manager = link->manager;
-        /* link may be NULL! */
 
         log_route_debug(route, "Removing", link, manager);
 
@@ -942,13 +958,21 @@ int route_remove(
         if (r < 0)
                 return r;
 
-        r = netlink_call_async(manager->rtnl, NULL, req,
-                               callback ?: route_remove_handler,
-                               link_netlink_destroy_callback, link);
-        if (r < 0)
-                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+        if (link) {
+                r = netlink_call_async(manager->rtnl, NULL, req,
+                                       callback ?: link_route_remove_handler,
+                                       link_netlink_destroy_callback, link);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
-        link_ref(link); /* link may be NULL, link_ref() is OK with that */
+                link_ref(link);
+        } else {
+                r = netlink_call_async(manager->rtnl, NULL, req,
+                                       manager_route_remove_handler,
+                                       NULL, manager);
+                if (r < 0)
+                        return log_error_errno(r, "Could not send rtnetlink message: %m");
+        }
 
         return 0;
 }
@@ -1233,6 +1257,26 @@ static int append_nexthops(const Route *route, sd_netlink_message *req) {
         return 0;
 }
 
+int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
+        int r;
+
+        assert(m);
+        assert(link);
+        assert(error_msg);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 0;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0 && r != -EEXIST) {
+                log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
+                link_enter_failed(link);
+                return 0;
+        }
+
+        return 1;
+}
+
 int route_configure(
                 const Route *route,
                 Link *link,
@@ -1374,15 +1418,9 @@ static int route_handler_with_gateway(sd_netlink *rtnl, sd_netlink_message *m, L
 
         link->route_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, "Could not set route with gateway");
+        if (r <= 0)
+                return r;
 
         if (link->route_messages == 0) {
                 log_link_debug(link, "Routes with gateway set");
@@ -1401,15 +1439,9 @@ static int route_handler_without_gateway(sd_netlink *rtnl, sd_netlink_message *m
 
         link->route_messages--;
 
-        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
-                return 1;
-
-        r = sd_netlink_message_get_errno(m);
-        if (r < 0 && r != -EEXIST) {
-                log_link_message_warning_errno(link, m, r, "Could not set route without gateway");
-                link_enter_failed(link);
-                return 1;
-        }
+        r = route_configure_handler_internal(rtnl, m, link, "Could not set route without gateway");
+        if (r <= 0)
+                return r;
 
         if (link->route_messages == 0) {
                 log_link_debug(link, "Routes set without gateway");
index 0cbeb44fcb20c26aa2dc1017093c4bf3d4be888c..bd8c08c1f6d874f8e9cec3c456d725a5c296ac88 100644 (file)
@@ -73,7 +73,9 @@ Route *route_free(Route *route);
 DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free);
 int route_dup(const Route *src, Route **ret);
 
+int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
 int route_configure(const Route *route, Link *link, link_netlink_message_handler_t callback, Route **ret);
+int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
 int route_remove(const Route *route, Manager *manager, Link *link, link_netlink_message_handler_t callback);
 
 int link_has_route(Link *link, const Route *route);