]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add new nexthop's attributes seg6 (step3)
authorHiroki Shirokura <slank.dev@gmail.com>
Thu, 17 Dec 2020 13:45:58 +0000 (22:45 +0900)
committerMark Stapp <mjs@voltanet.io>
Wed, 2 Jun 2021 14:24:47 +0000 (10:24 -0400)
This commit add new nexthop's addional object for SRv6
routing about seg6 route. Before this commit,
we can add MPLS info as additional object on nexthop.
This commit make it add more support about seg6 routes.

seg6 routes are ones of the LWT routing mechanism,
so configuration of seg6local routes is performed by
ZEBRA_ROUTE_SEND, it's same as MPLS configuration.

Real configuration implementation isn't implemented at
this commit. later commit add that. This commit add
only nexthop additional object and some misc functions.

Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
lib/nexthop.c
lib/nexthop.h
lib/zclient.c
lib/zclient.h

index 3c36dbf69a3406e8009d79fabd355d95891157f3..d0cc5dc258754a33c5dcbc20e7269f2bdddc3d8d 100644 (file)
@@ -37,6 +37,7 @@
 DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop");
 DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label");
 DEFINE_MTYPE_STATIC(LIB, NH_SEG6LOCAL, "Nexthop seg6local");
+DEFINE_MTYPE_STATIC(LIB, NH_SEG6, "Nexthop seg6");
 
 static int _nexthop_labels_cmp(const struct nexthop *nh1,
                               const struct nexthop *nh2)
@@ -89,6 +90,22 @@ static int _nexthop_seg6local_cmp(const struct nexthop *nh1,
                      sizeof(struct seg6local_context));
 }
 
+static int _nexthop_seg6_cmp(const struct nexthop *nh1,
+                            const struct nexthop *nh2)
+{
+       if (!nh1->nh_seg6_segs && !nh2->nh_seg6_segs)
+               return 0;
+
+       if (nh1->nh_seg6_segs && !nh2->nh_seg6_segs)
+               return 1;
+
+       if (!nh1->nh_seg6_segs && nh2->nh_seg6_segs)
+               return -1;
+
+       return memcmp(nh1->nh_seg6_segs, nh2->nh_seg6_segs,
+                     sizeof(struct in6_addr));
+}
+
 int nexthop_g_addr_cmp(enum nexthop_types_t type, const union g_addr *addr1,
                       const union g_addr *addr2)
 {
@@ -226,6 +243,10 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
                return ret;
 
        ret = _nexthop_seg6local_cmp(next1, next2);
+       if (ret != 0)
+               return ret;
+
+       ret = _nexthop_seg6_cmp(next1, next2);
 
        return ret;
 }
@@ -381,6 +402,7 @@ void nexthop_free(struct nexthop *nexthop)
 {
        nexthop_del_labels(nexthop);
        nexthop_del_seg6local(nexthop);
+       nexthop_del_seg6(nexthop);
        if (nexthop->resolved)
                nexthops_free(nexthop->resolved);
        XFREE(MTYPE_NEXTHOP, nexthop);
@@ -572,6 +594,21 @@ void nexthop_del_seg6local(struct nexthop *nexthop)
        nexthop->nh_seg6local_action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
 }
 
+void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr *segs)
+{
+       struct in6_addr *nh_segs;
+
+       nh_segs = XCALLOC(MTYPE_NH_SEG6, sizeof(struct in6_addr));
+       if (segs)
+               *nh_segs = *segs;
+       nexthop->nh_seg6_segs = nh_segs;
+}
+
+void nexthop_del_seg6(struct nexthop *nexthop)
+{
+       XFREE(MTYPE_NH_SEG6, nexthop->nh_seg6_segs);
+}
+
 const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
 {
        switch (nexthop->type) {
@@ -723,6 +760,10 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
                            sizeof(nexthop->nh_seg6local_ctx), key);
        }
 
+       if (nexthop->nh_seg6_segs)
+               key = jhash(nexthop->nh_seg6_segs,
+                           sizeof(nexthop->nh_seg6_segs), key);
+
        return key;
 }
 
@@ -779,6 +820,9 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
        if (nexthop->nh_seg6local_ctx)
                nexthop_add_seg6local(copy, nexthop->nh_seg6local_action,
                                      nexthop->nh_seg6local_ctx);
