diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/nexthop.c | 44 | ||||
-rw-r--r-- | lib/nexthop.h | 5 | ||||
-rw-r--r-- | lib/zclient.c | 27 | ||||
-rw-r--r-- | lib/zclient.h | 3 |
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; }; /* |