lib,sharpd,zebra: update nexthop object with nh_srv6

Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
Hiroki Shirokura 2021-04-05 13:29:12 +00:00 committed by Mark Stapp
parent 4ccd40339c
commit eab0f8f0a2
9 changed files with 308 additions and 269 deletions

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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

View File

@ -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:

View File

@ -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) {

View File

@ -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)",

View File

@ -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);
}