summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/nexthop.c44
-rw-r--r--lib/nexthop.h5
-rw-r--r--lib/zclient.c27
-rw-r--r--lib/zclient.h3
4 files changed, 79 insertions, 0 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 3c36dbf69..d0cc5dc25 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -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,
diff --git a/lib/nexthop.h b/lib/nexthop.h
index 7bddee871..8c52631af 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -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.
diff --git a/lib/zclient.c b/lib/zclient.c
index c8bb72059..8520fd769 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -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;
}
diff --git a/lib/zclient.h b/lib/zclient.h
index 6496e79c8..95f3775d5 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -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;
};
/*