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

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
32 changes: 32 additions & 0 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,38 @@ 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
6 changes: 6 additions & 0 deletions lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ 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);

extern 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 All @@ -255,6 +259,8 @@ extern bool nexthop_is_blackhole(const struct nexthop *nh);
*/
int nexthop_str2backups(const char *str, int *num_backups,
uint8_t *backups);
extern void nexthop_copy_no_context(struct nexthop *copy, const struct nexthop *nexthop,
struct nexthop *rparent);

void nexthop_json_helper(json_object *json_nexthop,
const struct nexthop *nexthop, bool display_vrfid,
Expand Down
73 changes: 73 additions & 0 deletions lib/nexthop_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,67 @@ void nexthop_group_add_sorted(struct nexthop_group *nhg,
_nexthop_add_sorted(&nhg->nexthop, nexthop);
}

/* Add nexthop to sorted list of nexthops.
* The difference with _nexthop_add_sorted is that it filters out duplicate 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 @@ -430,6 +491,18 @@ void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
}
}

/* Copy a list of nexthops, filtered the part of context. */
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,6 +51,10 @@ 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);
bool nexthop_group_add_sorted_nodup(struct nexthop_group *nhg, struct nexthop *nexthop);

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);
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 @@ -425,6 +428,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
10 changes: 7 additions & 3 deletions zebra/dplane_fpm_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,9 +909,10 @@ 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 @@ -1059,6 +1060,9 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx)
case DPLANE_OP_NONE:
case DPLANE_OP_STARTUP_STAGE:
case DPLANE_OP_VLAN_INSTALL:
case DPLANE_OP_PIC_CONTEXT_DELETE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
break;

}
Expand Down
4 changes: 4 additions & 0 deletions zebra/kernel_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1654,6 +1654,10 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,

case DPLANE_OP_SRV6_ENCAP_SRCADDR_SET:
return netlink_put_sr_tunsrc_set_msg(bth, ctx);
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_PIC_CONTEXT_DELETE:
return FRR_NETLINK_SUCCESS;
}

return FRR_NETLINK_ERROR;
Expand Down
3 changes: 3 additions & 0 deletions zebra/kernel_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,9 @@ void kernel_update_multi(struct dplane_ctx_list_head *ctx_list)
case DPLANE_OP_SYS_ROUTE_DELETE:
case DPLANE_OP_ROUTE_NOTIFY:
case DPLANE_OP_LSP_NOTIFY:
case DPLANE_OP_PIC_CONTEXT_UPDATE:
case DPLANE_OP_PIC_CONTEXT_INSTALL:
case DPLANE_OP_PIC_CONTEXT_DELETE:
res = ZEBRA_DPLANE_REQUEST_SUCCESS;
break;

Expand Down
39 changes: 24 additions & 15 deletions zebra/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ struct mgmt_be_client *mgmt_be_client;
/* Route retain mode flag. */
int retain_mode = 0;

bool fpm_pic_nexthop;

/* Receive buffer size for kernel control sockets */
#define RCVBUFSIZE_MIN 4194304
#ifdef HAVE_NETLINK
Expand All @@ -82,22 +84,22 @@ uint32_t rt_table_main_id = RT_TABLE_MAIN;
#define OPTION_V6_WITH_V4_NEXTHOP 2002

/* Command line options. */
const struct option longopts[] = {
{ "batch", no_argument, NULL, 'b' },
{ "allow_delete", no_argument, NULL, 'a' },
{ "socket", required_argument, NULL, 'z' },
{ "ecmp", required_argument, NULL, 'e' },
{ "retain", no_argument, NULL, 'r' },
{ "asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD },
{ "v6-with-v4-nexthops", no_argument, NULL, OPTION_V6_WITH_V4_NEXTHOP },
const struct option longopts[] = { { "pic", no_argument, NULL, 'p' },
{ "batch", no_argument, NULL, 'b' },
{ "allow_delete", no_argument, NULL, 'a' },
{ "socket", required_argument, NULL, 'z' },
{ "ecmp", required_argument, NULL, 'e' },
{ "retain", no_argument, NULL, 'r' },
{ "asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD },
{ "v6-with-v4-nexthops", no_argument, NULL,
OPTION_V6_WITH_V4_NEXTHOP },
#ifdef HAVE_NETLINK
{ "vrfwnetns", no_argument, NULL, 'n' },
{ "nl-bufsize", required_argument, NULL, 's' },
{ "v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS },
{ "vrfwnetns", no_argument, NULL, 'n' },
{ "nl-bufsize", required_argument, NULL, 's' },
{ "v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS },
#endif /* HAVE_NETLINK */
{ "routing-table", optional_argument, NULL, 'R' },
{ 0 }
};
{ "routing-table", optional_argument, NULL, 'R' },
{ 0 } };

zebra_capabilities_t _caps_p[] = {ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN,
ZCAP_NET_RAW,
Expand Down Expand Up @@ -356,16 +358,19 @@ int main(int argc, char **argv)

zserv_path = NULL;

fpm_pic_nexthop = false;

vrf_configure_backend(VRF_BACKEND_VRF_LITE);

frr_preinit(&zebra_di, argc, argv);

frr_opt_add("baz:e:rK:s:R:"
frr_opt_add("pbaz:e:rK:s:R:"
#ifdef HAVE_NETLINK
"n"
#endif
,
longopts,
" -p, --pic Runs in pic mode\n"
" -b, --batch Runs in batch mode\n"
" -a, --allow_delete Allow other processes to delete zebra routes\n"
" -z, --socket Set path of zebra socket\n"
Expand Down Expand Up @@ -452,6 +457,10 @@ int main(int argc, char **argv)
v6_with_v4_nexthop = true;
break;
#endif /* HAVE_NETLINK */
case 'p':
fpm_pic_nexthop = true;
break;

default:
frr_help_exit(1);
}
Expand Down
6 changes: 6 additions & 0 deletions zebra/rib.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ struct route_entry {
uint32_t nhe_id;
uint32_t nhe_installed_id;

uint32_t pic_nhe_id;
uint32_t pic_nhe_installed_id;

/* Type of this route. */
int type;

Expand Down Expand Up @@ -471,6 +474,7 @@ extern int rib_gc_dest(struct route_node *rn);
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);

extern uint8_t route_distance(int type);
extern bool zebra_update_pic_nhe(struct route_node *rn);

extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
bool rt_delete);
Expand Down Expand Up @@ -641,6 +645,8 @@ void route_entry_dump_nh(const struct route_entry *re, const char *straddr,
/* Name of hook calls */
#define ZEBRA_ON_RIB_PROCESS_HOOK_CALL "on_rib_process_dplane_results"

extern bool fpm_pic_nexthop;

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading