]> granicus.if.org Git - libnl/commitdiff
route: Add support for ttl propagation in MPLS routes
authorDavid Ahern <dsahern@gmail.com>
Thu, 17 Aug 2017 22:59:33 +0000 (15:59 -0700)
committerThomas Haller <thaller@redhat.com>
Fri, 18 Aug 2017 13:01:04 +0000 (15:01 +0200)
Add support for RTA_TTL_PROPAGATE attribute on a per-route basis.
Used to enable/disable TTL propagation at LSP egress.

Signed-off-by: David Ahern <dsahern@gmail.com>
include/netlink-private/types.h
include/netlink/route/route.h
lib/route/route_obj.c
libnl-route-3.sym

index ad4b1252132840fb1ef245432c123d89afc914f0..5d165b68b0ae75cc5bfcda1188d5e9b0968b4f72 100644 (file)
@@ -327,6 +327,7 @@ struct rtnl_route
        uint8_t                 rt_scope;
        uint8_t                 rt_type;
        uint8_t                 rt_nmetrics;
+       uint8_t                 rt_ttl_propagate;
        uint32_t                rt_flags;
        struct nl_addr *        rt_dst;
        struct nl_addr *        rt_src;
index 477250dd8258ec90a102b5e076bd1afeb41326e3..824dae35cce26f5294d55024d574ef6118539257 100644 (file)
@@ -94,6 +94,9 @@ extern struct nl_addr *rtnl_route_get_pref_src(struct rtnl_route *);
 extern void    rtnl_route_set_iif(struct rtnl_route *, int);
 extern int     rtnl_route_get_iif(struct rtnl_route *);
 extern int     rtnl_route_get_src_len(struct rtnl_route *);
+extern void    rtnl_route_set_ttl_propagate(struct rtnl_route *route,
+                                            uint8_t ttl_prop);
+extern int     rtnl_route_get_ttl_propagate(struct rtnl_route *route);
 
 extern void    rtnl_route_add_nexthop(struct rtnl_route *,
                                       struct rtnl_nexthop *);
index 0f03f54a686db2850fd96a7f532b5baa313db4e4..0f842481670512f4c2203a13d6fec59709a56913 100644 (file)
@@ -62,6 +62,7 @@
 #define ROUTE_ATTR_MULTIPATH 0x008000
 #define ROUTE_ATTR_REALMS    0x010000
 #define ROUTE_ATTR_CACHEINFO 0x020000
+#define ROUTE_ATTR_TTL_PROPAGATE 0x040000
 /** @endcond */
 
 static void route_constructor(struct nl_object *c)
@@ -245,6 +246,11 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
        if (r->ce_mask & ROUTE_ATTR_SRC)
                nl_dump(p, "src %s ", nl_addr2str(r->rt_src, buf, sizeof(buf)));
 
+       if (r->ce_mask & ROUTE_ATTR_TTL_PROPAGATE) {
+               nl_dump(p, " ttl-propagate %s",
+                       r->rt_ttl_propagate ? "enabled" : "disabled");
+       }
+
        nl_dump(p, "\n");
 
        if (r->ce_mask & ROUTE_ATTR_MULTIPATH) {
@@ -381,6 +387,8 @@ static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b,
        diff |= ROUTE_DIFF(IIF,         a->rt_iif != b->rt_iif);
        diff |= ROUTE_DIFF(PREF_SRC,    nl_addr_cmp(a->rt_pref_src,
                                                    b->rt_pref_src));
+       diff |= ROUTE_DIFF(TTL_PROPAGATE,
+                          a->rt_ttl_propagate != b->rt_ttl_propagate);
 
        if (flags & LOOSE_COMPARISON) {
                nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) {
@@ -578,6 +586,7 @@ static const struct trans_tbl route_attrs[] = {
        __ADD(ROUTE_ATTR_MULTIPATH, multipath),
        __ADD(ROUTE_ATTR_REALMS, realms),
        __ADD(ROUTE_ATTR_CACHEINFO, cacheinfo),
+       __ADD(ROUTE_ATTR_TTL_PROPAGATE, ttl_propagate),
 };
 
 static char *route_attrs2str(int attrs, char *buf, size_t len)
@@ -910,6 +919,21 @@ struct rtnl_nexthop *rtnl_route_nexthop_n(struct rtnl_route *r, int n)
        return NULL;
 }
 
+void rtnl_route_set_ttl_propagate(struct rtnl_route *route, uint8_t ttl_prop)
+{
+       route->rt_ttl_propagate = ttl_prop;
+       route->ce_mask |= ROUTE_ATTR_TTL_PROPAGATE;
+}
+
+int rtnl_route_get_ttl_propagate(struct rtnl_route *route)
+{
+       if (!route)
+               return -NLE_INVAL;
+       if (!(route->ce_mask & ROUTE_ATTR_TTL_PROPAGATE))
+               return -NLE_MISSING_ATTR;
+       return route->rt_ttl_propagate;
+}
+
 /** @} */
 
 /**
@@ -989,6 +1013,7 @@ static struct nla_policy route_policy[RTA_MAX+1] = {
        [RTA_CACHEINFO] = { .minlen = sizeof(struct rta_cacheinfo) },
        [RTA_METRICS]   = { .type = NLA_NESTED },
        [RTA_MULTIPATH] = { .type = NLA_NESTED },
+       [RTA_TTL_PROPAGATE] = { .type = NLA_U8 },
 };
 
 static int parse_multipath(struct rtnl_route *route, struct nlattr *attr)
@@ -1245,6 +1270,11 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
                        goto errout;
        }
 
+       if (tb[RTA_TTL_PROPAGATE]) {
+               rtnl_route_set_ttl_propagate(route,
+                                            nla_get_u8(tb[RTA_TTL_PROPAGATE]));
+       }
+
        if (old_nh) {
                rtnl_route_nh_set_flags(old_nh, rtm->rtm_flags & 0xff);
                if (route->rt_nr_nh == 0) {
@@ -1340,6 +1370,9 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
        if (route->ce_mask & ROUTE_ATTR_IIF)
                NLA_PUT_U32(msg, RTA_IIF, route->rt_iif);
 
+       if (route->ce_mask & ROUTE_ATTR_TTL_PROPAGATE)
+               NLA_PUT_U8(msg, RTA_TTL_PROPAGATE, route->rt_ttl_propagate);
+
        if (route->rt_nmetrics > 0) {
                uint32_t val;
 
index bb2d6583b8bcc34e5ca662fa257b8cf67de5d225..43827755310a3a68fcc9c4618f384ff25c16130b 100644 (file)
@@ -1057,4 +1057,6 @@ global:
        rtnl_route_nh_get_newdst;
        rtnl_route_nh_set_via;
        rtnl_route_nh_get_via;
+       rtnl_route_set_ttl_propagate;
+       rtnl_route_get_ttl_propagate;
 } libnl_3_2_29;