+
+       if (nexthop->nh_seg6_segs)
+               nexthop_add_seg6(copy, nexthop->nh_seg6_segs);
 }
 
 void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
index 7bddee8713f6d9f32da937ed9bf9defa9e1f53ad..8c52631af11c9b7e0ed43507e8eaa1aea398ef19 100644 (file)
@@ -144,6 +144,9 @@ struct nexthop {
        /* SRv6 localsid info for Endpoint-behaviour */
        enum seg6local_action_t nh_seg6local_action;
        struct seg6local_context *nh_seg6local_ctx;
+
+       /* SRv6 Headend-behaviour */
+       struct in6_addr *nh_seg6_segs;
 };
 
 /* Utility to append one nexthop to another. */
@@ -165,6 +168,8 @@ void nexthop_del_labels(struct nexthop *);
 void nexthop_add_seg6local(struct nexthop *nexthop, uint32_t action,
                           const struct seg6local_context *ctx);
 void nexthop_del_seg6local(struct nexthop *nexthop);
+void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr* segs);
+void nexthop_del_seg6(struct nexthop *nexthop);
 
 /*
  * Allocate a new nexthop object and initialize it from various args.
index c8bb72059150c6b5864f64bce70c857160e62144..8520fd769d2c99f68950dd17c364c256a656c696 100644 (file)
@@ -810,6 +810,13 @@ static int zapi_nexthop_seg6local_cmp(const struct zapi_nexthop *next1,
                      sizeof(struct seg6local_context));
 }
 
+static int zapi_nexthop_seg6_cmp(const struct zapi_nexthop *next1,
+                                const struct zapi_nexthop *next2)
+{
+       return memcmp(&next1->seg6_segs, &next2->seg6_segs,
+                     sizeof(struct in6_addr));
+}
+
 static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
                                      const struct zapi_nexthop *next2)
 {
@@ -914,6 +921,10 @@ static int zapi_nexthop_cmp(const void *item1, const void *item2)
                return ret;
 
        ret = zapi_nexthop_seg6local_cmp(next1, next2);
+       if (ret != 0)
+               return ret;
+
+       ret = zapi_nexthop_seg6_cmp(next1, next2);
 
        return ret;
 }
@@ -1016,6 +1027,10 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
                             sizeof(struct seg6local_context));
        }
 
+       if (CHECK_FLAG(api_flags, ZEBRA_FLAG_SEG6_ROUTE))
+               stream_write(s, &api_nh->seg6_segs,
+                            sizeof(struct in6_addr));
+
 done:
        return ret;
 }
@@ -1303,6 +1318,10 @@ int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
                           sizeof(struct seg6local_context));
        }
 
+       if (CHECK_FLAG(api_flags, ZEBRA_FLAG_SEG6_ROUTE))
+               STREAM_GET(&api_nh->seg6_segs, s,
+                          sizeof(struct in6_addr));
+
        /* Success */
        ret = 0;
 
@@ -1645,6 +1664,7 @@ stream_failure:
 
 struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
 {
+       uint8_t zero[16] = {0};
        struct nexthop *n = nexthop_new();
 
        n->type = znh->type;
@@ -1671,6 +1691,9 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
                nexthop_add_seg6local(n, znh->seg6local_action,
                                      &znh->seg6local_ctx);
 
+       if (memcmp(&znh->seg6_segs, zero, sizeof(struct in6_addr)) != 0)
+               nexthop_add_seg6(n, &znh->seg6_segs);
+
        return n;
 }
 
@@ -1721,6 +1744,10 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
                       sizeof(struct seg6local_context));
        }
 
+       if (nh->nh_seg6_segs != NULL)
+               memcpy(&znh->seg6_segs, nh->nh_seg6_segs,
+                      sizeof(struct in6_addr));
+
        return 0;
 }
 
index 6496e79c89738304a58c8c0a13df9fee14f02fd6..95f3775d5bb0915d58280756de0bf524d4236528 100644 (file)
@@ -474,6 +474,9 @@ struct zapi_nexthop {
        /* SRv6 localsid info for Endpoint-behaviour */
        uint32_t seg6local_action;
        struct seg6local_context seg6local_ctx;
+
+       /* SRv6 Headend-behaviour */
+       struct in6_addr seg6_segs;
 };
 
 /*