]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rib.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[mirror_frr.git] / zebra / zebra_rib.c
index c24a518afb2167379be65bb3bfba898d9a1a8849..f3112cc9c039bd564819e75cd8190fe60d529d95 100644 (file)
@@ -193,144 +193,47 @@ int zebra_check_addr(const struct prefix *p)
        return 1;
 }
 
-/* Add nexthop to the end of a rib node's nexthop list */
-void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop)
-{
-       _nexthop_group_add_sorted(re->ng, nexthop);
-}
-
-
 /**
  * copy_nexthop - copy a nexthop to the rib structure.
  */
 void route_entry_copy_nexthops(struct route_entry *re, struct nexthop *nh)
 {
-       assert(!re->ng->nexthop);
-       copy_nexthops(&re->ng->nexthop, nh, NULL);
-}
-
-/* Delete specified nexthop from the list. */
-void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop)
-{
-       if (nexthop->next)
-               nexthop->next->prev = nexthop->prev;
-       if (nexthop->prev)
-               nexthop->prev->next = nexthop->next;
-       else
-               re->ng->nexthop = nexthop->next;
-}
-
-
-struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re,
-                                               ifindex_t ifindex,
-                                               vrf_id_t nh_vrf_id)
-{
-       struct nexthop *nexthop;
-
-       nexthop = nexthop_new();
-       nexthop->type = NEXTHOP_TYPE_IFINDEX;
-       nexthop->ifindex = ifindex;
-       nexthop->vrf_id = nh_vrf_id;
-
-       route_entry_nexthop_add(re, nexthop);
-
-       return nexthop;
-}
-
-struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re,
-                                            struct in_addr *ipv4,
-                                            struct in_addr *src,
-                                            vrf_id_t nh_vrf_id)
-{
-       struct nexthop *nexthop;
-
-       nexthop = nexthop_new();
-       nexthop->type = NEXTHOP_TYPE_IPV4;
-       nexthop->vrf_id = nh_vrf_id;
-       nexthop->gate.ipv4 = *ipv4;
-       if (src)
-               nexthop->src.ipv4 = *src;
-
-       route_entry_nexthop_add(re, nexthop);
-
-       return nexthop;
-}
-
-struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
-                                                    struct in_addr *ipv4,
-                                                    struct in_addr *src,
-                                                    ifindex_t ifindex,
-                                                    vrf_id_t nh_vrf_id)
-{
-       struct nexthop *nexthop;
-       struct interface *ifp;
-
-       nexthop = nexthop_new();
-       nexthop->vrf_id = nh_vrf_id;
-       nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
-       nexthop->gate.ipv4 = *ipv4;
-       if (src)
-               nexthop->src.ipv4 = *src;
-       nexthop->ifindex = ifindex;
-       ifp = if_lookup_by_index(nexthop->ifindex, nh_vrf_id);
-       /*Pending: need to think if null ifp here is ok during bootup?
-         There was a crash because ifp here was coming to be NULL */
-       if (ifp)
-               if (connected_is_unnumbered(ifp))
-                       SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
-
-       route_entry_nexthop_add(re, nexthop);
-
-       return nexthop;
+       assert(!re->nhe->nhg->nexthop);
+       copy_nexthops(&re->nhe->nhg->nexthop, nh, NULL);
 }
 
-struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re,
-                                            struct in6_addr *ipv6,
-                                            vrf_id_t nh_vrf_id)
+static void route_entry_attach_ref(struct route_entry *re,
+                                  struct nhg_hash_entry *new)
 {
-       struct nexthop *nexthop;
-
-       nexthop = nexthop_new();
-       nexthop->vrf_id = nh_vrf_id;
-       nexthop->type = NEXTHOP_TYPE_IPV6;
-       nexthop->gate.ipv6 = *ipv6;
-
-       route_entry_nexthop_add(re, nexthop);
+       re->nhe = new;
+       re->nhe_id = new->id;
 
-       return nexthop;
+       zebra_nhg_increment_ref(new);
 }
 
-struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
-                                                    struct in6_addr *ipv6,
-                                                    ifindex_t ifindex,
-                                                    vrf_id_t nh_vrf_id)
+int route_entry_update_nhe(struct route_entry *re, struct nhg_hash_entry *new)
 {
-       struct nexthop *nexthop;
+       struct nhg_hash_entry *old = NULL;
+       int ret = 0;
 
-       nexthop = nexthop_new();
-       nexthop->vrf_id = nh_vrf_id;
-       nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
-       nexthop->gate.ipv6 = *ipv6;
-       nexthop->ifindex = ifindex;
+       if (new == NULL) {
+               re->nhe->nhg = NULL;
+               goto done;
+       }
 
-       route_entry_nexthop_add(re, nexthop);
+       if (re->nhe_id != new->id) {
+               old = zebra_nhg_lookup_id(re->nhe_id);
 
-       return nexthop;
-}
+               route_entry_attach_ref(re, new);
 
-struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
-                                                 enum blackhole_type bh_type)
-{
-       struct nexthop *nexthop;
+               if (old)
+                       zebra_nhg_decrement_ref(old);
+       } else if (!re->nhe)
+               /* This is the first time it's being attached */
+               route_entry_attach_ref(re, new);
 
-       nexthop = nexthop_new();
-       nexthop->vrf_id = VRF_DEFAULT;
-       nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
-       nexthop->bh_type = bh_type;
-
-       route_entry_nexthop_add(re, nexthop);
-
-       return nexthop;
+done:
+       return ret;
 }
 
 struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
@@ -501,7 +404,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
        if (re->type != ZEBRA_ROUTE_BGP)
                return 0;
 
-       for (ALL_NEXTHOPS_PTR(re->ng, nexthop))
+       for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop))
                if (!nexthop->nh_label || !nexthop->nh_label->num_labels)
                        return 0;
 
@@ -525,7 +428,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (info->safi != SAFI_UNICAST) {
-               for (ALL_NEXTHOPS_PTR(re->ng, nexthop))
+               for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        }
@@ -570,14 +473,6 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
                                nexthops_free(old->fib_ng.nexthop);
                                old->fib_ng.nexthop = NULL;
                        }
-
-                       if (!RIB_SYSTEM_ROUTE(old)) {
-                               /* Clear old route's FIB flags */
-                               for (ALL_NEXTHOPS_PTR(old->ng, nexthop)) {
-                                       UNSET_FLAG(nexthop->flags,
-                                                  NEXTHOP_FLAG_FIB);
-                               }
-                       }
                }
 
                if (zvrf)
@@ -611,7 +506,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
 
        if (info->safi != SAFI_UNICAST) {
                UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
-               for (ALL_NEXTHOPS_PTR(re->ng, nexthop))
+               for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
        }
@@ -671,7 +566,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
                        re->fib_ng.nexthop = NULL;
                }
 
-               for (ALL_NEXTHOPS_PTR(re->ng, nexthop))
+               for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
        }
 
@@ -847,7 +742,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
         * or not. */
