Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[preview]Add PIC support in the srv6 VPN scenario. #16879

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,7 @@ static void bgp_zebra_announce_parse_nexthop(
uint32_t ttl = 0;
uint32_t bos = 0;
uint32_t exp = 0;
bool src = false;
struct bgp_route_evpn *bre = NULL;

/* Determine if we're doing weighted ECMP or not */
Expand Down Expand Up @@ -1425,6 +1426,15 @@ static void bgp_zebra_announce_parse_nexthop(
memcpy(&api_nh->seg6_segs[0], sid_tmp,
sizeof(api_nh->seg6_segs[0]));

if (mpinfo->peer->connection->status == Established &&
mpinfo->peer->su_local->sa.sa_family == AF_INET6) {
memcpy(&api_nh->seg6_src,
&mpinfo->peer->su_local->sin6.sin6_addr,
sizeof(api_nh->seg6_src));
src = true;
}


if (mpinfo->attr->srv6_l3vpn &&
mpinfo->attr->srv6_l3vpn->transposition_len != 0) {
mpls_lse_decode(labels[0], &nh_label, &ttl,
Expand All @@ -1446,6 +1456,11 @@ static void bgp_zebra_announce_parse_nexthop(

api_nh->seg_num = 1;
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6);
if (src) {
SET_FLAG(api_nh->flags,
ZAPI_NEXTHOP_FLAG_SEG6_SRC);
src = false;
}
}

(*valid_nh_count)++;
Expand Down
41 changes: 40 additions & 1 deletion lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ void nexthop_del_srv6_seg6local(struct nexthop *nexthop)
}

void nexthop_add_srv6_seg6(struct nexthop *nexthop, const struct in6_addr *segs,
int num_segs)
const struct in6_addr *segs_src, int num_segs)
{
int i;

Expand All @@ -642,6 +642,9 @@ void nexthop_add_srv6_seg6(struct nexthop *nexthop, const struct in6_addr *segs,
for (i = 0; i < num_segs; i++)
memcpy(&nexthop->nh_srv6->seg6_segs->seg[i], &segs[i],
sizeof(struct in6_addr));
if (segs_src) {
nexthop->nh_srv6->seg6_src = *segs_src;
}
}

void nexthop_del_srv6_seg6(struct nexthop *nexthop)
Expand Down Expand Up @@ -888,6 +891,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
memcpy(&copy->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src));
memcpy(&copy->rmac, &nexthop->rmac, sizeof(nexthop->rmac));
copy->rparent = rparent;
copy->nh_encap.vni = nexthop->nh_encap.vni;
if (nexthop->nh_label)
nexthop_add_labels(copy, nexthop->nh_label_type,
nexthop->nh_label->num_labels,
Expand All @@ -904,6 +908,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy,
!sid_zero(nexthop->nh_srv6->seg6_segs))
nexthop_add_srv6_seg6(copy,
&nexthop->nh_srv6->seg6_segs->seg[0],
&nexthop->nh_srv6->seg6_src,
nexthop->nh_srv6->seg6_segs
->num_segs);
}
Expand Down Expand Up @@ -940,6 +945,40 @@ struct nexthop *nexthop_dup(const struct nexthop *nexthop,
return new;
}

void nexthop_copy_no_context(struct nexthop *copy, const struct nexthop *nexthop,
struct nexthop *rparent)
{
copy->vrf_id = nexthop->vrf_id;
copy->ifindex = nexthop->ifindex;
copy->type = nexthop->type;
copy->flags = nexthop->flags;
copy->weight = nexthop->weight;

assert(nexthop->backup_num < NEXTHOP_MAX_BACKUPS);
copy->backup_num = nexthop->backup_num;
if (copy->backup_num > 0)
memcpy(copy->backup_idx, nexthop->backup_idx, copy->backup_num);

copy->srte_color = nexthop->srte_color;
memcpy(&copy->gate, &nexthop->gate, sizeof(nexthop->gate));
memcpy(&copy->src, &nexthop->src, sizeof(nexthop->src));
memcpy(&copy->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src));
copy->rparent = rparent;

if (CHECK_FLAG(copy->flags, NEXTHOP_FLAG_RECURSIVE))
copy_nexthops_nocontext(&copy->resolved, nexthop->resolved,
copy);
}

struct nexthop *nexthop_dup_no_context(const struct nexthop *nexthop,
struct nexthop *rparent)
{
struct nexthop *new = nexthop_new();

nexthop_copy_no_context(new, nexthop, rparent);
return new;
}

