networkd: handle MTU field in IPv6 RA (#4719)
authorSusant Sahani <ssahani@users.noreply.github.com>
Wed, 23 Nov 2016 21:32:19 +0000 (03:02 +0530)
committerLennart Poettering <lennart@poettering.net>
Wed, 23 Nov 2016 21:32:19 +0000 (22:32 +0100)
This patch handles the custom MTU field in IPv6 RA.

fixes RFE #4464

src/libsystemd/sd-netlink/netlink-types.c
src/network/networkd-ndisc.c
src/network/networkd-route.c
src/network/networkd-route.h

index 1c10dd5..0f8b0cc 100644 (file)
@@ -500,6 +500,28 @@ static const NLTypeSystem rtnl_address_type_system = {
         .types = rtnl_address_types,
 };
 
+/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
+
+static const NLType rtnl_route_metrics_types[] = {
+        [RTAX_MTU]               = { .type = NETLINK_TYPE_U32 },
+        [RTAX_WINDOW]            = { .type = NETLINK_TYPE_U32 },
+        [RTAX_RTT]               = { .type = NETLINK_TYPE_U32 },
+        [RTAX_RTTVAR]            = { .type = NETLINK_TYPE_U32 },
+        [RTAX_SSTHRESH]          = { .type = NETLINK_TYPE_U32 },
+        [RTAX_CWND]              = { .type = NETLINK_TYPE_U32 },
+        [RTAX_ADVMSS]            = { .type = NETLINK_TYPE_U32 },
+        [RTAX_REORDERING]        = { .type = NETLINK_TYPE_U32 },
+        [RTAX_HOPLIMIT]          = { .type = NETLINK_TYPE_U32 },
+        [RTAX_INITCWND]          = { .type = NETLINK_TYPE_U32 },
+        [RTAX_FEATURES]          = { .type = NETLINK_TYPE_U32 },
+        [RTAX_RTO_MIN]           = { .type = NETLINK_TYPE_U32 },
+};
+
+static const NLTypeSystem rtnl_route_metrics_type_system = {
+        .count = ELEMENTSOF(rtnl_route_metrics_types),
+        .types = rtnl_route_metrics_types,
+};
+
 static const NLType rtnl_route_types[] = {
         [RTA_DST]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
         [RTA_SRC]               = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
@@ -508,9 +530,8 @@ static const NLType rtnl_route_types[] = {
         [RTA_GATEWAY]           = { .type = NETLINK_TYPE_IN_ADDR },
         [RTA_PRIORITY]          = { .type = NETLINK_TYPE_U32 },
         [RTA_PREFSRC]           = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */
-/*
-        [RTA_METRICS]           = { .type = NETLINK_TYPE_NESTED },
-        [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
+        [RTA_METRICS]           = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system},
+/*      [RTA_MULTIPATH]         = { .len = sizeof(struct rtnexthop) },
 */
         [RTA_FLOW]              = { .type = NETLINK_TYPE_U32 }, /* 6? */
 /*
index 70283e5..5320592 100644 (file)
@@ -56,6 +56,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         struct in6_addr gateway;
         uint16_t lifetime;
         unsigned preference;
+        uint32_t mtu;
         usec_t time_now;
         int r;
         Address *address;
@@ -116,6 +117,12 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
                 return;
         }
 
+        r = sd_ndisc_router_get_mtu(rt, &mtu);
+        if (r < 0) {
+                log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m");
+                return;
+        }
+
         r = route_new(&route);
         if (r < 0) {
                 log_link_error_errno(link, r, "Could not allocate route: %m");
@@ -128,6 +135,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         route->pref = preference;
         route->gw.in6 = gateway;
         route->lifetime = time_now + lifetime * USEC_PER_SEC;
+        route->mtu = mtu;
 
         r = route_configure(route, link, ndisc_netlink_handler);
         if (r < 0) {
index f78e106..bde26a4 100644 (file)
@@ -605,6 +605,20 @@ int route_configure(
         if (r < 0)
                 return log_error_errno(r, "Could not append RTA_OIF attribute: %m");
 
+        r = sd_netlink_message_open_container(req, RTA_METRICS);
+        if (r < 0)
+                return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+
+        if (route->mtu > 0) {
+                r = sd_netlink_message_append_u32(req, RTAX_MTU, route->mtu);
+                if (r < 0)
+                        return log_error_errno(r, "Could not append RTAX_MTU attribute: %m");
+        }
+
+        r = sd_netlink_message_close_container(req);
+        if (r < 0)
+                return log_error_errno(r, "Could not append RTA_METRICS attribute: %m");
+
         r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
         if (r < 0)
                 return log_error_errno(r, "Could not send rtnetlink message: %m");
index d4e4dba..02f0b27 100644 (file)
@@ -37,6 +37,7 @@ struct Route {
         unsigned char tos;
         uint32_t priority; /* note that ip(8) calls this 'metric' */
         uint32_t table;
+        uint32_t mtu;
         unsigned char pref;
         unsigned flags;