-       if (!nexthop_group_active_nexthop_num(new->ng)) {
+       if (!nexthop_group_active_nexthop_num(new->nhe->nhg)) {
                UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
                return;
        }
@@ -916,7 +811,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
 
                /* Update the nexthop; we could determine here that nexthop is
                 * inactive. */
-               if (nexthop_group_active_nexthop_num(new->ng))
+               if (nexthop_group_active_nexthop_num(new->nhe->nhg))
                        nh_active = 1;
 
                /* If nexthop is active, install the selected route, if
@@ -1034,7 +929,7 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
                /* both are connected.  are either loop or vrf? */
                struct nexthop *nexthop = NULL;
 
-               for (ALL_NEXTHOPS_PTR(alternate->ng, nexthop)) {
+               for (ALL_NEXTHOPS_PTR(alternate->nhe->nhg, nexthop)) {
                        struct interface *ifp = if_lookup_by_index(
                                nexthop->ifindex, alternate->vrf_id);
 
@@ -1042,7 +937,7 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
                                return alternate;
                }
 
-               for (ALL_NEXTHOPS_PTR(current->ng, nexthop)) {
+               for (ALL_NEXTHOPS_PTR(current->nhe->nhg, nexthop)) {
                        struct interface *ifp = if_lookup_by_index(
                                nexthop->ifindex, current->vrf_id);
 
@@ -1180,7 +1075,8 @@ static void rib_process(struct route_node *rn)
                }
 
                /* Infinite distance. */
-               if (re->distance == DISTANCE_INFINITY) {
+               if (re->distance == DISTANCE_INFINITY &&
+                   re->type != ZEBRA_ROUTE_KERNEL) {
                        UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
                        continue;
                }
@@ -1373,7 +1269,7 @@ static void zebra_rib_fixup_system(struct route_node *rn)
                SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
 
-               for (ALL_NEXTHOPS_PTR(re->ng, nhop)) {
+               for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nhop)) {
                        if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
                                continue;
 
@@ -1474,15 +1370,23 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
 
        ctx_nexthop = dplane_ctx_get_ng(ctx)->nexthop;
 
+       /* Nothing installed - we can skip some of the checking/comparison
+        * of nexthops.
+        */
+       if (ctx_nexthop == NULL) {
+               changed_p = true;
+               goto no_nexthops;
+       }
+
        /* Get the first `installed` one to check against.
         * If the dataplane doesn't set these to be what was actually installed,
-        * it will just be whatever was in re->ng?
+        * it will just be whatever was in re->nhe->nhg?
         */
        if (CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
            || !CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                ctx_nexthop = nexthop_next_active_resolved(ctx_nexthop);
 
-       for (ALL_NEXTHOPS_PTR(re->ng, nexthop)) {
+       for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) {
 
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
@@ -1536,6 +1440,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
                goto done;
        }
 
+no_nexthops:
+
        /* FIB nexthop set differs from the RIB set:
         * create a fib-specific nexthop-group
         */
@@ -1893,18 +1799,40 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        /* Ensure we clear the QUEUED flag */
        UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
 
-       /* Is this a notification that ... matters? We only really care about
-        * the route that is currently selected for installation.
+       /* Is this a notification that ... matters? We mostly care about
+        * the route that is currently selected for installation; we may also
+        * get an un-install notification, and handle that too.
         */
        if (re != dest->selected_fib) {
-               /* TODO -- don't skip processing entirely? We might like to
-                * at least report on the event.
+               /*
+                * If we need to, clean up after a delete that was part of
+                * an update operation.
                 */
-               if (debug_p)
-                       zlog_debug("%u:%s dplane notif, but type %s not selected_fib",
-                                  dplane_ctx_get_vrf(ctx), dest_str,
-                                  zebra_route_string(
-                                          dplane_ctx_get_type(ctx)));
+               end_count = 0;
+               for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
+                               end_count++;
+               }
+
+               /* If no nexthops or none installed, ensure that this re
+                * gets its 'installed' flag cleared.
+                */
+               if (end_count == 0) {
+                       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+                       if (debug_p)
+                               zlog_debug("%u:%s dplane notif, uninstalled type %s route",
+                                          dplane_ctx_get_vrf(ctx), dest_str,
+                                          zebra_route_string(
+                                                  dplane_ctx_get_type(ctx)));
+               } else {
+                       /* At least report on the event. */
+                       if (debug_p)
+                               zlog_debug("%u:%s dplane notif, but type %s not selected_fib",
+                                          dplane_ctx_get_vrf(ctx), dest_str,
+                                          zebra_route_string(
+                                                  dplane_ctx_get_type(ctx)));
+               }
                goto done;
        }
 
@@ -1913,9 +1841,12 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
         * and then again if there's been a change.
         */
        start_count = 0;
-       for (ALL_NEXTHOPS_PTR(rib_active_nhg(re), nexthop)) {
-               if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
-                       start_count++;
+
+       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
+               for (ALL_NEXTHOPS_PTR(rib_active_nhg(re), nexthop)) {
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
+                               start_count++;
+               }
        }
 
        /* Update zebra's nexthop FIB flags based on the context struct's
@@ -1925,10 +1856,8 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
 
        if (!fib_changed) {
                if (debug_p)
-                       zlog_debug("%u:%s No change from dplane notification",
+                       zlog_debug("%u:%s dplane notification: rib_update returns FALSE",
                                   dplane_ctx_get_vrf(ctx), dest_str);
-
-               goto done;
        }
 
        /*
@@ -1970,11 +1899,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
                /* Redistribute, lsp, and nht update */
                redistribute_update(dest_pfx, src_pfx, re, NULL);
 
-               zebra_rib_evaluate_rn_nexthops(
-                       rn, zebra_router_get_next_sequence());
-
-               zebra_rib_evaluate_mpls(rn);
-
        } else if (start_count > 0 && end_count == 0) {
                if (debug_p)
                        zlog_debug("%u:%s un-installed transition from dplane notification",
@@ -1993,12 +1917,13 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
 
                /* Redistribute, lsp, and nht update */
                redistribute_delete(dest_pfx, src_pfx, re, NULL);
+       }
 
-               zebra_rib_evaluate_rn_nexthops(
-                       rn, zebra_router_get_next_sequence());
+       /* Make any changes visible for lsp and nexthop-tracking processing */
+       zebra_rib_evaluate_rn_nexthops(
+               rn, zebra_router_get_next_sequence());
 
-               zebra_rib_evaluate_mpls(rn);
-       }
+       zebra_rib_evaluate_mpls(rn);
 
 done:
        if (rn)
@@ -2429,8 +2354,8 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
                nhe = zebra_nhg_lookup_id(re->nhe_id);
                if (nhe)
                        zebra_nhg_decrement_ref(nhe);
-       } else if (re->ng)
-               nexthop_group_delete(&re->ng);
+       } else if (re->nhe->nhg)
+               nexthop_group_delete(&re->nhe->nhg);
 
        nexthops_free(re->fib_ng.nexthop);
 
@@ -2497,10 +2422,10 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
                "%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u",
                straddr, re->metric, re->mtu, re->distance, re->flags, re->status);
        zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr,
