lib: add new nexthop's attributes seg6local (step1)

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>
This commit is contained in:
Hiroki Shirokura 2020-08-19 09:46:33 +09:00 committed by Mark Stapp
parent 7a4b49bdd1
commit cb7775a974
4 changed files with 120 additions and 0 deletions

View 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,

View 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.

View 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;
}

View 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;