diff options
author | Mark Stapp <mjs.ietf@gmail.com> | 2023-05-08 20:36:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-08 20:36:07 +0200 |
commit | eb4c026d13af32ea80ef264e86e63f7b7115a37b (patch) | |
tree | a99d14c899a27265ad144863f49bbc988ad3525a | |
parent | Merge pull request #13464 from sri-mohan1/srib-ldpd (diff) | |
parent | zebra:re-install dependent nhgs on interface up (diff) | |
download | frr-eb4c026d13af32ea80ef264e86e63f7b7115a37b.tar.xz frr-eb4c026d13af32ea80ef264e86e63f7b7115a37b.zip |
Merge pull request #13413 from chiragshah6/fdev2
zebra: re-install NHG on interface up
-rw-r--r-- | lib/nexthop.c | 9 | ||||
-rw-r--r-- | lib/nexthop.h | 3 | ||||
-rw-r--r-- | zebra/redistribute.c | 4 | ||||
-rw-r--r-- | zebra/zebra_nhg.c | 87 | ||||
-rw-r--r-- | zebra/zebra_nhg.h | 1 |
5 files changed, 100 insertions, 4 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c index b04c95c05..dcbb76b68 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -1076,3 +1076,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; +} diff --git a/lib/nexthop.h b/lib/nexthop.h index 1d95a3eee..43dd71e11 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -234,6 +234,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 diff --git a/zebra/redistribute.c b/zebra/redistribute.c index d2fa85eb6..6767000f3 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -548,6 +548,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. */ diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 8616b1405..96e021292 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1125,13 +1125,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); + } + } } /* @@ -3080,6 +3090,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); @@ -3106,7 +3122,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; } } @@ -3180,7 +3196,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)) @@ -3651,3 +3667,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); + } + } + } +} diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index b178007b4..6179be344 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -358,6 +358,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; |