-                  nexthop_group_nexthop_num(re->ng),
-                  nexthop_group_active_nexthop_num(re->ng));
+                  nexthop_group_nexthop_num(re->nhe->nhg),
+                  nexthop_group_active_nexthop_num(re->nhe->nhg));
 
-       for (ALL_NEXTHOPS_PTR(re->ng, nexthop)) {
+       for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) {
                struct interface *ifp;
                struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
 
@@ -2649,7 +2574,8 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
 }
 
 int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
-                     struct prefix_ipv6 *src_p, struct route_entry *re)
+                     struct prefix_ipv6 *src_p, struct route_entry *re,
+                     struct nexthop_group *ng)
 {
        struct nhg_hash_entry *nhe = NULL;
        struct route_table *table;
@@ -2666,8 +2592,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        table = zebra_vrf_get_table_with_table_id(afi, safi, re->vrf_id,
                                                  re->table);
        if (!table) {
-               if (re->ng)
-                       nexthop_group_delete(&re->ng);
+               if (ng)
+                       nexthop_group_delete(&ng);
                XFREE(MTYPE_RE, re);
                return 0;
        }
@@ -2684,13 +2610,13 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                        return -1;
                }
        } else {
-               nhe = zebra_nhg_rib_find(0, re->ng, afi);
+               nhe = zebra_nhg_rib_find(0, ng, afi);
 
                /*
                 * The nexthops got copied over into an nhe,
                 * so free them now.
                 */
-               nexthop_group_delete(&re->ng);
+               nexthop_group_delete(&ng);
 
                if (!nhe) {
                        char buf[PREFIX_STRLEN] = "";
@@ -2716,7 +2642,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
         * level protocols, as the refcnt might be wrong, since it checks
         * if old_id != new_id.
         */
-       zebra_nhg_re_update_ref(re, nhe);
+       route_entry_update_nhe(re, nhe);
 
        /* Make it sure prefixlen is applied to the prefix. */
        apply_mask(p);
@@ -2859,7 +2785,8 @@ 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)
                        continue;
-               if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng->nexthop)
+               if (re->type == ZEBRA_ROUTE_CONNECT &&
+                   (rtnh = re->nhe->nhg->nexthop)
                    && rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {
                        if (rtnh->ifindex != nh->ifindex)
                                continue;
@@ -2877,7 +2804,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        same = re;
                        break;
                }
-               for (ALL_NEXTHOPS_PTR(re->ng, rtnh)) {
+               for (ALL_NEXTHOPS_PTR(re->nhe->nhg, rtnh)) {
                        /*
                         * No guarantee all kernel send nh with labels
                         * on delete.
@@ -2919,7 +2846,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        if (allow_delete) {
                                UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
                                /* Unset flags. */
-                               for (rtnh = fib->ng->nexthop; rtnh;
+                               for (rtnh = fib->nhe->nhg->nexthop; rtnh;
                                     rtnh = rtnh->next)
                                        UNSET_FLAG(rtnh->flags,
                                                   NEXTHOP_FLAG_FIB);
@@ -2975,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)) {
                        struct nexthop *tmp_nh;
 
-                       for (ALL_NEXTHOPS_PTR(re->ng, tmp_nh)) {
+                       for (ALL_NEXTHOPS_PTR(re->nhe->nhg, tmp_nh)) {
                                struct ipaddr vtep_ip;
 
                                memset(&vtep_ip, 0, sizeof(struct ipaddr));
@@ -3015,6 +2942,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
 {
        struct route_entry *re = NULL;
        struct nexthop *nexthop = NULL;
+       struct nexthop_group *ng = NULL;
 
        /* Allocate new route_entry structure. */
        re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
@@ -3030,16 +2958,19 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
        re->tag = tag;
        re->nhe_id = nhe_id;
 
+       /* If the owner of the route supplies a shared nexthop-group id,
+        * we'll use that. Otherwise, pass the nexthop along directly.
+        */
        if (!nhe_id) {
-               re->ng = nexthop_group_new();
+               ng = nexthop_group_new();
 
                /* Add nexthop. */
                nexthop = nexthop_new();
                *nexthop = *nh;
-               route_entry_nexthop_add(re, nexthop);
+               nexthop_group_add_sorted(ng, nexthop);
        }
 
-       return rib_add_multipath(afi, safi, p, src_p, re);
+       return rib_add_multipath(afi, safi, p, src_p, re, ng);
 }
 
 static const char *rib_update_event2str(rib_update_event_t event)
@@ -3184,8 +3115,6 @@ static struct rib_update_ctx *rib_update_ctx_init(vrf_id_t vrf_id,
 static void rib_update_ctx_fini(struct rib_update_ctx **ctx)
 {
        XFREE(MTYPE_RIB_UPDATE_CTX, *ctx);
-
-       *ctx = NULL;
 }
 
 static int rib_update_handler(struct thread *thread)
@@ -3297,7 +3226,7 @@ void rib_sweep_table(struct route_table *table)
                         * this decision needs to be revisited
                         */
                        SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
-                       for (ALL_NEXTHOPS_PTR(re->ng, nexthop))
+                       for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop))
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
                        rib_uninstall_kernel(rn, re);
@@ -3647,7 +3576,7 @@ struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter)
         * Array that helps us go over all AFI/SAFI combinations via one
         * index.
         */
-       static struct {
+       static const struct {
                afi_t afi;
                safi_t safi;
        } afi_safis[] = {