zebra: Embed lib nexthop-group in zebra hash entry

Embed nexthop-group, which is just a pointer, in the zebra
nexthop-hash-entry object, rather than mallocing one.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
Mark Stapp 2020-02-25 08:29:46 -05:00
parent c13bfa7435
commit c415d89528
13 changed files with 97 additions and 96 deletions

View file

@ -648,7 +648,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
if (rmap_name) if (rmap_name)
ret = zebra_import_table_route_map_check( ret = zebra_import_table_route_map_check(
afi, re->type, re->instance, &rn->p, afi, re->type, re->instance, &rn->p,
re->nhe->nhg->nexthop, re->nhe->nhg.nexthop,
zvrf->vrf->vrf_id, re->tag, rmap_name); zvrf->vrf->vrf_id, re->tag, rmap_name);
if (ret != RMAP_PERMITMATCH) { if (ret != RMAP_PERMITMATCH) {
@ -685,7 +685,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
newre->instance = re->table; newre->instance = re->table;
ng = nexthop_group_new(); ng = nexthop_group_new();
copy_nexthops(&ng->nexthop, re->nhe->nhg->nexthop, NULL); copy_nexthops(&ng->nexthop, re->nhe->nhg.nexthop, NULL);
rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng); rib_add_multipath(afi, SAFI_UNICAST, &p, NULL, newre, ng);
@ -702,7 +702,7 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
prefix_copy(&p, &rn->p); prefix_copy(&p, &rn->p);
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
re->table, re->flags, &p, NULL, re->nhe->nhg->nexthop, re->table, re->flags, &p, NULL, re->nhe->nhg.nexthop,
re->nhe_id, zvrf->table_id, re->metric, re->distance, re->nhe_id, zvrf->table_id, re->metric, re->distance,
false); false);

View file

@ -515,7 +515,7 @@ static inline struct nexthop_group *rib_active_nhg(struct route_entry *re)
if (re->fib_ng.nexthop) if (re->fib_ng.nexthop)
return &(re->fib_ng); return &(re->fib_ng);
else else
return re->nhe->nhg; return &(re->nhe->nhg);
} }
extern void zebra_vty_init(void); extern void zebra_vty_init(void);

View file

@ -580,7 +580,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client,
memcpy(&api.src_prefix, src_p, sizeof(api.src_prefix)); memcpy(&api.src_prefix, src_p, sizeof(api.src_prefix));
} }
for (nexthop = re->nhe->nhg->nexthop; for (nexthop = re->nhe->nhg.nexthop;
nexthop; nexthop = nexthop->next) { nexthop; nexthop = nexthop->next) {
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
continue; continue;
@ -689,7 +689,7 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
* nexthop we are looking up. Therefore, we will just iterate * nexthop we are looking up. Therefore, we will just iterate
* over the top chain of nexthops. * over the top chain of nexthops.
*/ */
for (nexthop = re->nhe->nhg->nexthop; nexthop; for (nexthop = re->nhe->nhg.nexthop; nexthop;
nexthop = nexthop->next) nexthop = nexthop->next)
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
num += zserv_encode_nexthop(s, nexthop); num += zserv_encode_nexthop(s, nexthop);

View file

@ -1513,9 +1513,9 @@ static int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx,
/* Copy nexthops; recursive info is included too */ /* Copy nexthops; recursive info is included too */
copy_nexthops(&(ctx->u.rinfo.zd_ng.nexthop), copy_nexthops(&(ctx->u.rinfo.zd_ng.nexthop),
re->nhe->nhg->nexthop, NULL); re->nhe->nhg.nexthop, NULL);
/* Ensure that the dplane's nexthops flags are clear. */ /* Ensure that the dplane nexthops' flags are clear. */
for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop)) for (ALL_NEXTHOPS(ctx->u.rinfo.zd_ng, nexthop))
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
@ -1596,9 +1596,9 @@ static int dplane_ctx_nexthop_init(struct zebra_dplane_ctx *ctx,
ctx->u.rinfo.nhe.vrf_id = nhe->vrf_id; ctx->u.rinfo.nhe.vrf_id = nhe->vrf_id;
ctx->u.rinfo.nhe.type = nhe->type; ctx->u.rinfo.nhe.type = nhe->type;
nexthop_group_copy(&(ctx->u.rinfo.nhe.ng), nhe->nhg); nexthop_group_copy(&(ctx->u.rinfo.nhe.ng), &(nhe->nhg));
/* If its a group, convert it to a grp array of ids */ /* If this is a group, convert it to a grp array of ids */
if (!zebra_nhg_depends_is_empty(nhe) if (!zebra_nhg_depends_is_empty(nhe)
&& !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE)) && !CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSIVE))
ctx->u.rinfo.nhe.nh_grp_count = zebra_nhg_nhe2grp( ctx->u.rinfo.nhe.nh_grp_count = zebra_nhg_nhe2grp(
@ -1753,7 +1753,7 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
if (re) if (re)
copy_nexthops(&(ctx->u.pw.nhg.nexthop), copy_nexthops(&(ctx->u.pw.nhg.nexthop),
re->nhe->nhg->nexthop, NULL); re->nhe->nhg.nexthop, NULL);
route_unlock_node(rn); route_unlock_node(rn);
} }
@ -1849,7 +1849,7 @@ dplane_route_update_internal(struct route_node *rn,
* We'll need these to do per-nexthop deletes. * We'll need these to do per-nexthop deletes.
*/ */
copy_nexthops(&(ctx->u.rinfo.zd_old_ng.nexthop), copy_nexthops(&(ctx->u.rinfo.zd_old_ng.nexthop),
old_re->nhe->nhg->nexthop, NULL); old_re->nhe->nhg.nexthop, NULL);
#endif /* !HAVE_NETLINK */ #endif /* !HAVE_NETLINK */
} }

