summaryrefslogtreecommitdiff
path: root/lib/nexthop.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nexthop.c')
-rw-r--r--lib/nexthop.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 0ac6c0ae1b..23e3a2b733 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -36,6 +36,7 @@
DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop");
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label");
+DEFINE_MTYPE_STATIC(LIB, NH_SRV6, "Nexthop srv6");
static int _nexthop_labels_cmp(const struct nexthop *nh1,
const struct nexthop *nh2)
@@ -66,6 +67,39 @@ static int _nexthop_labels_cmp(const struct nexthop *nh1,
(nhl1->num_labels * sizeof(mpls_label_t)));
}
+static int _nexthop_srv6_cmp(const struct nexthop *nh1,
+ const struct nexthop *nh2)
+{
+ int ret = 0;
+
+ if (!nh1->nh_srv6 && !nh2->nh_srv6)
+ return 0;
+
+ if (nh1->nh_srv6 && !nh2->nh_srv6)
+ return 1;
+
+ if (!nh1->nh_srv6 && nh2->nh_srv6)
+ return -1;
+
+ if (nh1->nh_srv6->seg6local_action > nh2->nh_srv6->seg6local_action)
+ return 1;
+
+ if (nh2->nh_srv6->seg6local_action < nh1->nh_srv6->seg6local_action)
+ return -1;
+
+ ret = memcmp(&nh1->nh_srv6->seg6local_ctx,
+ &nh2->nh_srv6->seg6local_ctx,
+ sizeof(struct seg6local_context));
+ if (ret != 0)
+ return ret;
+
+ ret = memcmp(&nh1->nh_srv6->seg6_segs,
+ &nh2->nh_srv6->seg6_segs,
+ sizeof(struct in6_addr));
+
+ return ret;
+}
+
int nexthop_g_addr_cmp(enum nexthop_types_t type, const union g_addr *addr1,
const union g_addr *addr2)
{
@@ -199,6 +233,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_srv6_cmp(next1, next2);
return ret;
}
@@ -353,6 +391,8 @@ struct nexthop *nexthop_new(void)
void nexthop_free(struct nexthop *nexthop)
{
nexthop_del_labels(nexthop);
+ nexthop_del_srv6_seg6local(nexthop);
+ nexthop_del_srv6_seg6(nexthop);
if (nexthop->resolved)
nexthops_free(nexthop->resolved);
XFREE(MTYPE_NEXTHOP, nexthop);
@@ -523,6 +563,57 @@ void nexthop_del_labels(struct nexthop *nexthop)
nexthop->nh_label_type = ZEBRA_LSP_NONE;
}
+void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action,
+ const struct seg6local_context *ctx)
+{
+ if (action == ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
+ return;
+
+ if (!nexthop->nh_srv6)
+ nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
+ sizeof(struct nexthop_srv6));
+
+ nexthop->nh_srv6->seg6local_action = action;
+ nexthop->nh_srv6->seg6local_ctx = *ctx;
+}
+
+void nexthop_del_srv6_seg6local(struct nexthop *nexthop)
+{
+ if (!nexthop->nh_srv6)
+ return;
+
+ nexthop->nh_srv6->seg6local_action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
+
+ if (sid_zero(&nexthop->nh_srv6->seg6_segs))
+ XFREE(MTYPE_NH_SRV6, nexthop->nh_srv6);
+}
+
+void nexthop_add_srv6_seg6(struct nexthop *nexthop,
+ const struct in6_addr *segs)
+{
+ if (!segs)
+ return;
+
+ if (!nexthop->nh_srv6)
+ nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
+ sizeof(struct nexthop_srv6));
+
+ nexthop->nh_srv6->seg6_segs = *segs;
+}
+
+void nexthop_del_srv6_seg6(struct nexthop *nexthop)
+{
+ if (!nexthop->nh_srv6)
+ return;
+
+ memset(&nexthop->nh_srv6->seg6_segs, 0,
+ sizeof(nexthop->nh_srv6->seg6_segs));
+
+ if (nexthop->nh_srv6->seg6local_action ==
+ ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
+ XFREE(MTYPE_NH_SRV6, nexthop->nh_srv6);
+}
+
const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
{
switch (nexthop->type) {
@@ -668,6 +759,14 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
key = jhash_1word(nexthop->backup_idx[i], key);
}
+ if (nexthop->nh_srv6) {
+ key = jhash_1word(nexthop->nh_srv6->seg6local_action, key);
+ key = jhash(&nexthop->nh_srv6->seg6local_ctx,
+ sizeof(nexthop->nh_srv6->seg6local_ctx), key);
+ key = jhash(&nexthop->nh_srv6->seg6_segs,
+ sizeof(nexthop->nh_srv6->seg6_segs), key);
+ }
+
return key;
}
@@ -720,6 +819,17 @@ 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_srv6) {
+ if (nexthop->nh_srv6->seg6local_action !=
+ ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
+ nexthop_add_srv6_seg6local(copy,
+ nexthop->nh_srv6->seg6local_action,
+ &nexthop->nh_srv6->seg6local_ctx);
+ if (!sid_zero(&nexthop->nh_srv6->seg6_segs))
+ nexthop_add_srv6_seg6(copy,
+ &nexthop->nh_srv6->seg6_segs);
+ }
}
void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,