summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dao <dqminh89@gmail.com>2018-02-26 14:33:16 +0000
committerDaniel Dao <dqminh89@gmail.com>2018-03-12 11:36:25 +0000
commitf02ba163891bab73a80332b4599a9d73083cb6c2 (patch)
tree6cb5850a946f469b9fe65b9bc8148fefe4cdb0f2
parent332b0908370a1c5484df8084ea98743a25a24c50 (diff)
downloadsystemd-f02ba163891bab73a80332b4599a9d73083cb6c2.tar.gz
setup route expiration in kernel if supported
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>
-rw-r--r--src/basic/missing.h4
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c6
-rw-r--r--src/network/networkd-link.c2
-rw-r--r--src/network/networkd-route.c9
-rw-r--r--src/network/networkd-util.c21
-rw-r--r--src/network/networkd-util.h2
6 files changed, 41 insertions, 3 deletions
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 1cc3f08e48..567aea8da9 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -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
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 0ee7d6f0dc..dcee2d2a27 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -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 = {
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 64c45080df..cc9073fac3 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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)
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 70dca5219b..d25be44a10 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -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)
diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c
index b9c533fcc7..7ea14155b6 100644
--- a/src/network/networkd-util.c
+++ b/src/network/networkd-util.c
@@ -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;
+}
diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h
index 69ea93ad08..e8c3399937 100644
--- a/src/network/networkd-util.h
+++ b/src/network/networkd-util.h
@@ -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);