Skip to content

Commit

Permalink
Merge pull request #15362 from FRRouting/mergify/bp/stable/8.5/pr-13413
Browse files Browse the repository at this point in the history
zebra: re-install NHG on interface up (backport #13413)
  • Loading branch information
ton31337 authored Feb 13, 2024
2 parents b37e00c + a955b60 commit 24f1d45
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
9 changes: 9 additions & 0 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1092,3 +1092,12 @@ static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea,
}
return -1;
}

bool nexthop_is_ifindex_type(const struct nexthop *nh)
{
if (nh->type == NEXTHOP_TYPE_IFINDEX ||
nh->type == NEXTHOP_TYPE_IPV4_IFINDEX ||
nh->type == NEXTHOP_TYPE_IPV6_IFINDEX)
return true;
return false;
}
3 changes: 3 additions & 0 deletions lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ extern struct nexthop *nexthop_dup(const struct nexthop *nexthop,
extern struct nexthop *nexthop_dup_no_recurse(const struct nexthop *nexthop,
struct nexthop *rparent);

/* Check nexthop of IFINDEX type */
extern bool nexthop_is_ifindex_type(const struct nexthop *nh);

/*
* 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
4 changes: 4 additions & 0 deletions zebra/redistribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@ void zebra_interface_address_add_update(struct interface *ifp,
client, ifp, ifc);
}
}
/* interface associated NHGs may have been deleted,
* re-sync zebra -> dplane NHGs
*/
zebra_interface_nhg_reinstall(ifp);
}

/* Interface address deletion. */
Expand Down
87 changes: 83 additions & 4 deletions zebra/zebra_nhg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,13 +1140,23 @@ static void zebra_nhg_handle_uninstall(struct nhg_hash_entry *nhe)
zebra_nhg_free(nhe);
}

static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe)
static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install)
{
/* Update validity of groups depending on it */
struct nhg_connected *rb_node_dep;

frr_each_safe(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep)
frr_each_safe (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
zebra_nhg_set_valid(rb_node_dep->nhe);
/* install dependent NHG into kernel */
if (install) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug(
"%s nh id %u (flags 0x%x) associated dependent NHG %pNG install",
__func__, nhe->id, nhe->flags,
rb_node_dep->nhe);
zebra_nhg_install_kernel(rb_node_dep->nhe);
}
}
}

/*
Expand Down Expand Up @@ -3006,6 +3016,12 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
/* Resolve it first */
nhe = zebra_nhg_resolve(nhe);

if (zebra_nhg_set_valid_if_active(nhe)) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug("%s: valid flag set for nh %pNG", __func__,
nhe);
}

/* Make sure all depends are installed/queued */
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
zebra_nhg_install_kernel(rb_node_dep->nhe);
Expand All @@ -3032,7 +3048,7 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
break;
case ZEBRA_DPLANE_REQUEST_SUCCESS:
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
zebra_nhg_handle_install(nhe);
zebra_nhg_handle_install(nhe, false);
break;
}
}
Expand Down Expand Up @@ -3106,7 +3122,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
zebra_nhg_handle_install(nhe);
zebra_nhg_handle_install(nhe, true);

/* If daemon nhg, send it an update */
if (PROTO_OWNED(nhe))
Expand Down Expand Up @@ -3588,3 +3604,66 @@ static ssize_t printfrr_nhghe(struct fbuf *buf, struct printfrr_eargs *ea,
ret += bputs(buf, "]");
return ret;
}

/*
* On interface add the nexthop that resolves to this intf needs
* a re-install. There are following scenarios when the nexthop group update
* gets skipped:
* 1. When upper level protocol sends removal of NHG, there is
* timer running to keep NHG for 180 seconds, during this interval, same route
* with same set of nexthops installation is given , the same NHG is used
* but since NHG is not reinstalled on interface address add, it is not aware
* in Dplan/Kernel.
* 2. Due to a quick port flap due to interface add and delete
* to be processed in same queue one after another. Zebra believes that
* there is no change in nhg in this case. Hence this re-install will
* make sure the nexthop group gets updated to Dplan/Kernel.
*/
void zebra_interface_nhg_reinstall(struct interface *ifp)
{
struct nhg_connected *rb_node_dep = NULL;
struct zebra_if *zif = ifp->info;
struct nexthop *nh;

if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug(
"%s: Installing interface %s associated NHGs into kernel",
__func__, ifp->name);

frr_each (nhg_connected_tree, &zif->nhg_dependents, rb_node_dep) {
nh = rb_node_dep->nhe->nhg.nexthop;
if (zebra_nhg_set_valid_if_active(rb_node_dep->nhe)) {
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
zlog_debug(
"%s: Setting the valid flag for nhe %pNG, interface: %s",
__func__, rb_node_dep->nhe, ifp->name);
}
/* Check for singleton NHG associated to interface */
if (nexthop_is_ifindex_type(nh) &&
zebra_nhg_depends_is_empty(rb_node_dep->nhe)) {
struct nhg_connected *rb_node_dependent;

if (IS_ZEBRA_DEBUG_NHG)
zlog_debug(
"%s install nhe %pNG nh type %u flags 0x%x",
__func__, rb_node_dep->nhe, nh->type,
rb_node_dep->nhe->flags);
zebra_nhg_install_kernel(rb_node_dep->nhe);

/* mark depedent uninstall, when interface associated
* singleton is installed, install depedent
*/
frr_each_safe (nhg_connected_tree,
&rb_node_dep->nhe->nhg_dependents,
rb_node_dependent) {
if (IS_ZEBRA_DEBUG_NHG)
zlog_debug(
"%s dependent nhe %pNG unset installed flag",
__func__,
rb_node_dependent->nhe);
UNSET_FLAG(rb_node_dependent->nhe->flags,
NEXTHOP_GROUP_INSTALLED);
}
}
}
}
1 change: 1 addition & 0 deletions zebra/zebra_nhg.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
/* Dataplane install/uninstall */
extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
extern void zebra_interface_nhg_reinstall(struct interface *ifp);

/* Forward ref of dplane update context type */
struct zebra_dplane_ctx;
Expand Down

0 comments on commit 24f1d45

Please sign in to comment.