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, NEXTHOP, "Nexthop");
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label"); DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label");
DEFINE_MTYPE_STATIC(LIB, NH_SEG6LOCAL, "Nexthop seg6local"); DEFINE_MTYPE_STATIC(LIB, NH_SRV6, "Nexthop srv6");
DEFINE_MTYPE_STATIC(LIB, NH_SEG6, "Nexthop seg6");
static int _nexthop_labels_cmp(const struct nexthop *nh1, static int _nexthop_labels_cmp(const struct nexthop *nh1,
const struct nexthop *nh2) const struct nexthop *nh2)
@ -68,42 +67,37 @@ static int _nexthop_labels_cmp(const struct nexthop *nh1,
(nhl1->num_labels * sizeof(mpls_label_t))); (nhl1->num_labels * sizeof(mpls_label_t)));
} }
static int _nexthop_seg6local_cmp(const struct nexthop *nh1, static int _nexthop_srv6_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,
const struct nexthop *nh2) 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; return 0;
if (nh1->nh_seg6_segs && !nh2->nh_seg6_segs) if (nh1->nh_srv6 && !nh2->nh_srv6)
return 1; return 1;
if (!nh1->nh_seg6_segs && nh2->nh_seg6_segs) if (!nh1->nh_srv6 && nh2->nh_srv6)
return -1; return -1;
return memcmp(nh1->nh_seg6_segs, nh2->nh_seg6_segs, if (nh1->nh_srv6->seg6local_action > nh2->nh_srv6->seg6local_action)
sizeof(struct in6_addr)); 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, 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) if (ret != 0)
return ret; return ret;
ret = _nexthop_seg6local_cmp(next1, next2); ret = _nexthop_srv6_cmp(next1, next2);
if (ret != 0)
return ret;
ret = _nexthop_seg6_cmp(next1, next2);
return ret; return ret;
} }
@ -401,8 +391,8 @@ struct nexthop *nexthop_new(void)
void nexthop_free(struct nexthop *nexthop) void nexthop_free(struct nexthop *nexthop)
{ {
nexthop_del_labels(nexthop); nexthop_del_labels(nexthop);
nexthop_del_seg6local(nexthop); nexthop_del_srv6_seg6local(nexthop);
nexthop_del_seg6(nexthop); nexthop_del_srv6_seg6(nexthop);
if (nexthop->resolved) if (nexthop->resolved)
nexthops_free(nexthop->resolved); nexthops_free(nexthop->resolved);
XFREE(MTYPE_NEXTHOP, nexthop); XFREE(MTYPE_NEXTHOP, nexthop);
@ -573,40 +563,55 @@ void nexthop_del_labels(struct nexthop *nexthop)
nexthop->nh_label_type = ZEBRA_LSP_NONE; nexthop->nh_label_type = ZEBRA_LSP_NONE;
} }
void nexthop_add_seg6local(struct nexthop *nexthop, uint32_t action, void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action,
const struct seg6local_context *ctx) const struct seg6local_context *ctx)
{ {
struct seg6local_context *nh_ctx;
if (action == ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) if (action == ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
return; return;
nh_ctx = XCALLOC(MTYPE_NH_SEG6LOCAL, sizeof(struct seg6local_context)); if (!nexthop->nh_srv6)
if (ctx) nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
*nh_ctx = *ctx; sizeof(struct nexthop_srv6));
nexthop->nh_seg6local_action = action;
nexthop->nh_seg6local_ctx = nh_ctx; 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); if (!nexthop->nh_srv6)
nexthop->nh_seg6local_action = ZEBRA_SEG6_LOCAL_ACTION_UNSPEC; 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 (!nexthop->nh_srv6)
if (segs) nexthop->nh_srv6 = XCALLOC(MTYPE_NH_SRV6,
*nh_segs = *segs; sizeof(struct nexthop_srv6));
nexthop->nh_seg6_segs = nh_segs;
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) 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); key = jhash_1word(nexthop->backup_idx[i], key);
} }
if (nexthop->nh_seg6local_ctx) { if (nexthop->nh_srv6) {
key = jhash_1word(nexthop->nh_seg6local_action, key); key = jhash_1word(nexthop->nh_srv6->seg6local_action, key);
key = jhash(nexthop->nh_seg6local_ctx, key = jhash(&nexthop->nh_srv6->seg6local_ctx,
sizeof(nexthop->nh_seg6local_ctx), key); 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; return key;
} }
@ -817,12 +820,16 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
nexthop->nh_label->num_labels, nexthop->nh_label->num_labels,
&nexthop->nh_label->label[0]); &nexthop->nh_label->label[0]);
if (nexthop->nh_seg6local_ctx) if (nexthop->nh_srv6) {
nexthop_add_seg6local(copy, nexthop->nh_seg6local_action, if (nexthop->nh_srv6->seg6local_action !=
nexthop->nh_seg6local_ctx); ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_srv6_seg6local(copy,
if (nexthop->nh_seg6_segs) nexthop->nh_srv6->seg6local_action,
nexthop_add_seg6(copy, nexthop->nh_seg6_segs); &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, 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 */ /* SR-TE color used for matching SR-TE policies */
uint32_t srte_color; uint32_t srte_color;
/* SRv6 localsid info for Endpoint-behaviour */ /* SRv6 information */
enum seg6local_action_t nh_seg6local_action; struct nexthop_srv6 *nh_srv6;
struct seg6local_context *nh_seg6local_ctx;
/* SRv6 Headend-behaviour */
struct in6_addr *nh_seg6_segs;
}; };
/* Utility to append one nexthop to another. */ /* 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, void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t ltype,
uint8_t num_labels, const mpls_label_t *labels); uint8_t num_labels, const mpls_label_t *labels);
void nexthop_del_labels(struct nexthop *); void nexthop_del_labels(struct nexthop *);
void nexthop_add_seg6local(struct nexthop *nexthop, uint32_t action, void nexthop_add_srv6_seg6local(struct nexthop *nexthop, uint32_t action,
const struct seg6local_context *ctx); const struct seg6local_context *ctx);
void nexthop_del_seg6local(struct nexthop *nexthop); void nexthop_del_srv6_seg6local(struct nexthop *nexthop);
void nexthop_add_seg6(struct nexthop *nexthop, const struct in6_addr *segs); void nexthop_add_srv6_seg6(struct nexthop *nexthop,
void nexthop_del_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. * 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; 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) static inline const char *seg6_mode2str(enum seg6_mode_t mode)
{ {
switch (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.type = NEXTHOP_TYPE_IFINDEX;
nh.ifindex = oif; nh.ifindex = oif;
nexthop_add_seg6local(&nh, action, context); nexthop_add_srv6_seg6local(&nh, action, context);
zapi_nexthop_from_nexthop(&api.nexthops[0], &nh); zapi_nexthop_from_nexthop(&api.nexthops[0], &nh);
api.nexthop_num = 1; api.nexthop_num = 1;
@ -1734,7 +1734,6 @@ stream_failure:
struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
{ {
uint8_t zero[16] = {0};
struct nexthop *n = nexthop_new(); struct nexthop *n = nexthop_new();
n->type = znh->type; 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); memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
} }
if (znh->seg6local_action != 0) if (znh->seg6local_action != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_seg6local(n, znh->seg6local_action, nexthop_add_srv6_seg6local(n, znh->seg6local_action,
&znh->seg6local_ctx); &znh->seg6local_ctx);
if (memcmp(&znh->seg6_segs, zero, sizeof(struct in6_addr)) != 0) if (!sid_zero(&znh->seg6_segs))
nexthop_add_seg6(n, &znh->seg6_segs); nexthop_add_srv6_seg6(n, &znh->seg6_segs);
return n; 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); memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
} }
if (nh->nh_seg6local_action != 0 && nh->nh_seg6local_ctx != NULL) { if (nh->nh_srv6) {
znh->seg6local_action = nh->nh_seg6local_action; if (nh->nh_srv6->seg6local_action !=
memcpy(&znh->seg6local_ctx, nh->nh_seg6local_ctx, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
sizeof(struct seg6local_context)); 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) if (!sid_zero(&nh->nh_srv6->seg6_segs))
memcpy(&znh->seg6_segs, nh->nh_seg6_segs, memcpy(&znh->seg6_segs, &nh->nh_srv6->seg6_segs,
sizeof(struct in6_addr)); sizeof(struct in6_addr));
}
return 0; return 0;
} }

View File

@ -407,7 +407,7 @@ DEFPY (install_seg6_routes,
sg.r.nhop.vrf_id = vrf->vrf_id; sg.r.nhop.vrf_id = vrf->vrf_id;
sg.r.nhop_group.nexthop = &sg.r.nhop; 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); SET_FLAG(route_flags, ZEBRA_FLAG_SEG6_ROUTE);
sg.r.vrf_id = vrf->vrf_id; 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.ifindex = ifname2ifindex(seg6l_oif, vrf->vrf_id);
sg.r.nhop.vrf_id = vrf->vrf_id; sg.r.nhop.vrf_id = vrf->vrf_id;
sg.r.nhop_group.nexthop = &sg.r.nhop; 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); SET_FLAG(route_flags, ZEBRA_FLAG_SEG6LOCAL_ROUTE);
sg.r.vrf_id = vrf->vrf_id; 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); nexthop_add_labels(&nh, ZEBRA_LSP_STATIC, num_labels, labels);
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) 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) if (num_segs)
nexthop_add_seg6(&nh, &seg6_segs); nexthop_add_srv6_seg6(&nh, &seg6_segs);
return nh; return nh;
} }
@ -641,11 +641,11 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id,
num_labels, labels); num_labels, labels);
if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) if (seg6l_act != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
nexthop_add_seg6local(nh, seg6l_act, nexthop_add_srv6_seg6local(nh, seg6l_act,
&seg6l_ctx); &seg6l_ctx);
if (num_segs) if (num_segs)
nexthop_add_seg6(nh, &seg6_segs); nexthop_add_srv6_seg6(nh, &seg6_segs);
if (rtnh->rtnh_flags & RTNH_F_ONLINK) if (rtnh->rtnh_flags & RTNH_F_ONLINK)
SET_FLAG(nh->flags, NEXTHOP_FLAG_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))) sizeof(label_buf)))
return false; return false;
if (nexthop->nh_seg6local_ctx) { if (nexthop->nh_srv6) {
struct rtattr *nest; if (nexthop->nh_srv6->seg6local_action !=
const struct seg6local_context *ctx; ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
struct rtattr *nest;
const struct seg6local_context *ctx;
ctx = nexthop->nh_seg6local_ctx; ctx = &nexthop->nh_srv6->seg6local_ctx;
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE, if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
LWTUNNEL_ENCAP_SEG6_LOCAL)) LWTUNNEL_ENCAP_SEG6_LOCAL))
return false; return false;
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP); nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
if (!nest) if (!nest)
return false; return false;
switch (nexthop->nh_seg6local_action) { switch (nexthop->nh_srv6->seg6local_action) {
case ZEBRA_SEG6_LOCAL_ACTION_END: case ZEBRA_SEG6_LOCAL_ACTION_END:
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION, if (!nl_attr_put32(nlmsg, req_size,
SEG6_LOCAL_ACTION_END)) SEG6_LOCAL_ACTION,
return false; SEG6_LOCAL_ACTION_END))
break; return false;
case ZEBRA_SEG6_LOCAL_ACTION_END_X: break;
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION, case ZEBRA_SEG6_LOCAL_ACTION_END_X:
SEG6_LOCAL_ACTION_END_X)) if (!nl_attr_put32(nlmsg, req_size,
return false; SEG6_LOCAL_ACTION,
if (!nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH6, SEG6_LOCAL_ACTION_END_X))
&ctx->nh6, sizeof(struct in6_addr))) return false;
return false; if (!nl_attr_put(nlmsg, req_size,
break; SEG6_LOCAL_NH6, &ctx->nh6,
case ZEBRA_SEG6_LOCAL_ACTION_END_T: sizeof(struct in6_addr)))
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION, return false;
SEG6_LOCAL_ACTION_END_T)) break;
return false; case ZEBRA_SEG6_LOCAL_ACTION_END_T:
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE, if (!nl_attr_put32(nlmsg, req_size,
ctx->table)) SEG6_LOCAL_ACTION,
return false; SEG6_LOCAL_ACTION_END_T))
break; return false;
case ZEBRA_SEG6_LOCAL_ACTION_END_DX4: if (!nl_attr_put32(nlmsg, req_size,
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION, SEG6_LOCAL_TABLE,
SEG6_LOCAL_ACTION_END_DX4)) ctx->table))
return false; return false;
if (!nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH4, break;
&ctx->nh4, sizeof(struct in_addr))) case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
return false; if (!nl_attr_put32(nlmsg, req_size,
break; SEG6_LOCAL_ACTION,
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6: SEG6_LOCAL_ACTION_END_DX4))
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION, return false;
SEG6_LOCAL_ACTION_END_DT6)) if (!nl_attr_put(nlmsg, req_size,
return false; SEG6_LOCAL_NH4, &ctx->nh4,
if (!nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE, sizeof(struct in_addr)))
ctx->table)) return false;
return false; break;
break; case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
default: if (!nl_attr_put32(nlmsg, req_size,
zlog_err("%s: unsupport seg6local behaviour action=%u", SEG6_LOCAL_ACTION,
__func__, nexthop->nh_seg6local_action); SEG6_LOCAL_ACTION_END_DT6))
break; 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) { if (!sid_zero(&nexthop->nh_srv6->seg6_segs)) {
char tun_buf[4096]; char tun_buf[4096];
ssize_t tun_len; ssize_t tun_len;
struct rtattr *nest; struct rtattr *nest;
if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE, if (!nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
LWTUNNEL_ENCAP_SEG6)) LWTUNNEL_ENCAP_SEG6))
return false; return false;
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP); nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
if (!nest) if (!nest)
return false; return false;
tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf), tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
nexthop->nh_seg6_segs); &nexthop->nh_srv6->seg6_segs);
if (tun_len < 0) if (tun_len < 0)
return false; return false;
if (!nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH, tun_buf, if (!nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH,
tun_len)) tun_buf, tun_len))
return false; return false;
nl_attr_nest_end(nlmsg, nest); nl_attr_nest_end(nlmsg, nest);
}
} }
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) 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); nl_attr_nest_end(&req->n, nest);
} }
if (nh->nh_seg6local_ctx) { if (nh->nh_srv6) {
uint32_t action; if (nh->nh_srv6->seg6local_action !=
uint16_t encap; ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
struct rtattr *nest; uint32_t action;
const struct seg6local_context *ctx; uint16_t encap;
struct rtattr *nest;
const struct seg6local_context *ctx;
req->nhm.nh_family = AF_INET6; req->nhm.nh_family = AF_INET6;
action = nh->nh_seg6local_action; action = nh->nh_srv6->seg6local_action;
ctx = nh->nh_seg6local_ctx; ctx = &nh->nh_srv6->seg6local_ctx;
encap = LWTUNNEL_ENCAP_SEG6_LOCAL; encap = LWTUNNEL_ENCAP_SEG6_LOCAL;
if (!nl_attr_put(&req->n, buflen, if (!nl_attr_put(&req->n, buflen,
NHA_ENCAP_TYPE, &encap, NHA_ENCAP_TYPE,
sizeof(uint16_t))) &encap,
return 0; sizeof(uint16_t)))
return 0;
nest = nl_attr_nest(&req->n, buflen, nest = nl_attr_nest(&req->n, buflen,
NHA_ENCAP | NLA_F_NESTED); NHA_ENCAP | NLA_F_NESTED);
if (!nest) if (!nest)
return 0; return 0;
switch (action) { switch (action) {
case SEG6_LOCAL_ACTION_END: case SEG6_LOCAL_ACTION_END:
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_ACTION, SEG6_LOCAL_ACTION,
SEG6_LOCAL_ACTION_END)) SEG6_LOCAL_ACTION_END))
return 0; return 0;
break; break;
case SEG6_LOCAL_ACTION_END_X: case SEG6_LOCAL_ACTION_END_X:
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_ACTION, SEG6_LOCAL_ACTION,
SEG6_LOCAL_ACTION_END_X)) SEG6_LOCAL_ACTION_END_X))
return 0; return 0;
if (!nl_attr_put(&req->n, buflen, if (!nl_attr_put(
&req->n, buflen,
SEG6_LOCAL_NH6, &ctx->nh6, SEG6_LOCAL_NH6, &ctx->nh6,
sizeof(struct in6_addr))) sizeof(struct in6_addr)))
return 0; return 0;
break; break;
case SEG6_LOCAL_ACTION_END_T: case SEG6_LOCAL_ACTION_END_T:
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_ACTION, SEG6_LOCAL_ACTION,
SEG6_LOCAL_ACTION_END_T)) SEG6_LOCAL_ACTION_END_T))
return 0; return 0;
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_TABLE, SEG6_LOCAL_TABLE,
ctx->table)) ctx->table))
return 0; return 0;
break; break;
case SEG6_LOCAL_ACTION_END_DX4: case SEG6_LOCAL_ACTION_END_DX4:
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_ACTION, SEG6_LOCAL_ACTION,
SEG6_LOCAL_ACTION_END_DX4)) SEG6_LOCAL_ACTION_END_DX4))
return 0; return 0;
if (!nl_attr_put(&req->n, buflen, if (!nl_attr_put(
&req->n, buflen,
SEG6_LOCAL_NH4, &ctx->nh4, SEG6_LOCAL_NH4, &ctx->nh4,
sizeof(struct in_addr))) sizeof(struct in_addr)))
return 0; return 0;
break; break;
case SEG6_LOCAL_ACTION_END_DT6: case SEG6_LOCAL_ACTION_END_DT6:
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_ACTION, SEG6_LOCAL_ACTION,
SEG6_LOCAL_ACTION_END_DT6)) SEG6_LOCAL_ACTION_END_DT6))
return 0; return 0;
if (!nl_attr_put32(&req->n, buflen, if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_TABLE, SEG6_LOCAL_TABLE,
ctx->table)) ctx->table))
return 0; return 0;
break; break;
default: default:
zlog_err("%s: unsupport seg6local behaviour action=%u", zlog_err("%s: unsupport seg6local behaviour action=%u",
__func__, action); __func__, action);
break; break;
}
nl_attr_nest_end(&req->n, nest);
} }
nl_attr_nest_end(&req->n, nest);
}
if (nh->nh_seg6_segs) { if (!sid_zero(&nh->nh_srv6->seg6_segs)) {
char tun_buf[4096]; char tun_buf[4096];
ssize_t tun_len; ssize_t tun_len;
struct rtattr *nest; struct rtattr *nest;
if (!nl_attr_put16(&req->n, buflen, if (!nl_attr_put16(&req->n, buflen,
NHA_ENCAP_TYPE, NHA_ENCAP_TYPE,
LWTUNNEL_ENCAP_SEG6)) LWTUNNEL_ENCAP_SEG6))
return 0; return 0;
nest = nl_attr_nest(&req->n, buflen, nest = nl_attr_nest(&req->n, buflen,
NHA_ENCAP | NLA_F_NESTED); NHA_ENCAP | NLA_F_NESTED);
if (!nest) if (!nest)
return 0; return 0;
tun_len = fill_seg6ipt_encap(tun_buf, tun_len = fill_seg6ipt_encap(tun_buf,
sizeof(tun_buf), sizeof(tun_buf),
nh->nh_seg6_segs); &nh->nh_srv6->seg6_segs);
if (tun_len < 0) if (tun_len < 0)
return 0; return 0;
if (!nl_attr_put(&req->n, buflen, if (!nl_attr_put(&req->n, buflen,
SEG6_IPTUNNEL_SRH, SEG6_IPTUNNEL_SRH,
tun_buf, tun_len)) tun_buf, tun_len))
return 0; return 0;
nl_attr_nest_end(&req->n, nest); nl_attr_nest_end(&req->n, nest);
}
} }
nexthop_done: nexthop_done:

View File

@ -1756,8 +1756,9 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
seg6local_action2str( seg6local_action2str(
api_nh->seg6local_action)); api_nh->seg6local_action));
nexthop_add_seg6local(nexthop, api_nh->seg6local_action, nexthop_add_srv6_seg6local(nexthop,
&api_nh->seg6local_ctx); api_nh->seg6local_action,
&api_nh->seg6local_ctx);
} }
if (CHECK_FLAG(flags, ZEBRA_FLAG_SEG6_ROUTE) 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) if (IS_ZEBRA_DEBUG_RECV)
zlog_debug("%s: adding seg6", __func__); 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) { 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); nh = nhg_ctx_get_nh(*ctx);
nexthop_del_labels(nh); nexthop_del_labels(nh);
nexthop_del_seg6local(nh); nexthop_del_srv6_seg6local(nh);
nexthop_del_seg6(nh); nexthop_del_srv6_seg6(nh);
done: done:
XFREE(MTYPE_NHG_CTX, *ctx); 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. */ /* The copy may have allocated labels; free them if necessary. */
nexthop_del_labels(&lookup); nexthop_del_labels(&lookup);
nexthop_del_seg6local(&lookup); nexthop_del_srv6_seg6local(&lookup);
nexthop_del_seg6(&lookup); nexthop_del_srv6_seg6(&lookup);
if (IS_ZEBRA_DEBUG_NHG_DETAIL) if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug("%s: nh %pNHv => %p (%u)", 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)); sizeof(buf), 1));
} }
if (nexthop->nh_seg6local_ctx) { if (nexthop->nh_srv6) {
seg6local_context2str(buf, sizeof(buf), seg6local_context2str(buf, sizeof(buf),
nexthop->nh_seg6local_ctx, &nexthop->nh_srv6->seg6local_ctx,
nexthop->nh_seg6local_action); nexthop->nh_srv6->seg6local_action);
vty_out(vty, ", seg6local %s %s", vty_out(vty, ", seg6local %s %s",
seg6local_action2str(nexthop->nh_seg6local_action), seg6local_action2str(nexthop->nh_srv6->seg6local_action),
buf); buf);
}
if (nexthop->nh_seg6_segs) { inet_ntop(AF_INET6, &nexthop->nh_srv6->seg6_segs, buf, sizeof(buf));
inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
vty_out(vty, ", seg6 %s", 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", json_object_int_add(json_nexthop, "srteColor",
nexthop->srte_color); nexthop->srte_color);
if (nexthop->nh_seg6local_ctx) { if (nexthop->nh_srv6) {
json_seg6local = json_object_new_object(); json_seg6local = json_object_new_object();
json_object_string_add( json_object_string_add(
json_seg6local, "action", json_seg6local, "action",
seg6local_action2str(nexthop->nh_seg6local_action)); seg6local_action2str(nexthop->nh_srv6->seg6local_action));
json_object_object_add(json_nexthop, "seg6local", json_object_object_add(json_nexthop, "seg6local",
json_seg6local); json_seg6local);
}
if (nexthop->nh_seg6_segs) {
json_seg6 = json_object_new_object(); 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_string_add(json_seg6, "segs", buf);
json_object_object_add(json_nexthop, "seg6", json_seg6); json_object_object_add(json_nexthop, "seg6", json_seg6);
} }