]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add new nexthop's attributes seg6local (step1)
authorHiroki Shirokura <slank.dev@gmail.com>
Wed, 19 Aug 2020 00:46:33 +0000 (09:46 +0900)
committerMark Stapp <mjs@voltanet.io>
Wed, 2 Jun 2021 14:24:47 +0000 (10:24 -0400)
This commit is a part of #5853 works that add new nexthop's addional
object for SRv6 routing about seg6local route. Before this commit,
we can add MPLS info as additional object on nexthop.
This commit make it add more support about seg6local routes.

seg6local 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 0ac6c0ae1b0eec87cb5989b05337f4cf9029cabe..3c36dbf69a3406e8009d79fabd355d95891157f3 100644 (file)
@@ -36,6 +36,7 @@
 
 DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop");
 DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label");
+DEFINE_MTYPE_STATIC(LIB, NH_SEG6LOCAL, "Nexthop seg6local");
 
 static int _nexthop_labels_cmp(const struct nexthop *nh1,
                               const struct nexthop *nh2)
@@ -66,6 +67,28 @@ static int _nexthop_labels_cmp(const struct nexthop *nh1,
                      (nhl1->num_labels * sizeof(mpls_label_t)));
 }
 
+static int _nexthop_seg6local_cmp(const struct nexthop *nh1,
+                                 const struct nexthop *nh2)
+{
+       if (nh1->nh_seg6local_action > nh2->nh_seg6local_action)
+               return 1;
+
+       if (nh2->nh_seg6local_action < nh1->nh_seg6local_action)
+               return -1;
+
+       if (!nh1->nh_seg6local_ctx && !nh2->nh_seg6local_ctx)
+               return 0;
+
+       if (nh1->nh_seg6local_ctx && !nh2->nh_seg6local_ctx)
+               return 1;
+
+       if (!nh1->nh_seg6local_ctx && nh2->nh_seg6local_ctx)
+               return -1;
+
+       return memcmp(nh1->nh_seg6local_ctx, nh2->nh_seg6local_ctx,
+                     sizeof(struct seg6local_context));
+}
+
 int nexthop_g_addr_cmp(enum nexthop_types_t type, const union g_addr *addr1,
                       const union g_addr *addr2)
 {
@@ -199,6 +222,10 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
                return ret;
 
        ret = _nexthop_labels_cmp(next1, next2);
+       if (ret != 0)
+               return ret;
+
+       ret = _nexthop_seg6local_cmp(next1, next2);
 
        return ret;
 }
@@ -353,6 +380,7 @@ struct nexthop *nexthop_new(void)
 void nexthop_free(struct nexthop *nexthop)
 {
        nexthop_del_labels(nexthop);
+       nexthop_del_seg6local(nexthop);
        if (nexthop->resolved)
                nexthops_free(nexthop->resolved);
        XFREE(MTYPE_NEXTHOP, nexthop);
@@ -523,6 +551,27 @@ void nexthop_del_labels(struct nexthop *nexthop)
        nexthop->nh_label_type = ZEBRA_LSP_NONE;
 }
 
+void nexthop_add_seg6local(struct nexthop *nexthop, uint32_t action,
+                          const struct seg6local_context *ctx)
+{
+       struct seg6local_context *nh_ctx;
+
+       if (action == ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
+               return;
+
+       nh_ctx = XCALLOC(MTYPE_NH_SEG6LOCAL, sizeof(struct seg6local_context));
+       if (ctx)
+               *nh_ctx = *ctx;
+       nexthop->nh_seg6local_action = action;
+       nexthop->nh_seg6local_ctx = nh_ctx;
+}
+
+void nexthop_del_seg6local(struct nexthop *nexthop)
+{
+       XFREE(MTYPE_NH_SEG6LOCAL, nexthop->nh_seg6local_ctx);
+       nexthop->nh_seg6local_action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
+}
+
 const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
 {
        switch (nexthop->type) {
@@ -668,6 +717,12 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
                        key = jhash_1word(nexthop->backup_idx[i], key);
        }
 
+       if (nexthop->nh_seg6local_ctx) {
+               key = jhash_1word(nexthop->nh_seg6local_action, key);
+               key = jhash(nexthop->nh_seg6local_ctx,
+                           sizeof(nexthop->nh_seg6local_ctx), key);
+       }
+
        return key;
 }
 
@@ -720,6 +775,10 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
                nexthop_add_labels(copy, nexthop->nh_label_type,
                                   nexthop->nh_label->num_labels,
                                   &nexthop->nh_label->label[0]);
+
+       if (nexthop->nh_seg6local_ctx)
+               nexthop_add_seg6local(copy, nexthop->nh_seg6local_action,
+                                     nexthop->nh_seg6local_ctx);
 }
 
 void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
