Skip to content

Commit

Permalink
zebra&bgpd : Add PIC support in the srv6 VPN scenario.
Browse files Browse the repository at this point in the history
This PR implements the separation of nh_srv6-related information, which was originally stored in the nexthop, in the srv6-vpn scenario. It generates a new pic nexthop that contains only the next-hop forwarding information. Meanwhile, the original nexthop containing nh_srv6 is used as pic context information and indexed separately.

Signed-off-by: hanyu.zly&freddy <[email protected]>
  • Loading branch information
zice312963205 committed Sep 20, 2024
1 parent 40c9d64 commit ad254d2
Show file tree
Hide file tree
Showing 24 changed files with 575 additions and 72 deletions.
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

0 comments on commit ad254d2

Please sign in to comment.