mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 17:42:20 +00:00
Merge pull request #13413 from chiragshah6/fdev2
zebra: re-install NHG on interface up
This commit is contained in:
commit
eb4c026d13
@ -1076,3 +1076,12 @@ static ssize_t printfrr_nh(struct fbuf *buf, struct printfrr_eargs *ea,
|
|||||||
}
|
}
|
||||||
return -1;
|
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;
|
||||||
|
}
|
||||||
|
@ -234,6 +234,9 @@ extern struct nexthop *nexthop_dup(const struct nexthop *nexthop,
|
|||||||
extern struct nexthop *nexthop_dup_no_recurse(const struct nexthop *nexthop,
|
extern struct nexthop *nexthop_dup_no_recurse(const struct nexthop *nexthop,
|
||||||
struct nexthop *rparent);
|
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,
|
* 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
|
* into caller's array of uint8_ts. The array must be NEXTHOP_MAX_BACKUPS
|
||||||
|
@ -548,6 +548,10 @@ void zebra_interface_address_add_update(struct interface *ifp,
|
|||||||
client, ifp, ifc);
|
client, ifp, ifc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* interface associated NHGs may have been deleted,
|
||||||
|
* re-sync zebra -> dplane NHGs
|
||||||
|
*/
|
||||||
|
zebra_interface_nhg_reinstall(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface address deletion. */
|
/* Interface address deletion. */
|
||||||
|
@ -1125,13 +1125,23 @@ static void zebra_nhg_handle_uninstall(struct nhg_hash_entry *nhe)
|
|||||||
zebra_nhg_free(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 */
|
/* Update validity of groups depending on it */
|
||||||
struct nhg_connected *rb_node_dep;
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3080,6 +3090,12 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
|||||||
/* Resolve it first */
|
/* Resolve it first */
|
||||||
nhe = zebra_nhg_resolve(nhe);
|
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 */
|
/* Make sure all depends are installed/queued */
|
||||||
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
|
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
|
||||||
zebra_nhg_install_kernel(rb_node_dep->nhe);
|
zebra_nhg_install_kernel(rb_node_dep->nhe);
|
||||||
@ -3106,7 +3122,7 @@ void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
|
|||||||
break;
|
break;
|
||||||
case ZEBRA_DPLANE_REQUEST_SUCCESS:
|
case ZEBRA_DPLANE_REQUEST_SUCCESS:
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
|
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
|
||||||
zebra_nhg_handle_install(nhe);
|
zebra_nhg_handle_install(nhe, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3180,7 +3196,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||||||
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
|
if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
|
||||||
SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
|
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 daemon nhg, send it an update */
|
||||||
if (PROTO_OWNED(nhe))
|
if (PROTO_OWNED(nhe))
|
||||||
@ -3651,3 +3667,66 @@ static ssize_t printfrr_nhghe(struct fbuf *buf, struct printfrr_eargs *ea,
|
|||||||
ret += bputs(buf, "]");
|
ret += bputs(buf, "]");
|
||||||
return ret;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -358,6 +358,7 @@ extern uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
|
|||||||
/* Dataplane install/uninstall */
|
/* Dataplane install/uninstall */
|
||||||
extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
|
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_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
|
||||||
|
extern void zebra_interface_nhg_reinstall(struct interface *ifp);
|
||||||
|
|
||||||
/* Forward ref of dplane update context type */
|
/* Forward ref of dplane update context type */
|
||||||
struct zebra_dplane_ctx;
|
struct zebra_dplane_ctx;
|
||||||
|
Loading…
Reference in New Issue
Block a user