index d6ea83cf0614db530f8fc0f8be486a1569510311..7bddee8713f6d9f32da937ed9bf9defa9e1f53ad 100644 (file)
@@ -26,6 +26,7 @@
 #include "prefix.h"
 #include "mpls.h"
 #include "vxlan.h"
+#include "srv6.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -139,6 +140,10 @@ struct nexthop {
 
        /* SR-TE color used for matching SR-TE policies */
        uint32_t srte_color;
+
+       /* SRv6 localsid info for Endpoint-behaviour */
+       enum seg6local_action_t nh_seg6local_action;
+       struct seg6local_context *nh_seg6local_ctx;
 };
 
 /* Utility to append one nexthop to another. */
@@ -157,6 +162,9 @@ void nexthops_free(struct nexthop *nexthop);
 void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t ltype,
                        uint8_t num_labels, const mpls_label_t *labels);
 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);
 
 /*
  * Allocate a new nexthop object and initialize it from various args.
index 3ea1789441b857d150578e657ee9c7cfd6ca0d1b..bf67392cbe1e11b1b2d33c4ed9a3d8d9e7483ff8 100644 (file)
@@ -796,6 +796,19 @@ static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
        return memcmp(next1->labels, next2->labels, next1->label_num);
 }
 
+static int zapi_nexthop_seg6local_cmp(const struct zapi_nexthop *next1,
+                                     const struct zapi_nexthop *next2)
+{
+       if (next1->seg6local_action > next2->seg6local_action)
+               return 1;
+
+       if (next1->seg6local_action < next2->seg6local_action)
+               return -1;
+
+       return memcmp(&next1->seg6local_ctx, &next2->seg6local_ctx,
+                     sizeof(struct seg6local_context));
+}
+
 static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
                                      const struct zapi_nexthop *next2)
 {
@@ -896,6 +909,10 @@ static int zapi_nexthop_cmp(const void *item1, const void *item2)
                return ret;
 
        ret = zapi_nexthop_labels_cmp(next1, next2);
+       if (ret != 0)
+               return ret;
+
+       ret = zapi_nexthop_seg6local_cmp(next1, next2);
 
        return ret;
 }
@@ -992,6 +1009,12 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
                        stream_putc(s, api_nh->backup_idx[i]);
        }
 
+       if (CHECK_FLAG(api_flags, ZEBRA_FLAG_SEG6LOCAL_ROUTE)) {
+               stream_putl(s, api_nh->seg6local_action);
+               stream_write(s, &api_nh->seg6local_ctx,
+                            sizeof(struct seg6local_context));
+       }
+
 done:
        return ret;
 }
@@ -1273,6 +1296,12 @@ int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
                        STREAM_GETC(s, api_nh->backup_idx[i]);
        }
 
+       if (CHECK_FLAG(api_flags, ZEBRA_FLAG_SEG6LOCAL_ROUTE)) {
+               STREAM_GETL(s, api_nh->seg6local_action);
+               STREAM_GET(&api_nh->seg6local_ctx, s,
+                          sizeof(struct seg6local_context));
+       }
+
        /* Success */
        ret = 0;
 
@@ -1637,6 +1666,10 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
                memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
        }
 
+       if (znh->seg6local_action != 0)
+               nexthop_add_seg6local(n, znh->seg6local_action,
+                                     &znh->seg6local_ctx);
+
        return n;
 }
 
@@ -1681,6 +1714,12 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
                memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
        }
 
+       if (nh->nh_seg6local_action != 0 && nh->nh_seg6local_ctx != NULL) {
+               znh->seg6local_action = nh->nh_seg6local_action;
+               memcpy(&znh->seg6local_ctx, nh->nh_seg6local_ctx,
+                      sizeof(struct seg6local_context));
+       }
+
        return 0;
 }
 
index 8c279165425246212dc6c3996d8a47639372bd82..3f5225f09791740ed873a6282ef71221106c7b6b 100644 (file)
@@ -459,6 +459,10 @@ struct zapi_nexthop {
 
        /* SR-TE color. */
        uint32_t srte_color;
+
+       /* SRv6 localsid info for Endpoint-behaviour */
+       uint32_t seg6local_action;
+       struct seg6local_context seg6local_ctx;
 };
 
 /*
@@ -555,6 +559,16 @@ struct zapi_route {
  * offload situation.
  */
 #define ZEBRA_FLAG_OFFLOAD_FAILED     0x200
+/*
+ * This flag tells Zebra that the route is a seg6 route and should
+ * be treated specially.
+ */
+#define ZEBRA_FLAG_SEG6_ROUTE         0x400
+/*
+ * This flag tells Zebra that the route is a seg6local route and
+ * should be treated specially.
+ */
+#define ZEBRA_FLAG_SEG6LOCAL_ROUTE    0x800
 
        /* The older XXX_MESSAGE flags live here */
        uint32_t message;