]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
setup route expiration in kernel if supported 8106/head
authorDaniel Dao <dqminh89@gmail.com>
Mon, 26 Feb 2018 14:33:16 +0000 (14:33 +0000)
committerDaniel Dao <dqminh89@gmail.com>
Mon, 12 Mar 2018 11:36:25 +0000 (11:36 +0000)
kernel >= 4.5 (with commit https://github.com/torvalds/linux/commit/32bc201e1974976b7d3fea9a9b17bb7392ca6394) supports
RTA_EXPIRES netlink attribute to set router lifetime. This simply detect
the kernel version (>=4.5) and set the lifetime properly, fallback to
expiring route in userspace for kernel that doesnt support it.

Signed-off-by: Daniel Dao <dqminh89@gmail.com>
src/basic/missing.h
src/libsystemd/sd-netlink/netlink-types.c
src/network/networkd-link.c
src/network/networkd-route.c
src/network/networkd-util.c
src/network/networkd-util.h

index 1cc3f08e489326d4d624de91b315a10ed4bb6a4d..567aea8da9c3c4178e16ecb77101bc3afd333774 100644 (file)
@@ -1058,6 +1058,10 @@ struct input_mask {
 #define RTAX_QUICKACK 15
 #endif
 
+#ifndef RTA_EXPIRES
+#define RTA_EXPIRES 23
+#endif
+
 #ifndef IPV6_UNICAST_IF
 #define IPV6_UNICAST_IF 76
 #endif
index 0ee7d6f0dcc0d7b25ec75c31b180f39301bc91c0..dcee2d2a275653d824119242e344de00b89ac606 100644 (file)
@@ -582,7 +582,11 @@ static const NLType rtnl_route_types[] = {
         RTA_NEWDST,
 */
         [RTA_PREF]              = { .type = NETLINK_TYPE_U8 },
-
+/*
+        RTA_ENCAP_TYPE,
+        RTA_ENCAP,
+ */
+        [RTA_EXPIRES]           = { .type = NETLINK_TYPE_U32 },
 };
 
 static const NLTypeSystem rtnl_route_type_system = {
index 64c45080dfaa9ec18619fa707000325547103068..cc9073fac387149df5fed5f370090d301ce1762a 100644 (file)
@@ -2964,7 +2964,7 @@ network_file_fail:
                         if (r < 0)
                                 return log_link_error_errno(link, r, "Failed to add route: %m");
 
-                        if (lifetime != USEC_INFINITY) {
+                        if (lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
                                 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), lifetime,
                                                       0, route_expire_handler, route);
                                 if (r < 0)
index 70dca5219baea67c61ca6378d0e5a9c7e9ea3740..d25be44a100af42f3da0bb9ebb6fcbc56b59c6f0 100644 (file)
@@ -617,6 +617,13 @@ int route_configure(
         if (r < 0)
                 return log_error_errno(r, "Could not append RTA_PREF attribute: %m");
 
+        if (route->lifetime != USEC_INFINITY && kernel_route_expiration_supported()) {
+                r = sd_netlink_message_append_u32(req, RTA_EXPIRES,
+                        DIV_ROUND_UP(usec_sub_unsigned(route->lifetime, now(clock_boottime_or_monotonic())), USEC_PER_SEC));
+                if (r < 0)
+                        return log_error_errno(r, "Could not append RTA_EXPIRES attribute: %m");
+        }
+
         r = sd_rtnl_message_route_set_type(req, route->type);
         if (r < 0)
                 return log_error_errno(r, "Could not set route type: %m");
@@ -674,7 +681,7 @@ int route_configure(
         /* TODO: drop expiration handling once it can be pushed into the kernel */
         route->lifetime = lifetime;
 
-        if (route->lifetime != USEC_INFINITY) {
+        if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
                 r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(),
                                       route->lifetime, 0, route_expire_handler, route);
                 if (r < 0)
index b9c533fcc7cf7455f4b4c013e89f6e9122bca325..7ea14155b60beaa8633bf6f232c833708e16e42d 100644 (file)
@@ -18,6 +18,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "condition.h"
 #include "conf-parser.h"
 #include "networkd-util.h"
 #include "parse-util.h"
@@ -99,3 +100,23 @@ int config_parse_address_family_boolean_with_kernel(
 
         return 0;
 }
+
+/* Router lifetime can be set with netlink interface since kernel >= 4.5
+ * so for the supported kernel we dont need to expire routes in userspace */
+int kernel_route_expiration_supported(void) {
+        static int cached = -1;
+        int r;
+
+        if (cached < 0) {
+                Condition c = {
+                        .type = CONDITION_KERNEL_VERSION,
+                        .parameter = (char *) ">= 4.5"
+                };
+                r = condition_test(&c);
+                if (r < 0)
+                        return r;
+
+                cached = r;
+        }
+        return cached;
+}
index 69ea93ad08014c27a0934e3940f14bb232d14ec6..e8c33999377d3e190c41c1376f785611f22a6f70 100644 (file)
@@ -37,3 +37,5 @@ int config_parse_address_family_boolean_with_kernel(const char* unit, const char
 
 const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
 AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_;
+
+int kernel_route_expiration_supported(void);