mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 02:46:26 +00:00
lib,sharpd,zebra: update nexthop object with nh_srv6
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
parent
4ccd40339c
commit
eab0f8f0a2
149
lib/nexthop.c
149
lib/nexthop.c
@ -36,8 +36,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");
|
||||
DEFINE_MTYPE_STATIC(LIB, NH_SRV6, "Nexthop srv6");
|
||||
|
||||
static int _nexthop_labels_cmp(const struct nexthop *nh1,
|
||||
const struct nexthop *nh2)
|
||||
@ -68,42 +67,37 @@ 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));
|
||||
}
|
||||
|
||||
static int _nexthop_seg6_cmp(const struct nexthop *nh1,
|
||||
static int _nexthop_srv6_cmp(const struct nexthop *nh1,
|
||||
const struct nexthop *nh2)
|
||||
{
|
||||
if (!nh1->nh_seg6_segs && !nh2->nh_seg6_segs)
|
||||
int ret = 0;
|
||||
|
||||
if (!nh1->nh_srv6 && !nh2->nh_srv6)
|
||||
return 0;
|
||||
|
||||
if (nh1->nh_seg6_segs && !nh2->nh_seg6_segs)
|
||||
if (nh1->nh_srv6 && !nh2->nh_srv6)
|
||||
return 1;
|
||||
|
||||
if (!nh1->nh_seg6_segs && nh2->nh_seg6_segs)
|
||||
if (!nh1->nh_srv6 && nh2->nh_srv6)
|
||||
return -1;
|
||||
|
||||
return memcmp(nh1->nh_seg6_segs, nh2->nh_seg6_segs,
|
||||
sizeof(struct in6_addr));
|
||||
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,
|
||||
@ -242,11 +236,7 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = _nexthop_seg6local_cmp(next1, next2);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = _nexthop_seg6_cmp(next1, next2);
|
||||
ret = _nexthop_srv6_cmp(next1, next2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -401,8 +391,8 @@ struct nexthop *nexthop_new(void)
|
||||
void nexthop_free(struct nexthop *nexthop)
|
||||
{
|
||||
nexthop_del_labels(nexthop);
|
||||
nexthop_del_seg6local(nexthop);
|
||||
nexthop_del_seg6(nexthop);
|
||||
nexthop_del_srv6_seg6local(nexthop);
|
||||
nexthop_del_srv6_seg6(nexthop);
|
||||
if (nexthop->resolved)
|
||||
nexthops_free(nexthop->resolved);
|
||||
XFREE(MTYPE_NEXTHOP, nexthop);
|
||||
@ -573,40 +563,55 @@ 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)
|
||||
void nexthop_add_srv6_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;
|
||||
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_seg6local(struct nexthop *nexthop)
|
||||
void nexthop_del_srv6_seg6local(struct nexthop *nexthop)
|
||||
{
|
||||
XFREE(MTYPE_NH_SEG6LOCAL, nexthop->nh_seg6local_ctx);
|
||||
nexthop->nh_seg6local_action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC;
|
||||
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_seg6(struct nexthop *nexthop, const struct in6_addr *segs)
|
||||
void nexthop_add_srv6_seg6(struct nexthop *nexthop,
|
||||
const struct in6_addr *segs)
|
||||
{
|
||||
struct in6_addr *nh_segs;
|
||||
if (!segs)
|
||||
return;
|
||||
|
||||
nh_segs = XCALLOC(MTYPE_NH_SEG6, sizeof(struct in6_addr));
|
||||
if (segs)
|
||||
*nh_segs = *segs;
|
||||
nexthop->nh_seg6_segs = nh_segs;
|
||||
if (!nexthop->nh_srv6)
|
||||
nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
|
||||
sizeof(struct nexthop_srv6));
|
||||
|
||||
nexthop->nh_srv6->seg6_segs = *segs;
|
||||
}
|
||||
|
||||
void nexthop_del_seg6(struct nexthop *nexthop)
|
||||
void nexthop_del_srv6_seg6(struct nexthop *nexthop)
|
||||
{
|
||||
XFREE(MTYPE_NH_SEG6, nexthop->nh_seg6_segs);
|
||||
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)
|
||||
@ -754,16 +759,14 @@ 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);
|
||||
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);
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6_segs)
|
||||
key = jhash(nexthop->nh_seg6_segs,
|
||||
sizeof(nexthop->nh_seg6_segs), key);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -817,12 +820,16 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
|
||||
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);
|
||||
|
||||
if (nexthop->nh_seg6_segs)
|
||||
nexthop_add_seg6(copy, nexthop->nh_seg6_segs);
|
||||
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,
|
||||
|
@ -141,12 +141,8 @@ 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;
|
||||
|
||||
/* SRv6 Headend-behaviour */
|
||||
struct in6_addr *nh_seg6_segs;
|
||||
/* SRv6 information */
|
||||
struct nexthop_srv6 *nh_srv6;
|
||||
};
|
||||
|
||||
/* Utility to append one nexthop to another. */
|
||||
@ -165,11 +161,12 @@ 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);
|
||||
void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr *segs);
|
||||
void nexthop_del_seg6(struct nexthop *nexthop);
|
||||
void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action,
|
||||
const struct seg6local_context *ctx);
|
||||
void nexthop_del_srv6_seg6local(struct nexthop *nexthop);
|
||||
void nexthop_add_srv6_seg6(struct nexthop *nexthop,
|
||||
const struct in6_addr *segs);
|
||||
void nexthop_del_srv6_seg6(struct nexthop *nexthop);
|
||||
|
||||
/*
|
||||
* Allocate a new nexthop object and initialize it from various args.
|
||||
|
@ -117,6 +117,15 @@ struct srv6_locator_chunk {
|
||||
uint32_t session_id;
|
||||
};
|
||||
|
||||
struct nexthop_srv6 {
|
||||
/* SRv6 localsid info for Endpoint-behaviour */
|
||||
enum seg6local_action_t seg6local_action;
|
||||
struct seg6local_context seg6local_ctx;
|
||||
|
||||
/* SRv6 Headend-behaviour */
|
||||
struct in6_addr seg6_segs;
|
||||
};
|
||||
|
||||
static inline const char *seg6_mode2str(enum seg6_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
|
@ -464,7 +464,7 @@ enum zclient_send_status zclient_send_localsid(struct zclient *zclient,
|
||||
|
||||
nh.type = NEXTHOP_TYPE_IFINDEX;
|
||||
nh.ifindex = oif;
|
||||
nexthop_add_seg6local(&nh, action, context);
|
||||
nexthop_add_srv6_seg6local(&nh, action, context);
|
||||
|
||||
zapi_nexthop_from_nexthop(&api.nexthops[0], &nh);
|
||||
api.nexthop_num = 1;
|
||||
@ -1734,7 +1734,6 @@ 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;
|
||||
@ -1757,12 +1756,12 @@ 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);
|
||||
if (znh->seg6local_action != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
|
||||
nexthop_add_srv6_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);
|
||||
if (!sid_zero(&znh->seg6_segs))
|
||||
nexthop_add_srv6_seg6(n, &znh->seg6_segs);
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -1808,15 +1807,19 @@ 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));
|
||||
}
|
||||
if (nh->nh_srv6) {
|
||||
if (nh->nh_srv6->seg6local_action !=
|
||||
ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
|
||||
znh->seg6local_action = nh->nh_srv6->seg6local_action;
|
||||
memcpy(&znh->seg6local_ctx,
|
||||
&nh->nh_srv6->seg6local_ctx,
|
||||
sizeof(struct seg6local_context));
|
||||
}
|
||||
|
||||
if (nh->nh_seg6_segs != NULL)
|
||||
memcpy(&znh->seg6_segs, nh->nh_seg6_segs,
|
||||
sizeof(struct in6_addr));
|
||||
if (!sid_zero(&nh->nh_srv6->seg6_segs))
|
||||
memcpy(&znh->seg6_segs, &nh->nh_srv6->seg6_segs,
|
||||
sizeof(struct in6_addr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ DEFPY (install_seg6_routes,
|
||||
sg.r.nhop.vrf_id = vrf->vrf_id;
|
||||
sg.r.nhop_group.nexthop = &sg.r.nhop;
|
||||
|
||||
nexthop_add_seg6(&sg.r.nhop, &seg6_seg);
|
||||
nexthop_add_srv6_seg6(&sg.r.nhop, &seg6_seg);
|
||||
SET_FLAG(route_flags, ZEBRA_FLAG_SEG6_ROUTE);
|
||||
|
||||
sg.r.vrf_id = vrf->vrf_id;
|
||||
@ -504,7 +504,7 @@ DEFPY (install_seg6local_routes,
|
||||
sg.r.nhop.ifindex = ifname2ifindex(seg6l_oif, vrf->vrf_id);
|
||||
sg.r.nhop.vrf_id = vrf->vrf_id;
|
||||
sg.r.nhop_group.nexthop = &sg.r.nhop;
|
||||
nexthop_add_seg6local(&sg.r.nhop, action, &ctx);
|
||||
nexthop_add_srv6_seg6local(&sg.r.nhop, action, &ctx);
|
||||
SET_FLAG(route_flags, ZEBRA_FLAG_SEG6LOCAL_ROUTE);
|
||||
|
||||
sg.r.vrf_id = vrf->vrf_id;
|
||||
|
@ -534,10 +534,10 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
|
||||
nexthop_add_labels(&nh, ZEBRA_LSP_STATIC, num_labels, labels);
|
||||
|
||||
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
|
||||
nexthop_add_seg6local(&nh, seg6l_act, &seg6l_ctx);
|
||||
nexthop_add_srv6_seg6local(&nh, seg6l_act, &seg6l_ctx);
|
||||
|
||||
if (num_segs)
|
||||
nexthop_add_seg6(&nh, &seg6_segs);
|
||||
nexthop_add_srv6_seg6(&nh, &seg6_segs);
|
||||
|
||||
return nh;
|
||||
}
|
||||
@ -641,11 +641,11 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
|
||||
num_labels, labels);
|
||||
|
||||
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
|
||||
nexthop_add_seg6local(nh, seg6l_act,
|
||||
&seg6l_ctx);
|
||||
nexthop_add_srv6_seg6local(nh, seg6l_act,
|
||||
&seg6l_ctx);
|
||||
|
||||
if (num_segs)
|
||||
nexthop_add_seg6(nh, &seg6_segs);
|
||||
nexthop_add_srv6_seg6(nh, &seg6_segs);
|
||||
|
||||
if (rtnh->rtnh_flags & RTNH_F_ONLINK)
|
||||
SET_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK);
|
||||
@ -1399,84 +1399,97 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
|
||||
sizeof(label_buf)))
|
||||
return false;
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
if (nexthop->nh_srv6) {
|
||||
if (nexthop->nh_srv6->seg6local_action !=
|
||||
ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
|
||||
ctx = nexthop->nh_seg6local_ctx;
|
||||
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL))
|
||||
return false;
|
||||
ctx = &nexthop->nh_srv6->seg6local_ctx;
|
||||
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL))
|
||||
return false;
|
||||
|
||||
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||
if (!nest)
|
||||
return false;
|
||||
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||
if (!nest)
|
||||
return false;
|
||||
|
||||
switch (nexthop->nh_seg6local_action) {
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END:
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_X:
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_X))
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH6,
|
||||
&ctx->nh6, sizeof(struct in6_addr)))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_T:
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_T))
|
||||
return false;
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DX4))
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH4,
|
||||
&ctx->nh4, sizeof(struct in_addr)))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DT6))
|
||||
return false;
|
||||
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__, nexthop->nh_seg6local_action);
|
||||
break;
|
||||
switch (nexthop->nh_srv6->seg6local_action) {
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END:
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_X:
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_X))
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size,
|
||||
SEG6_LOCAL_NH6, &ctx->nh6,
|
||||
sizeof(struct in6_addr)))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_T:
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_T))
|
||||
return false;
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DX4))
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size,
|
||||
SEG6_LOCAL_NH4, &ctx->nh4,
|
||||
sizeof(struct in_addr)))
|
||||
return false;
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DT6))
|
||||
return false;
|
||||
if (!nl_attr_put32(nlmsg, req_size,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__,
|
||||
nexthop->nh_srv6->seg6local_action);
|
||||
break;
|
||||
}
|
||||
nl_attr_nest_end(nlmsg, nest);
|
||||
}
|
||||
nl_attr_nest_end(nlmsg, nest);
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6_segs) {
|
||||
char tun_buf[4096];
|
||||
ssize_t tun_len;
|
||||
struct rtattr *nest;
|
||||
if (!sid_zero(&nexthop->nh_srv6->seg6_segs)) {
|
||||
char tun_buf[4096];
|
||||
ssize_t tun_len;
|
||||
struct rtattr *nest;
|
||||
|
||||
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6))
|
||||
return false;
|
||||
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||
if (!nest)
|
||||
return false;
|
||||
tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
|
||||
nexthop->nh_seg6_segs);
|
||||
if (tun_len < 0)
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH, tun_buf,
|
||||
tun_len))
|
||||
return false;
|
||||
nl_attr_nest_end(nlmsg, nest);
|
||||
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6))
|
||||
return false;
|
||||
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||
if (!nest)
|
||||
return false;
|
||||
tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
|
||||
&nexthop->nh_srv6->seg6_segs);
|
||||
if (tun_len < 0)
|
||||
return false;
|
||||
if (!nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH,
|
||||
tun_buf, tun_len))
|
||||
return false;
|
||||
nl_attr_nest_end(nlmsg, nest);
|
||||
}
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||
@ -2473,104 +2486,117 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
|
||||
if (nh->nh_seg6local_ctx) {
|
||||
uint32_t action;
|
||||
uint16_t encap;
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
if (nh->nh_srv6) {
|
||||
if (nh->nh_srv6->seg6local_action !=
|
||||
ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
|
||||
uint32_t action;
|
||||
uint16_t encap;
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
|
||||
req->nhm.nh_family = AF_INET6;
|
||||
action = nh->nh_seg6local_action;
|
||||
ctx = nh->nh_seg6local_ctx;
|
||||
encap = LWTUNNEL_ENCAP_SEG6_LOCAL;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
NHA_ENCAP_TYPE, &encap,
|
||||
sizeof(uint16_t)))
|
||||
return 0;
|
||||
req->nhm.nh_family = AF_INET6;
|
||||
action = nh->nh_srv6->seg6local_action;
|
||||
ctx = &nh->nh_srv6->seg6local_ctx;
|
||||
encap = LWTUNNEL_ENCAP_SEG6_LOCAL;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
NHA_ENCAP_TYPE,
|
||||
&encap,
|
||||
sizeof(uint16_t)))
|
||||
return 0;
|
||||
|
||||
nest = nl_attr_nest(&req->n, buflen,
|
||||
NHA_ENCAP | NLA_F_NESTED);
|
||||
if (!nest)
|
||||
return 0;
|
||||
nest = nl_attr_nest(&req->n, buflen,
|
||||
NHA_ENCAP | NLA_F_NESTED);
|
||||
if (!nest)
|
||||
return 0;
|
||||
|
||||
switch (action) {
|
||||
case SEG6_LOCAL_ACTION_END:
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
switch (action) {
|
||||
case SEG6_LOCAL_ACTION_END:
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END))
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_X:
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_X:
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_X))
|
||||
return 0;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
return 0;
|
||||
if (!nl_attr_put(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_NH6, &ctx->nh6,
|
||||
sizeof(struct in6_addr)))
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_T:
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_T:
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_T))
|
||||
return 0;
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DX4:
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DX4:
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DX4))
|
||||
return 0;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
return 0;
|
||||
if (!nl_attr_put(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_NH4, &ctx->nh4,
|
||||
sizeof(struct in_addr)))
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DT6:
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DT6:
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DT6))
|
||||
return 0;
|
||||
if (!nl_attr_put32(&req->n, buflen,
|
||||
return 0;
|
||||
if (!nl_attr_put32(
|
||||
&req->n, buflen,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__, action);
|
||||
break;
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__, action);
|
||||
break;
|
||||
}
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
|
||||
if (nh->nh_seg6_segs) {
|
||||
char tun_buf[4096];
|
||||
ssize_t tun_len;
|
||||
struct rtattr *nest;
|
||||
if (!sid_zero(&nh->nh_srv6->seg6_segs)) {
|
||||
char tun_buf[4096];
|
||||
ssize_t tun_len;
|
||||
struct rtattr *nest;
|
||||
|
||||
if (!nl_attr_put16(&req->n, buflen,
|
||||
NHA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6))
|
||||
return 0;
|
||||
nest = nl_attr_nest(&req->n, buflen,
|
||||
NHA_ENCAP | NLA_F_NESTED);
|
||||
if (!nest)
|
||||
return 0;
|
||||
tun_len = fill_seg6ipt_encap(tun_buf,
|
||||
sizeof(tun_buf),
|
||||
nh->nh_seg6_segs);
|
||||
if (tun_len < 0)
|
||||
return 0;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
SEG6_IPTUNNEL_SRH,
|
||||
tun_buf, tun_len))
|
||||
return 0;
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
if (!nl_attr_put16(&req->n, buflen,
|
||||
NHA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6))
|
||||
return 0;
|
||||
nest = nl_attr_nest(&req->n, buflen,
|
||||
NHA_ENCAP | NLA_F_NESTED);
|
||||
if (!nest)
|
||||
return 0;
|
||||
tun_len = fill_seg6ipt_encap(tun_buf,
|
||||
sizeof(tun_buf),
|
||||
&nh->nh_srv6->seg6_segs);
|
||||
if (tun_len < 0)
|
||||
return 0;
|
||||
if (!nl_attr_put(&req->n, buflen,
|
||||
SEG6_IPTUNNEL_SRH,
|
||||
tun_buf, tun_len))
|
||||
return 0;
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
}
|
||||
|
||||
nexthop_done:
|
||||
|
@ -1756,8 +1756,9 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
|
||||
seg6local_action2str(
|
||||
api_nh->seg6local_action));
|
||||
|
||||
nexthop_add_seg6local(nexthop, api_nh->seg6local_action,
|
||||
&api_nh->seg6local_ctx);
|
||||
nexthop_add_srv6_seg6local(nexthop,
|
||||
api_nh->seg6local_action,
|
||||
&api_nh->seg6local_ctx);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(flags, ZEBRA_FLAG_SEG6_ROUTE)
|
||||
@ -1765,7 +1766,7 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
|
||||
if (IS_ZEBRA_DEBUG_RECV)
|
||||
zlog_debug("%s: adding seg6", __func__);
|
||||
|
||||
nexthop_add_seg6(nexthop, &api_nh->seg6_segs);
|
||||
nexthop_add_srv6_seg6(nexthop, &api_nh->seg6_segs);
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RECV) {
|
||||
|
@ -1007,8 +1007,8 @@ void nhg_ctx_free(struct nhg_ctx **ctx)
|
||||
nh = nhg_ctx_get_nh(*ctx);
|
||||
|
||||
nexthop_del_labels(nh);
|
||||
nexthop_del_seg6local(nh);
|
||||
nexthop_del_seg6(nh);
|
||||
nexthop_del_srv6_seg6local(nh);
|
||||
nexthop_del_srv6_seg6(nh);
|
||||
|
||||
done:
|
||||
XFREE(MTYPE_NHG_CTX, *ctx);
|
||||
@ -1379,8 +1379,8 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
|
||||
|
||||
/* The copy may have allocated labels; free them if necessary. */
|
||||
nexthop_del_labels(&lookup);
|
||||
nexthop_del_seg6local(&lookup);
|
||||
nexthop_del_seg6(&lookup);
|
||||
nexthop_del_srv6_seg6local(&lookup);
|
||||
nexthop_del_srv6_seg6(&lookup);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||
zlog_debug("%s: nh %pNHv => %p (%u)",
|
||||
|
@ -653,17 +653,15 @@ static void show_route_nexthop_helper(struct vty *vty,
|
||||
sizeof(buf), 1));
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
if (nexthop->nh_srv6) {
|
||||
seg6local_context2str(buf, sizeof(buf),
|
||||
nexthop->nh_seg6local_ctx,
|
||||
nexthop->nh_seg6local_action);
|
||||
&nexthop->nh_srv6->seg6local_ctx,
|
||||
nexthop->nh_srv6->seg6local_action);
|
||||
vty_out(vty, ", seg6local %s %s",
|
||||
seg6local_action2str(nexthop->nh_seg6local_action),
|
||||
seg6local_action2str(nexthop->nh_srv6->seg6local_action),
|
||||
buf);
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6_segs) {
|
||||
inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
|
||||
inet_ntop(AF_INET6, &nexthop->nh_srv6->seg6_segs, buf, sizeof(buf));
|
||||
vty_out(vty, ", seg6 %s", buf);
|
||||
}
|
||||
|
||||
@ -869,18 +867,16 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
|
||||
json_object_int_add(json_nexthop, "srteColor",
|
||||
nexthop->srte_color);
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
if (nexthop->nh_srv6) {
|
||||
json_seg6local = json_object_new_object();
|
||||
json_object_string_add(
|
||||
json_seg6local, "action",
|
||||
seg6local_action2str(nexthop->nh_seg6local_action));
|
||||
seg6local_action2str(nexthop->nh_srv6->seg6local_action));
|
||||
json_object_object_add(json_nexthop, "seg6local",
|
||||
json_seg6local);
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6_segs) {
|
||||
json_seg6 = json_object_new_object();
|
||||
inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
|
||||
inet_ntop(AF_INET6, &nexthop->nh_srv6->seg6_segs, buf, sizeof(buf));
|
||||
json_object_string_add(json_seg6, "segs", buf);
|
||||
json_object_object_add(json_nexthop, "seg6", json_seg6);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user