/*
* Parse one or more backup index values, as comma-separated numbers,
* into caller's array of uint8_ts. The array must be NEXTHOP_MAX_BACKUPS
Expand Down
5 changes: 4 additions & 1 deletion lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ 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 *seg,
int num_segs);
const struct in6_addr *segs_src, int num_segs);
void nexthop_del_srv6_seg6(struct nexthop *nexthop);

/*
Expand Down Expand Up @@ -237,6 +237,9 @@ extern void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
extern void nexthop_copy_no_recurse(struct nexthop *copy,
const struct nexthop *nexthop,
struct nexthop *rparent);

struct nexthop *nexthop_dup_no_context(const struct nexthop *nexthop,
struct nexthop *rparent);
/* Duplicates a nexthop and returns the newly allocated nexthop */
extern struct nexthop *nexthop_dup(const struct nexthop *nexthop,
struct nexthop *rparent);
Expand Down
76 changes: 76 additions & 0 deletions lib/nexthop_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,69 @@ void nexthop_group_add_sorted(struct nexthop_group *nhg,
_nexthop_add_sorted(&nhg->nexthop, nexthop);
}


/* Add nexthop to sorted list of nexthops */
static bool _nexthop_add_no_dup(struct nexthop **head, struct nexthop *nexthop)
{
struct nexthop *position, *prev;
int ret = 0;

assert(!nexthop->next);

for (position = *head, prev = NULL; position;
prev = position, position = position->next) {
ret = nexthop_cmp(position, nexthop);
if (ret == 0)
return false;
else if (nexthop_cmp(position, nexthop) > 0) {
nexthop->next = position;
nexthop->prev = prev;

if (nexthop->prev)
nexthop->prev->next = nexthop;
else
*head = nexthop;

position->prev = nexthop;
return true;
}
}

nexthop->prev = prev;
if (prev)
prev->next = nexthop;
else
*head = nexthop;
return true;
}

bool nexthop_group_add_sorted_nodup(struct nexthop_group *nhg,
struct nexthop *nexthop)
{
struct nexthop *tail;
int ret = 0;

assert(!nexthop->next);

/* Try to just append to the end first;
* trust the list is already sorted
*/
tail = nexthop_group_tail(nhg);
if (tail) {
ret = nexthop_cmp(tail, nexthop);
if (ret == 0)
return false;
if (ret < 0) {
tail->next = nexthop;
nexthop->prev = tail;
return true;
}
}

return _nexthop_add_no_dup(&nhg->nexthop, nexthop);
}


/* Delete nexthop from a nexthop list. */
void _nexthop_del(struct nexthop_group *nhg, struct nexthop *nh)
{
Expand Down Expand Up @@ -433,6 +496,19 @@ void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
}
}

/* Copy a list of nexthops, no effort made to sort or order them. */
void copy_nexthops_nocontext(struct nexthop **tnh, const struct nexthop *nh,
struct nexthop *rparent)
{
struct nexthop *nexthop;
const struct nexthop *nh1;

for (nh1 = nh; nh1; nh1 = nh1->next) {
nexthop = nexthop_dup_no_context(nh1, rparent);
_nexthop_add(tnh, nexthop);
}
}

uint32_t nexthop_group_hash_no_recurse(const struct nexthop_group *nhg)
{
struct nexthop *nh;
Expand Down
4 changes: 4 additions & 0 deletions lib/nexthop_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ void nexthop_group_copy_nh_sorted(struct nexthop_group *nhg,
void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
struct nexthop *rparent);

void copy_nexthops_nocontext(struct nexthop **tnh, const struct nexthop *nh,
struct nexthop *rparent);
uint32_t nexthop_group_hash_no_recurse(const struct nexthop_group *nhg);
uint32_t nexthop_group_hash(const struct nexthop_group *nhg);
void nexthop_group_mark_duplicates(struct nexthop_group *nhg);

/* Add a nexthop to a list, enforcing the canonical sort order. */
void nexthop_group_add_sorted(struct nexthop_group *nhg,
struct nexthop *nexthop);
bool nexthop_group_add_sorted_nodup(struct nexthop_group *nhg,
struct nexthop *nexthop);

/* The following for loop allows to iterate over the nexthop
* structure of routes.
Expand Down
1 change: 1 addition & 0 deletions lib/srv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ struct nexthop_srv6 {

/* SRv6 Headend-behaviour */
struct seg6_seg_stack *seg6_segs;
struct in6_addr seg6_src;
};

/* SID format type */
Expand Down
22 changes: 20 additions & 2 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,9 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
stream_put(s, &api_nh->seg6_segs[0],
api_nh->seg_num * sizeof(struct in6_addr));
}
if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_SEG6_SRC))
stream_write(s, &api_nh->seg6_src, sizeof(struct in6_addr));

done:
return ret;
}
Expand Down Expand Up @@ -1463,6 +1466,9 @@ int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
api_nh->seg_num * sizeof(struct in6_addr));
}

if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6_SRC))
STREAM_GET(&api_nh->seg6_src, s, sizeof(struct in6_addr));

/* Success */
ret = 0;

Expand Down Expand Up @@ -2202,8 +2208,15 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
nexthop_add_srv6_seg6local(n, znh->seg6local_action,
&znh->seg6local_ctx);