View file

@ -309,7 +309,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
ri->rtm_type = RTN_UNICAST; ri->rtm_type = RTN_UNICAST;
ri->metric = &re->metric; ri->metric = &re->metric;
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
if (ri->num_nhs >= zrouter.multipath_num) if (ri->num_nhs >= zrouter.multipath_num)
break; break;

View file

@ -186,7 +186,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
* the label advertised by the recursive nexthop (plus we don't have the * the label advertised by the recursive nexthop (plus we don't have the
* logic yet to push multiple labels). * logic yet to push multiple labels).
*/ */
for (nexthop = re->nhe->nhg->nexthop; for (nexthop = re->nhe->nhg.nexthop;
nexthop; nexthop = nexthop->next) { nexthop; nexthop = nexthop->next) {
/* Skip inactive and recursive entries. */ /* Skip inactive and recursive entries. */
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
@ -638,7 +638,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
|| !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED)) || !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))
continue; continue;
for (match_nh = match->nhe->nhg->nexthop; match_nh; for (match_nh = match->nhe->nhg.nexthop; match_nh;
match_nh = match_nh->next) { match_nh = match_nh->next) {
if (match->type == ZEBRA_ROUTE_CONNECT if (match->type == ZEBRA_ROUTE_CONNECT
|| nexthop->ifindex == match_nh->ifindex) { || nexthop->ifindex == match_nh->ifindex) {
@ -689,10 +689,10 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
break; break;
} }
if (!match || !match->nhe->nhg->nexthop) if (!match || !match->nhe->nhg.nexthop)
return 0; return 0;
nexthop->ifindex = match->nhe->nhg->nexthop->ifindex; nexthop->ifindex = match->nhe->nhg.nexthop->ifindex;
return 1; return 1;
} }
@ -2631,7 +2631,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
* We can't just change the values here since we are hashing * We can't just change the values here since we are hashing
* on labels. We need to create a whole new group * on labels. We need to create a whole new group
*/ */
nexthop_group_copy(&new_grp, re->nhe->nhg); nexthop_group_copy(&new_grp, &(re->nhe->nhg));
found = false; found = false;
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) { for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
@ -2712,7 +2712,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
if (re == NULL) if (re == NULL)
return -1; return -1;
nexthop_group_copy(&new_grp, re->nhe->nhg); nexthop_group_copy(&new_grp, &(re->nhe->nhg));
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next)
nexthop_del_labels(nexthop); nexthop_del_labels(nexthop);
@ -2949,7 +2949,7 @@ static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
RNODE_FOREACH_RE (rn, re) { RNODE_FOREACH_RE (rn, re) {
struct nexthop_group new_grp = {}; struct nexthop_group new_grp = {};
nexthop_group_copy(&new_grp, re->nhe->nhg); nexthop_group_copy(&new_grp, &(re->nhe->nhg));
for (nexthop = new_grp.nexthop; nexthop; for (nexthop = new_grp.nexthop; nexthop;
nexthop = nexthop->next) { nexthop = nexthop->next) {

View file

@ -315,20 +315,20 @@ zebra_nhg_connect_depends(struct nhg_hash_entry *nhe,
} }
/* Add the ifp now if its not a group or recursive and has ifindex */ /* Add the ifp now if its not a group or recursive and has ifindex */
if (zebra_nhg_depends_is_empty(nhe) && nhe->nhg->nexthop if (zebra_nhg_depends_is_empty(nhe) && nhe->nhg.nexthop
&& nhe->nhg->nexthop->ifindex) { && nhe->nhg.nexthop->ifindex) {
struct interface *ifp = NULL; struct interface *ifp = NULL;
ifp = if_lookup_by_index(nhe->nhg->nexthop->ifindex, ifp = if_lookup_by_index(nhe->nhg.nexthop->ifindex,
nhe->nhg->nexthop->vrf_id); nhe->nhg.nexthop->vrf_id);
if (ifp) if (ifp)
zebra_nhg_set_if(nhe, ifp); zebra_nhg_set_if(nhe, ifp);
else else
flog_err( flog_err(
EC_ZEBRA_IF_LOOKUP_FAILED, EC_ZEBRA_IF_LOOKUP_FAILED,
"Zebra failed to lookup an interface with ifindex=%d in vrf=%u for NHE id=%u", "Zebra failed to lookup an interface with ifindex=%d in vrf=%u for NHE id=%u",
nhe->nhg->nexthop->ifindex, nhe->nhg.nexthop->ifindex,
nhe->nhg->nexthop->vrf_id, nhe->id); nhe->nhg.nexthop->vrf_id, nhe->id);
} }
} }
@ -350,8 +350,7 @@ static struct nhg_hash_entry *zebra_nhg_copy(const struct nhg_hash_entry *copy,
nhe->id = id; nhe->id = id;
nhe->nhg = nexthop_group_new(); nexthop_group_copy(&(nhe->nhg), &(copy->nhg));
nexthop_group_copy(nhe->nhg, copy->nhg);
nhe->vrf_id = copy->vrf_id; nhe->vrf_id = copy->vrf_id;
nhe->afi = copy->afi; nhe->afi = copy->afi;
@ -371,7 +370,7 @@ static void *zebra_nhg_hash_alloc(void *arg)
nhe = zebra_nhg_copy(copy, copy->id); nhe = zebra_nhg_copy(copy, copy->id);
/* Mark duplicate nexthops in a group at creation time. */ /* Mark duplicate nexthops in a group at creation time. */
nexthop_group_mark_duplicates(nhe->nhg); nexthop_group_mark_duplicates(&(nhe->nhg));
zebra_nhg_connect_depends(nhe, copy->nhg_depends); zebra_nhg_connect_depends(nhe, copy->nhg_depends);
zebra_nhg_insert_id(nhe); zebra_nhg_insert_id(nhe);
@ -385,7 +384,8 @@ uint32_t zebra_nhg_hash_key(const void *arg)
uint32_t key = 0x5a351234; uint32_t key = 0x5a351234;
key = jhash_3words(nhe->vrf_id, nhe->afi, nexthop_group_hash(nhe->nhg), key = jhash_3words(nhe->vrf_id, nhe->afi,
nexthop_group_hash(&(nhe->nhg)),
key); key);
return key; return key;
@ -416,7 +416,7 @@ bool zebra_nhg_hash_equal(const void *arg1, const void *arg2)
return false; return false;
/* Nexthops should be sorted */ /* Nexthops should be sorted */
for (nexthop1 = nhe1->nhg->nexthop, nexthop2 = nhe2->nhg->nexthop; for (nexthop1 = nhe1->nhg.nexthop, nexthop2 = nhe2->nhg.nexthop;
nexthop1 || nexthop2; nexthop1 || nexthop2;
nexthop1 = nexthop1->next, nexthop2 = nexthop2->next) { nexthop1 = nexthop1->next, nexthop2 = nexthop2->next) {
if (nexthop1 && !nexthop2) if (nexthop1 && !nexthop2)
@ -498,7 +498,7 @@ static int zebra_nhg_process_grp(struct nexthop_group *nhg,
* in the kernel. * in the kernel.
*/ */
copy_nexthops(&nhg->nexthop, depend->nhg->nexthop, NULL); copy_nexthops(&nhg->nexthop, depend->nhg.nexthop, NULL);
} }
return 0; return 0;
@ -536,14 +536,14 @@ static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id,
lookup.id = id ? id : ++id_counter; lookup.id = id ? id : ++id_counter;
lookup.type = type ? type : ZEBRA_ROUTE_NHG; lookup.type = type ? type : ZEBRA_ROUTE_NHG;
lookup.nhg = nhg; lookup.nhg = *nhg;
lookup.vrf_id = vrf_id; lookup.vrf_id = vrf_id;
if (lookup.nhg->nexthop->next) { if (lookup.nhg.nexthop->next) {
/* Groups can have all vrfs and AF's in them */ /* Groups can have all vrfs and AF's in them */
lookup.afi = AFI_UNSPEC; lookup.afi = AFI_UNSPEC;
} else { } else {
switch (lookup.nhg->nexthop->type) { switch (lookup.nhg.nexthop->type) {
case (NEXTHOP_TYPE_IFINDEX): case (NEXTHOP_TYPE_IFINDEX):
case (NEXTHOP_TYPE_BLACKHOLE): case (NEXTHOP_TYPE_BLACKHOLE):
/* /*
@ -1206,7 +1206,8 @@ zebra_nhg_rib_find(uint32_t id, struct nexthop_group *nhg, afi_t rt_afi)
static void zebra_nhg_free_members(struct nhg_hash_entry *nhe) static void zebra_nhg_free_members(struct nhg_hash_entry *nhe)
{ {
nexthop_group_delete(&nhe->nhg); nexthops_free(nhe->nhg.nexthop);
/* Decrement to remove connection ref */ /* Decrement to remove connection ref */
nhg_connected_tree_decrement_ref(&nhe->nhg_depends); nhg_connected_tree_decrement_ref(&nhe->nhg_depends);
nhg_connected_tree_free(&nhe->nhg_depends); nhg_connected_tree_free(&nhe->nhg_depends);
@ -1533,7 +1534,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
if (match->type == ZEBRA_ROUTE_CONNECT) { if (match->type == ZEBRA_ROUTE_CONNECT) {
/* Directly point connected route. */ /* Directly point connected route. */
newhop = match->nhe->nhg->nexthop; newhop = match->nhe->nhg.nexthop;
if (newhop) { if (newhop) {
if (nexthop->type == NEXTHOP_TYPE_IPV4 if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV6) || nexthop->type == NEXTHOP_TYPE_IPV6)
@ -1542,7 +1543,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
return 1; return 1;
} else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) { } else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
resolved = 0; resolved = 0;
for (ALL_NEXTHOPS_PTR(match->nhe->nhg, newhop)) { for (ALL_NEXTHOPS(match->nhe->nhg, newhop)) {
if (!CHECK_FLAG(match->status, if (!CHECK_FLAG(match->status,
ROUTE_ENTRY_INSTALLED)) ROUTE_ENTRY_INSTALLED))
continue; continue;
@ -1563,7 +1564,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
return resolved; return resolved;
} else if (re->type == ZEBRA_ROUTE_STATIC) { } else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0; resolved = 0;
for (ALL_NEXTHOPS_PTR(match->nhe->nhg, newhop)) { for (ALL_NEXTHOPS(match->nhe->nhg, newhop)) {
if (!CHECK_FLAG(match->status, if (!CHECK_FLAG(match->status,
ROUTE_ENTRY_INSTALLED)) ROUTE_ENTRY_INSTALLED))
continue; continue;
@ -1754,7 +1755,7 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED); UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
/* Copy over the nexthops in current state */ /* Copy over the nexthops in current state */
nexthop_group_copy(&new_grp, re->nhe->nhg); nexthop_group_copy(&new_grp, &(re->nhe->nhg));
for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) { for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
@ -1866,7 +1867,7 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
if (!duplicate) { if (!duplicate) {
grp[i].id = depend->id; grp[i].id = depend->id;
/* We aren't using weights for anything right now */ /* We aren't using weights for anything right now */
grp[i].weight = depend->nhg->nexthop->weight; grp[i].weight = depend->nhg.nexthop->weight;
i++; i++;
} }

View file

@ -40,16 +40,15 @@ struct nh_grp {
PREDECL_RBTREE_UNIQ(nhg_connected_tree); PREDECL_RBTREE_UNIQ(nhg_connected_tree);
/* /*
* Hashtables contiaining entries found in `zebra_router`. * Hashtables containing nhg entries is in `zebra_router`.
*/ */
struct nhg_hash_entry { struct nhg_hash_entry {
uint32_t id; uint32_t id;
afi_t afi; afi_t afi;
vrf_id_t vrf_id; vrf_id_t vrf_id;
int type; int type;
struct nexthop_group *nhg; struct nexthop_group nhg;
/* If this is not a group, it /* If this is not a group, it
* will be a single nexthop * will be a single nexthop

View file

@ -259,7 +259,7 @@ static int zebra_pw_check_reachability(struct zebra_pw *pw)
* Need to ensure that there's a label binding for all nexthops. * Need to ensure that there's a label binding for all nexthops.
* Otherwise, ECMP for this route could render the pseudowire unusable. * Otherwise, ECMP for this route could render the pseudowire unusable.
*/ */
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
if (!nexthop->nh_label) { if (!nexthop->nh_label) {
if (IS_ZEBRA_DEBUG_PW) if (IS_ZEBRA_DEBUG_PW)
zlog_debug("%s: unlabeled route for %s", zlog_debug("%s: unlabeled route for %s",

View file

@ -198,8 +198,8 @@ int zebra_check_addr(const struct prefix *p)
*/ */
void route_entry_copy_nexthops(struct route_entry *re, struct nexthop *nh) void route_entry_copy_nexthops(struct route_entry *re, struct nexthop *nh)
{ {
assert(!re->nhe->nhg->nexthop); assert(!re->nhe->nhg.nexthop);
copy_nexthops(&re->nhe->nhg->nexthop, nh, NULL); copy_nexthops(&re->nhe->nhg.nexthop, nh, NULL);
} }
static void route_entry_attach_ref(struct route_entry *re, static void route_entry_attach_ref(struct route_entry *re,
@ -217,12 +217,14 @@ int route_entry_update_nhe(struct route_entry *re, struct nhg_hash_entry *new)
int ret = 0; int ret = 0;
if (new == NULL) { if (new == NULL) {
re->nhe->nhg = NULL; if (re->nhe)
zebra_nhg_decrement_ref(re->nhe);
re->nhe = NULL;
goto done; goto done;
} }
if (re->nhe_id != new->id) { if (re->nhe_id != new->id) {
old = zebra_nhg_lookup_id(re->nhe_id); old = re->nhe;
route_entry_attach_ref(re, new); route_entry_attach_ref(re, new);
@ -404,7 +406,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
if (re->type != ZEBRA_ROUTE_BGP) if (re->type != ZEBRA_ROUTE_BGP)
return 0; return 0;
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
if (!nexthop->nh_label || !nexthop->nh_label->num_labels) if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
return 0; return 0;
@ -428,7 +430,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
srcdest_rnode_prefixes(rn, &p, &src_p); srcdest_rnode_prefixes(rn, &p, &src_p);
if (info->safi != SAFI_UNICAST) { if (info->safi != SAFI_UNICAST) {
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
return; return;
} }
@ -437,7 +439,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
/* /*
* Install the resolved nexthop object first. * Install the resolved nexthop object first.
*/ */
zebra_nhg_install_kernel(zebra_nhg_lookup_id(re->nhe_id)); zebra_nhg_install_kernel(re->nhe);
/* /*
* If this is a replace to a new RE let the originator of the RE * If this is a replace to a new RE let the originator of the RE
@ -506,7 +508,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
if (info->safi != SAFI_UNICAST) { if (info->safi != SAFI_UNICAST) {
UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
return; return;
} }
@ -566,7 +568,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
re->fib_ng.nexthop = NULL; re->fib_ng.nexthop = NULL;
} }
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
} }
@ -742,7 +744,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
/* Update real nexthop. This may actually determine if nexthop is active /* Update real nexthop. This may actually determine if nexthop is active
* or not. */ * or not. */
if (!nexthop_group_active_nexthop_num(new->nhe->nhg)) { if (!nexthop_group_active_nexthop_num(&(new->nhe->nhg))) {
UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED); UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
return; return;
} }
@ -811,7 +813,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
/* Update the nexthop; we could determine here that nexthop is /* Update the nexthop; we could determine here that nexthop is
* inactive. */ * inactive. */
if (nexthop_group_active_nexthop_num(new->nhe->nhg)) if (nexthop_group_active_nexthop_num(&(new->nhe->nhg)))
nh_active = 1; nh_active = 1;
/* If nexthop is active, install the selected route, if /* If nexthop is active, install the selected route, if
@ -929,7 +931,7 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
/* both are connected. are either loop or vrf? */ /* both are connected. are either loop or vrf? */
struct nexthop *nexthop = NULL; struct nexthop *nexthop = NULL;
for (ALL_NEXTHOPS_PTR(alternate->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(alternate->nhe->nhg, nexthop)) {
struct interface *ifp = if_lookup_by_index( struct interface *ifp = if_lookup_by_index(
nexthop->ifindex, alternate->vrf_id); nexthop->ifindex, alternate->vrf_id);
@ -937,7 +939,7 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
return alternate; return alternate;
} }
for (ALL_NEXTHOPS_PTR(current->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(current->nhe->nhg, nexthop)) {
struct interface *ifp = if_lookup_by_index( struct interface *ifp = if_lookup_by_index(
nexthop->ifindex, current->vrf_id); nexthop->ifindex, current->vrf_id);
@ -1269,7 +1271,7 @@ static void zebra_rib_fixup_system(struct route_node *rn)
SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nhop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nhop)) {
if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
continue; continue;
@ -1386,7 +1388,7 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
|| !CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_ACTIVE)) || !CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_ACTIVE))
ctx_nexthop = nexthop_next_active_resolved(ctx_nexthop); ctx_nexthop = nexthop_next_active_resolved(ctx_nexthop);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue; continue;
@ -2354,8 +2356,8 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
nhe = zebra_nhg_lookup_id(re->nhe_id); nhe = zebra_nhg_lookup_id(re->nhe_id);
if (nhe) if (nhe)
zebra_nhg_decrement_ref(nhe); zebra_nhg_decrement_ref(nhe);
} else if (re->nhe->nhg) } else if (re->nhe->nhg.nexthop)
nexthop_group_delete(&re->nhe->nhg); nexthops_free(re->nhe->nhg.nexthop);
nexthops_free(re->fib_ng.nexthop); nexthops_free(re->fib_ng.nexthop);
@ -2423,10 +2425,10 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
"%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u", "%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u",
straddr, re->metric, re->mtu, re->distance, re->flags, re->status); straddr, re->metric, re->mtu, re->distance, re->flags, re->status);
zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr, zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
nexthop_group_nexthop_num(re->nhe->nhg), nexthop_group_nexthop_num(&(re->nhe->nhg)),
nexthop_group_active_nexthop_num(re->nhe->nhg)); nexthop_group_active_nexthop_num(&(re->nhe->nhg)));
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
struct interface *ifp; struct interface *ifp;
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
@ -2784,7 +2786,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric) if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric)
continue; continue;
if (re->type == ZEBRA_ROUTE_CONNECT && if (re->type == ZEBRA_ROUTE_CONNECT &&
(rtnh = re->nhe->nhg->nexthop) (rtnh = re->nhe->nhg.nexthop)
&& rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) { && rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
if (rtnh->ifindex != nh->ifindex) if (rtnh->ifindex != nh->ifindex)
continue; continue;
@ -2802,7 +2804,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
same = re; same = re;
break; break;
} }
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, rtnh)) { for (ALL_NEXTHOPS(re->nhe->nhg, rtnh)) {
/* /*
* No guarantee all kernel send nh with labels * No guarantee all kernel send nh with labels
* on delete. * on delete.
@ -2844,7 +2846,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
if (allow_delete) { if (allow_delete) {
UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED); UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
/* Unset flags. */ /* Unset flags. */
for (rtnh = fib->nhe->nhg->nexthop; rtnh; for (rtnh = fib->nhe->nhg.nexthop; rtnh;
rtnh = rtnh->next) rtnh = rtnh->next)
UNSET_FLAG(rtnh->flags, UNSET_FLAG(rtnh->flags,
NEXTHOP_FLAG_FIB); NEXTHOP_FLAG_FIB);
@ -2900,7 +2902,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) { if (CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE)) {
struct nexthop *tmp_nh; struct nexthop *tmp_nh;
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, tmp_nh)) { for (ALL_NEXTHOPS(re->nhe->nhg, tmp_nh)) {
struct ipaddr vtep_ip; struct ipaddr vtep_ip;
memset(&vtep_ip, 0, sizeof(struct ipaddr)); memset(&vtep_ip, 0, sizeof(struct ipaddr));
@ -3224,7 +3226,7 @@ void rib_sweep_table(struct route_table *table)
* this decision needs to be revisited * this decision needs to be revisited
*/ */
SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) for (ALL_NEXTHOPS(re->nhe->nhg, nexthop))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
rib_uninstall_kernel(rn, re); rib_uninstall_kernel(rn, re);

View file

@ -54,7 +54,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, RNH, "Nexthop tracking object")
static void free_state(vrf_id_t vrf_id, struct route_entry *re, static void free_state(vrf_id_t vrf_id, struct route_entry *re,
struct route_node *rn); struct route_node *rn);
static void copy_state(struct rnh *rnh, struct route_entry *re, static void copy_state(struct rnh *rnh, const struct route_entry *re,
struct route_node *rn); struct route_node *rn);
static int compare_state(struct route_entry *r1, struct route_entry *r2); static int compare_state(struct route_entry *r1, struct route_entry *r2);
static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
@ -384,7 +384,7 @@ static void zebra_rnh_clear_nexthop_rnh_filters(struct route_entry *re)
struct nexthop *nexthop; struct nexthop *nexthop;
if (re) { if (re) {
for (nexthop = re->nhe->nhg->nexthop; nexthop; for (nexthop = re->nhe->nhg.nexthop; nexthop;
nexthop = nexthop->next) { nexthop = nexthop->next) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RNH_FILTERED); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RNH_FILTERED);
} }
@ -403,7 +403,7 @@ static int zebra_rnh_apply_nht_rmap(afi_t afi, struct zebra_vrf *zvrf,
route_map_result_t ret; route_map_result_t ret;
if (prn && re) { if (prn && re) {
for (nexthop = re->nhe->nhg->nexthop; nexthop; for (nexthop = re->nhe->nhg.nexthop; nexthop;
nexthop = nexthop->next) { nexthop = nexthop->next) {
ret = zebra_nht_route_map_check( ret = zebra_nht_route_map_check(
afi, proto, &prn->p, zvrf, re, nexthop); afi, proto, &prn->p, zvrf, re, nexthop);
@ -688,7 +688,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
/* Just being SELECTED isn't quite enough - must /* Just being SELECTED isn't quite enough - must
* have an installed nexthop to be useful. * have an installed nexthop to be useful.
*/ */
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
if (rnh_nexthop_valid(re, nexthop)) if (rnh_nexthop_valid(re, nexthop))
break; break;
} }
@ -707,7 +707,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
break; break;
if (re->type == ZEBRA_ROUTE_NHRP) { if (re->type == ZEBRA_ROUTE_NHRP) {
for (nexthop = re->nhe->nhg->nexthop; for (nexthop = re->nhe->nhg.nexthop;
nexthop; nexthop;
nexthop = nexthop->next) nexthop = nexthop->next)
if (nexthop->type if (nexthop->type
@ -945,7 +945,7 @@ static void free_state(vrf_id_t vrf_id, struct route_entry *re,
XFREE(MTYPE_RE, re); XFREE(MTYPE_RE, re);
} }
static void copy_state(struct rnh *rnh, struct route_entry *re, static void copy_state(struct rnh *rnh, const struct route_entry *re,
struct route_node *rn) struct route_node *rn)
{ {
struct route_entry *state; struct route_entry *state;
@ -966,9 +966,8 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
state->status = re->status; state->status = re->status;
state->nhe = zebra_nhg_alloc(); state->nhe = zebra_nhg_alloc();
state->nhe->nhg = nexthop_group_new();
nexthop_group_copy(state->nhe->nhg, re->nhe->nhg); nexthop_group_copy(&(state->nhe->nhg), &(re->nhe->nhg));
rnh->state = state; rnh->state = state;
} }
@ -986,12 +985,12 @@ static int compare_state(struct route_entry *r1, struct route_entry *r2)
if (r1->metric != r2->metric) if (r1->metric != r2->metric)
return 1; return 1;
if (nexthop_group_nexthop_num(r1->nhe->nhg) if (nexthop_group_nexthop_num(&(r1->nhe->nhg))
!= nexthop_group_nexthop_num(r2->nhe->nhg)) != nexthop_group_nexthop_num(&(r2->nhe->nhg)))
return 1; return 1;
if (nexthop_group_hash(r1->nhe->nhg) != if (nexthop_group_hash(&(r1->nhe->nhg)) !=
nexthop_group_hash(r2->nhe->nhg)) nexthop_group_hash(&(r2->nhe->nhg)))
return 1; return 1;
return 0; return 0;
@ -1043,7 +1042,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
num = 0; num = 0;
nump = stream_get_endp(s); nump = stream_get_endp(s);
stream_putc(s, 0); stream_putc(s, 0);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nh)) for (ALL_NEXTHOPS(re->nhe->nhg, nh))
if (rnh_nexthop_valid(re, nh)) { if (rnh_nexthop_valid(re, nh)) {
zapi_nexthop_from_nexthop(&znh, nh); zapi_nexthop_from_nexthop(&znh, nh);
zapi_nexthop_encode(s, &znh, 0 /* flags */); zapi_nexthop_encode(s, &znh, 0 /* flags */);
@ -1114,7 +1113,7 @@ static void print_rnh(struct route_node *rn, struct vty *vty)
if (rnh->state) { if (rnh->state) {
vty_out(vty, " resolved via %s\n", vty_out(vty, " resolved via %s\n",
zebra_route_string(rnh->state->type)); zebra_route_string(rnh->state->type));
for (nexthop = rnh->state->nhe->nhg->nexthop; nexthop; for (nexthop = rnh->state->nhe->nhg.nexthop; nexthop;
nexthop = nexthop->next) nexthop = nexthop->next)
print_nh(nexthop, vty); print_nh(nexthop, vty);
} else } else

View file

@ -285,8 +285,8 @@ static void check_replace(struct route_node *np2, struct route_entry *re2,
return; return;
} }
if (in_addr_cmp((uint8_t *)&(*re)->nhe->nhg->nexthop->gate.ipv4, if (in_addr_cmp((uint8_t *)&(*re)->nhe->nhg.nexthop->gate.ipv4,
(uint8_t *)&re2->nhe->nhg->nexthop->gate.ipv4) (uint8_t *)&re2->nhe->nhg.nexthop->gate.ipv4)
<= 0) <= 0)
return; return;
@ -372,7 +372,7 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
(uint8_t *)&dest)) { (uint8_t *)&dest)) {
RNODE_FOREACH_RE (*np, *re) { RNODE_FOREACH_RE (*np, *re) {
if (!in_addr_cmp((uint8_t *)&(*re)->nhe if (!in_addr_cmp((uint8_t *)&(*re)->nhe
->nhg->nexthop ->nhg.nexthop
->gate.ipv4, ->gate.ipv4,
(uint8_t *)&nexthop)) (uint8_t *)&nexthop))
if (proto if (proto
@ -407,7 +407,7 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
|| ((policy == policy2) && (proto == proto2) || ((policy == policy2) && (proto == proto2)
&& (in_addr_cmp( && (in_addr_cmp(
(uint8_t *)&re2->nhe (uint8_t *)&re2->nhe
->nhg->nexthop->gate.ipv4, ->nhg.nexthop->gate.ipv4,
(uint8_t *)&nexthop) (uint8_t *)&nexthop)
>= 0))) >= 0)))
check_replace(np2, re2, np, re); check_replace(np2, re2, np, re);
@ -432,7 +432,7 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
nexthop = (*re)->nhe->nhg->nexthop; nexthop = (*re)->nhe->nhg.nexthop;
if (nexthop) { if (nexthop) {
pnt = (uint8_t *)&nexthop->gate.ipv4; pnt = (uint8_t *)&nexthop->gate.ipv4;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -462,7 +462,7 @@ static uint8_t *ipFwTable(struct variable *v, oid objid[], size_t *objid_len,
if (!np) if (!np)
return NULL; return NULL;
nexthop = re->nhe->nhg->nexthop; nexthop = re->nhe->nhg.nexthop;
if (!nexthop) if (!nexthop)
return NULL; return NULL;

View file

@ -264,7 +264,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
if (show_ng) if (show_ng)
vty_out(vty, " Nexthop Group ID: %u\n", re->nhe_id); vty_out(vty, " Nexthop Group ID: %u\n", re->nhe_id);
for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
char addrstr[32]; char addrstr[32];
vty_out(vty, " %c%s", vty_out(vty, " %c%s",
@ -417,7 +417,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (is_fib) if (is_fib)
nhg = rib_active_nhg(re); nhg = rib_active_nhg(re);
else else
nhg = re->nhe->nhg; nhg = &(re->nhe->nhg);
if (json) { if (json) {
json_route = json_object_new_object(); json_route = json_object_new_object();
@ -470,10 +470,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_int_add(json_route, "internalFlags", json_object_int_add(json_route, "internalFlags",
re->flags); re->flags);
json_object_int_add(json_route, "internalNextHopNum", json_object_int_add(json_route, "internalNextHopNum",
nexthop_group_nexthop_num(re->nhe->nhg)); nexthop_group_nexthop_num(&(re->nhe->nhg)));
json_object_int_add(json_route, "internalNextHopActiveNum", json_object_int_add(json_route, "internalNextHopActiveNum",
nexthop_group_active_nexthop_num( nexthop_group_active_nexthop_num(
re->nhe->nhg)); &(re->nhe->nhg)));
if (uptime < ONE_DAY_SECOND) if (uptime < ONE_DAY_SECOND)
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
tm->tm_sec); tm->tm_sec);
@ -1149,7 +1149,7 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe)
vty_out(vty, "\n"); vty_out(vty, "\n");
} }
for (ALL_NEXTHOPS_PTR(nhe->nhg, nexthop)) { for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
vty_out(vty, " "); vty_out(vty, " ");
else else
@ -1970,7 +1970,7 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
fib_cnt[ZEBRA_ROUTE_TOTAL]++; fib_cnt[ZEBRA_ROUTE_TOTAL]++;
fib_cnt[re->type]++; fib_cnt[re->type]++;
} }
for (nexthop = re->nhe->nhg->nexthop; (!cnt && nexthop); for (nexthop = re->nhe->nhg.nexthop; (!cnt && nexthop);
nexthop = nexthop->next) { nexthop = nexthop->next) {
cnt++; cnt++;
rib_cnt[ZEBRA_ROUTE_TOTAL]++; rib_cnt[ZEBRA_ROUTE_TOTAL]++;