]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: refuse to configure address or route with 0 valid lifetime 24001/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 13 Jul 2022 17:39:56 +0000 (02:39 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 14 Jul 2022 12:00:05 +0000 (21:00 +0900)
Fixes #23625.

src/network/networkd-address.c
src/network/networkd-route.c

index ba936d932a4526eec449887943fec7032760d1ab..a60cd746a4bab8f2720cafa7b7ef947463eadf9c 100644 (file)
@@ -212,7 +212,7 @@ void address_set_broadcast(Address *a, Link *link) {
         a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
 }
 
-static struct ifa_cacheinfo *address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {
+static void address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {
         usec_t now_usec;
 
         assert(m);
@@ -225,8 +225,6 @@ static struct ifa_cacheinfo *address_set_cinfo(Manager *m, const Address *a, str
                 .ifa_valid = usec_to_sec(a->lifetime_valid_usec, now_usec),
                 .ifa_prefered = usec_to_sec(a->lifetime_preferred_usec, now_usec),
         };
-
-        return cinfo;
 }
 
 static void address_set_lifetime(Manager *m, Address *a, const struct ifa_cacheinfo *cinfo) {
@@ -1030,12 +1028,13 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
         return 1;
 }
 
-static int address_configure(const Address *address, Link *link, Request *req) {
+static int address_configure(const Address *address, const struct ifa_cacheinfo *c, Link *link, Request *req) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
 
         assert(address);
         assert(IN_SET(address->family, AF_INET, AF_INET6));
+        assert(c);
         assert(link);
         assert(link->ifindex > 0);
         assert(link->manager);
@@ -1072,8 +1071,7 @@ static int address_configure(const Address *address, Link *link, Request *req) {
                         return r;
         }
 
-        r = sd_netlink_message_append_cache_info(m, IFA_CACHEINFO,
-                                                 address_set_cinfo(link->manager, address, &(struct ifa_cacheinfo) {}));
+        r = sd_netlink_message_append_cache_info(m, IFA_CACHEINFO, c);
         if (r < 0)
                 return r;
 
@@ -1102,6 +1100,7 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) {
 }
 
 static int address_process_request(Request *req, Link *link, Address *address) {
+        struct ifa_cacheinfo c;
         int r;
 
         assert(req);
@@ -1111,7 +1110,16 @@ static int address_process_request(Request *req, Link *link, Address *address) {
         if (!address_is_ready_to_configure(link, address))
                 return 0;
 
-        r = address_configure(address, link, req);
+        address_set_cinfo(link->manager, address, &c);
+        if (c.ifa_valid == 0) {
+                log_link_debug(link, "Refuse to configure %s address %s, as its valid lifetime is zero.",
+                               network_config_source_to_string(address->source),
+                               IN_ADDR_PREFIX_TO_STRING(address->family, &address->in_addr, address->prefixlen));
+                address_cancel_requesting(address);
+                return 1;
+        }
+
+        r = address_configure(address, &c, link, req);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to configure address: %m");
 
index 8ab5aaf0dbe35b4e9e0d9b4cb0c9bcbca29a2748..921b031b2963c3507412e020a5f72a44ca5578ce 100644 (file)
@@ -1153,7 +1153,7 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
         return 1;
 }
 
-static int route_configure(const Route *route, Link *link, Request *req) {
+static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link, Request *req) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
 
@@ -1179,17 +1179,10 @@ static int route_configure(const Route *route, Link *link, Request *req) {
         if (r < 0)
                 return r;
 
-        if (route->lifetime_usec != USEC_INFINITY) {
-                usec_t now_usec;
-                uint32_t sec;
-
-                assert_se(sd_event_now(link->manager->event, CLOCK_BOOTTIME, &now_usec) >= 0);
-                sec = usec_to_sec(route->lifetime_usec, now_usec);
-                if (sec != UINT32_MAX) {
-                        r = sd_netlink_message_append_u32(m, RTA_EXPIRES, sec);
-                        if (r < 0)
-                                return r;
-                }
+        if (lifetime_sec != UINT32_MAX) {
+                r = sd_netlink_message_append_u32(m, RTA_EXPIRES, lifetime_sec);
+                if (r < 0)
+                        return r;
         }
 
         if (route->ttl_propagate >= 0) {
@@ -1324,6 +1317,7 @@ static int route_process_request(Request *req, Link *link, Route *route) {
 
         assert(req);
         assert(link);
+        assert(link->manager);
         assert(route);
 
         r = route_is_ready_to_configure(route, link);
@@ -1362,7 +1356,25 @@ static int route_process_request(Request *req, Link *link, Route *route) {
                 }
         }
 
-        r = route_configure(route, link, req);
+        usec_t now_usec;
+        assert_se(sd_event_now(link->manager->event, CLOCK_BOOTTIME, &now_usec) >= 0);
+        uint32_t sec = usec_to_sec(route->lifetime_usec, now_usec);
+        if (sec == 0) {
+                log_link_debug(link, "Refuse to configure %s route with zero lifetime.",
+                               network_config_source_to_string(route->source));
+
+                if (converted)
+                        for (size_t i = 0; i < converted->n; i++) {
+                                Route *existing;
+
+                                assert_se(route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) >= 0);
+                                route_cancel_requesting(existing);
+                        }
+                else
+                        route_cancel_requesting(route);
+        }
+
+        r = route_configure(route, sec, link, req);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to configure route: %m");