if (znh->seg_num && !sid_zero_ipv6(znh->seg6_segs))
nexthop_add_srv6_seg6(n, &znh->seg6_segs[0], znh->seg_num);
if (znh->seg_num && !sid_zero_ipv6(znh->seg6_segs)) {
if (!sid_zero_ipv6(&znh->seg6_src))
nexthop_add_srv6_seg6(n, &znh->seg6_segs[0],
&znh->seg6_src, znh->seg_num);
else
nexthop_add_srv6_seg6(n, &znh->seg6_segs[0], NULL,
znh->seg_num);
}


return n;
}
Expand Down Expand Up @@ -2273,6 +2286,11 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
&nh->nh_srv6->seg6_segs->seg[i],
sizeof(struct in6_addr));
}
if (!sid_zero_ipv6(&nh->nh_srv6->seg6_src)) {
SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_SEG6_SRC);
memcpy(&znh->seg6_src, &nh->nh_srv6->seg6_src,
sizeof(struct in6_addr));
}
}

return 0;
Expand Down
9 changes: 9 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ struct zapi_nexthop {
/* SRv6 Headend-behaviour */
int seg_num;
struct in6_addr seg6_segs[SRV6_MAX_SEGS];
struct in6_addr seg6_src;
};

/*
Expand All @@ -476,6 +477,7 @@ struct zapi_nexthop {
#define ZAPI_NEXTHOP_FLAG_SEG6 0x10
#define ZAPI_NEXTHOP_FLAG_SEG6LOCAL 0x20
#define ZAPI_NEXTHOP_FLAG_EVPN 0x40
#define ZAPI_NEXTHOP_FLAG_SEG6_SRC 0x80

/*
* ZAPI Nexthop Group. For use with protocol creation of nexthop groups.
Expand Down Expand Up @@ -570,6 +572,13 @@ struct zapi_route {
*/
#define ZEBRA_FLAG_OUTOFSYNC 0x400

/*
* This flag lets us know that the route entry is set to bypass
* kernel for some reason (e.g. route-map, etc)
*/
#define ZEBRA_FLAG_KERNEL_BYPASS 0x800


/* The older XXX_MESSAGE flags live here */
uint32_t message;

Expand Down
2 changes: 1 addition & 1 deletion sharpd/sharp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ DEFPY (install_seg6_routes,
sg.r.nhop.gate.ipv6 = seg6_nh6;
sg.r.nhop.vrf_id = vrf->vrf_id;
sg.r.nhop_group.nexthop = &sg.r.nhop;
nexthop_add_srv6_seg6(&sg.r.nhop, &seg6_seg, 1);
nexthop_add_srv6_seg6(&sg.r.nhop, &seg6_seg, NULL, 1);

sg.r.vrf_id = vrf->vrf_id;
sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst, 0,
Expand Down
6 changes: 6 additions & 0 deletions zebra/dpdk/zebra_dplane_dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_NH_INSTALL:
case DPLANE_OP_NH_UPDATE:
case DPLANE_OP_NH_DELETE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_PIC_CONTEXT_DELETE:
case DPLANE_OP_LSP_INSTALL:
case DPLANE_OP_LSP_UPDATE:
case DPLANE_OP_LSP_DELETE:
Expand Down Expand Up @@ -424,6 +427,9 @@ static void zd_dpdk_process_update(struct zebra_dplane_ctx *ctx)
case DPLANE_OP_NH_INSTALL:
case DPLANE_OP_NH_UPDATE:
case DPLANE_OP_NH_DELETE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_PIC_CONTEXT_DELETE:
case DPLANE_OP_LSP_INSTALL:
case DPLANE_OP_LSP_UPDATE:
case DPLANE_OP_LSP_DELETE:
Expand Down
11 changes: 8 additions & 3 deletions zebra/dplane_fpm_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,9 +909,11 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
* If we were configured to not use next hop groups, then quit as soon
* as possible.
*/
if ((!fnc->use_nhg)
&& (op == DPLANE_OP_NH_DELETE || op == DPLANE_OP_NH_INSTALL
|| op == DPLANE_OP_NH_UPDATE))
if ((!fnc->use_nhg) &&
(op == DPLANE_OP_NH_DELETE || op == DPLANE_OP_NH_INSTALL ||
op == DPLANE_OP_NH_UPDATE || op == DPLANE_OP_PIC_CONTEXT_DELETE ||
op == DPLANE_OP_PIC_CONTEXT_INSTALL ||
op == DPLANE_OP_PIC_CONTEXT_UPDATE))
return 0;

nl_buf_len = 0;
Expand Down Expand Up @@ -1057,6 +1059,9 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
case DPLANE_OP_TC_FILTER_UPDATE:
case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
case DPLANE_OP_NONE:
case DPLANE_OP_PIC_CONTEXT_DELETE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_STARTUP_STAGE:
break;

Expand Down
3 changes: 3 additions & 0 deletions zebra/kernel_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1572,6 +1572,9 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
case DPLANE_OP_NH_INSTALL:
case DPLANE_OP_NH_UPDATE:
case DPLANE_OP_NH_DELETE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_PIC_CONTEXT_DELETE:
return netlink_put_nexthop_update_msg(bth, ctx);

case DPLANE_OP_LSP_INSTALL:
Expand Down
Loading
Loading