diff --git a/lib/zebra.h b/lib/zebra.h index 5bb7dfaf45..da069d1dfa 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -471,7 +471,6 @@ extern const char *zserv_command_string (unsigned int command); #define ZEBRA_FLAG_STATIC 0x40 #define ZEBRA_FLAG_REJECT 0x80 #define ZEBRA_FLAG_SCOPE_LINK 0x100 -#define ZEBRA_FLAG_FIB_OVERRIDE 0x200 #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ diff --git a/zebra/rib.h b/zebra/rib.h index 96301a8af4..285166f067 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -87,7 +87,6 @@ struct rib /* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */ #define RIB_ENTRY_NEXTHOPS_CHANGED 0x2 #define RIB_ENTRY_CHANGED 0x4 -#define RIB_ENTRY_SELECTED_FIB 0x8 /* Nexthop information. */ u_char nexthop_num; diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index bc9d22e001..220fddaf67 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -892,7 +892,7 @@ zfpm_route_for_update (rib_dest_t *dest) RIB_DEST_FOREACH_ROUTE (dest, rib) { - if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) + if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) continue; return rib; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 6bd5417ac9..775619ac2d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -432,7 +432,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, /* if the next hop is imported from another table, skip it */ if (match->type == ZEBRA_ROUTE_TABLE) continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } @@ -628,7 +628,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, { if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } @@ -793,7 +793,7 @@ rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id, { if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } @@ -929,7 +929,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id) { if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } @@ -949,7 +949,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id) /* * This clone function, unlike its original rib_lookup_ipv4(), checks * if specified IPv4 route record (prefix/mask -> gate) exists in - * the whole RIB and has RIB_ENTRY_SELECTED_FIB set. + * the whole RIB and has ZEBRA_FLAG_SELECTED set. * * Return values: * -1: error @@ -989,7 +989,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate, { if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) continue; - if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } @@ -1299,19 +1299,14 @@ rib_uninstall (struct route_node *rn, struct rib *rib) { rib_table_info_t *info = rn->table->info; - if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) { if (info->safi == SAFI_UNICAST) zfpm_trigger_update (rn, "rib_uninstall"); + redistribute_delete (&rn->p, rib); if (! RIB_SYSTEM_ROUTE (rib)) rib_uninstall_kernel (rn, rib); - UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB); - } - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) - { - redistribute_delete (&rn->p, rib); UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED); } } @@ -1379,70 +1374,76 @@ rib_gc_dest (struct route_node *rn) } static void -rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, - struct rib *new) +rib_process_add_route (struct zebra_vrf *zvrf, struct route_node *rn, + struct rib *select) { char buf[INET6_ADDRSTRLEN]; + int installed = 1; zfpm_trigger_update (rn, "new route selected"); /* Update real nexthop. This may actually determine if nexthop is active or not. */ - if (!nexthop_active_update (rn, new, 1)) + if (!nexthop_active_update (rn, select, 1)) { - UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); + UNSET_FLAG(select->status, RIB_ENTRY_CHANGED); return; } - SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); + SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); if (IS_ZEBRA_DEBUG_RIB) { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type); } - if (!RIB_SYSTEM_ROUTE (new)) + if (!RIB_SYSTEM_ROUTE (select)) { - if (rib_install_kernel (rn, new, 0)) + if (rib_install_kernel (rn, select, 0)) { + installed = 0; inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_warn ("%u:%s/%d: Route install failed", zvrf->vrf_id, buf, rn->p.prefixlen); } } - UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); + /* Update for redistribution. */ + if (installed) + redistribute_update (&rn->p, select, NULL); + UNSET_FLAG(select->status, RIB_ENTRY_CHANGED); } static void -rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, - struct rib *old) +rib_process_del_route (struct zebra_vrf *zvrf, struct route_node *rn, + struct rib *fib) { char buf[INET6_ADDRSTRLEN]; zfpm_trigger_update (rn, "removing existing route"); - /* Uninstall from kernel. */ + /* Withdraw redistribute and uninstall from kernel. */ if (IS_ZEBRA_DEBUG_RIB) { inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, old, old->type); + zvrf->vrf_id, buf, rn->p.prefixlen, rn, fib, fib->type); } - if (!RIB_SYSTEM_ROUTE (old)) - rib_uninstall_kernel (rn, old); + redistribute_delete(&rn->p, fib); + if (!RIB_SYSTEM_ROUTE (fib)) + rib_uninstall_kernel (rn, fib); - UNSET_FLAG (old->status, RIB_ENTRY_SELECTED_FIB); + UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); /* Update nexthop for route, reset changed flag. */ - nexthop_active_update (rn, old, 1); - UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); + nexthop_active_update (rn, fib, 1); + UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED); } static void -rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, - struct rib *old, struct rib *new) +rib_process_update_route (struct zebra_vrf *zvrf, struct route_node *rn, + struct rib *select, struct rib *fib) { char buf[INET6_ADDRSTRLEN]; struct nexthop *nexthop = NULL, *tnexthop; @@ -1457,13 +1458,13 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, * We have to install or update if a new route has been selected or * something has changed. */ - if (new != old || - CHECK_FLAG (new->status, RIB_ENTRY_CHANGED)) + if (select != fib || + CHECK_FLAG (select->status, RIB_ENTRY_CHANGED)) { zfpm_trigger_update (rn, "updating existing route"); /* Update the nexthop; we could determine here that nexthop is inactive. */ - if (nexthop_active_update (rn, new, 1)) + if (nexthop_active_update (rn, select, 1)) nh_active = 1; /* If nexthop is active, install the selected route, if appropriate. If @@ -1474,18 +1475,18 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (IS_ZEBRA_DEBUG_RIB) { - if (new != old) + if (select != fib) zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) " "old %p (type %d)", zvrf->vrf_id, buf, rn->p.prefixlen, - rn, new, new->type, old, old->type); + rn, select, select->type, fib, fib->type); else zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type); + zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type); } /* Non-system route should be installed. */ - if (!RIB_SYSTEM_ROUTE (new)) + if (!RIB_SYSTEM_ROUTE (select)) { - if (rib_install_kernel (rn, new, 1)) + if (rib_install_kernel (rn, select, 1)) { installed = 0; inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); @@ -1495,23 +1496,26 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, } /* If install succeeded or system route, cleanup flags for prior route. */ - if (installed && new != old) + if (installed && select != fib) { - if (RIB_SYSTEM_ROUTE(new)) + if (RIB_SYSTEM_ROUTE(select)) { - if (!RIB_SYSTEM_ROUTE (old)) - rib_uninstall_kernel (rn, old); + if (!RIB_SYSTEM_ROUTE (fib)) + rib_uninstall_kernel (rn, fib); } else { - for (nexthop = old->nexthop; nexthop; nexthop = nexthop->next) + for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); } } /* Update for redistribution. */ if (installed) - SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); + { + SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); + redistribute_update (&rn->p, select, (select == fib) ? NULL : fib); + } } /* @@ -1520,22 +1524,28 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, */ if (!nh_active || !installed) { + struct rib *del; + if (IS_ZEBRA_DEBUG_RIB) { - if (new != old) + if (select != fib) zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) " "old %p (type %d) - %s", zvrf->vrf_id, buf, rn->p.prefixlen, - rn, new, new->type, old, old->type, + rn, select, select->type, fib, fib->type, nh_active ? "install failed" : "nexthop inactive"); else zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s", - zvrf->vrf_id, buf, rn->p.prefixlen, rn, new, new->type, + zvrf->vrf_id, buf, rn->p.prefixlen, rn, select, select->type, nh_active ? "install failed" : "nexthop inactive"); } - if (!RIB_SYSTEM_ROUTE (old)) - rib_uninstall_kernel (rn, old); - UNSET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); + del = (select == fib) ? select : fib; + + redistribute_delete(&rn->p, del); + + if (!RIB_SYSTEM_ROUTE (del)) + rib_uninstall_kernel (rn, del); + UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); } } else @@ -1546,33 +1556,33 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, * netlink reporting interface up before IPv4 or IPv6 protocol is ready * to add routes. */ - if (!RIB_SYSTEM_ROUTE (new)) + if (!RIB_SYSTEM_ROUTE (select)) { int in_fib = 0; - for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing)) + for (ALL_NEXTHOPS_RO(select->nexthop, nexthop, tnexthop, recursing)) if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { in_fib = 1; break; } if (!in_fib) - rib_install_kernel (rn, new, 0); + rib_install_kernel (rn, select, 0); } } /* Update prior route. */ - if (new != old) + if (select != fib) { - UNSET_FLAG (old->status, RIB_ENTRY_SELECTED_FIB); + UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); /* Set real nexthop. */ - nexthop_active_update (rn, old, 1); - UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); + nexthop_active_update (rn, fib, 1); + UNSET_FLAG(fib->status, RIB_ENTRY_CHANGED); } /* Clear changed flag. */ - UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); + UNSET_FLAG(select->status, RIB_ENTRY_CHANGED); } /* Check if 'alternate' RIB entry is better than 'current'. */ @@ -1623,32 +1633,33 @@ rib_process (struct route_node *rn) { struct rib *rib; struct rib *next; - struct rib *old_selected = NULL; - struct rib *new_selected = NULL; - struct rib *old_fib = NULL; - struct rib *new_fib = NULL; + struct rib *fib = NULL; + struct rib *select = NULL; + struct rib *del = NULL; struct rib *best = NULL; char buf[INET6_ADDRSTRLEN]; rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; vrf_id_t vrf_id = VRF_UNKNOWN; + rib_table_info_t *info; assert (rn); - + info = rn->table->info; + dest = rib_dest_from_rnode (rn); if (dest) { zvrf = rib_dest_vrf (dest); vrf_id = zvrf->vrf_id; } - + if (IS_ZEBRA_DEBUG_RIB) inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug ("%u:%s/%d: Processing rn %p", vrf_id, buf, rn->p.prefixlen, rn); - RNODE_FOREACH_RIB (rn, rib) + RNODE_FOREACH_RIB_SAFE (rn, rib, next) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug ("%u:%s/%d: Examine rib %p (type %d) status %x flags %x " @@ -1658,23 +1669,31 @@ rib_process (struct route_node *rn) UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); - /* Currently selected rib. */ + /* Currently installed rib. */ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) { - assert (old_selected == NULL); - old_selected = rib; - } - /* Currently in fib */ - if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) - { - assert (old_fib == NULL); - old_fib = rib; + assert (fib == NULL); + fib = rib; } - /* Skip deleted entries from selection */ + /* Unlock removed routes, so they'll be freed, bar the FIB entry, + * which we need to do do further work with below. + */ if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) - continue; - + { + if (rib != fib) + { + if (IS_ZEBRA_DEBUG_RIB) + rnode_debug (rn, vrf_id, "rn %p, removing rib %p", + (void *)rn, (void *)rib); + rib_unlink (rn, rib); + } + else + del = rib; + + continue; + } + /* Skip unreachable nexthop. */ /* This first call to nexthop_active_update is merely to determine if * there's any change to nexthops associated with this RIB entry. Now, @@ -1691,15 +1710,9 @@ rib_process (struct route_node *rn) { if (rib->type == ZEBRA_ROUTE_TABLE) { - /* XXX: HERE BE DRAGONS!!!!! - * In all honesty, I have not yet figured out what this part - * does or why the RIB_ENTRY_CHANGED test above is correct - * or why we need to delete a route here, and also not whether - * this concerns both selected and fib route, or only selected - * or only fib */ /* This entry was denied by the 'ip protocol table' route-map, we * need to delete it */ - if (rib != old_selected) + if (rib != fib) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug ("%s: %s/%d: imported via import-table but denied " @@ -1708,12 +1721,15 @@ rib_process (struct route_node *rn) rib_unlink (rn, rib); } else - SET_FLAG (rib->status, RIB_ENTRY_REMOVED); + del = rib; } continue; } + if (info->safi == SAFI_MULTICAST) + continue; + /* Infinite distance. */ if (rib->distance == DISTANCE_INFINITY) { @@ -1721,101 +1737,33 @@ rib_process (struct route_node *rn) continue; } - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) - { - best = rib_choose_best(new_fib, rib); - if (new_fib && best != new_fib) - UNSET_FLAG (new_fib->status, RIB_ENTRY_CHANGED); - new_fib = best; - } - else - { - best = rib_choose_best(new_selected, rib); - if (new_selected && best != new_selected) - UNSET_FLAG (new_selected->status, RIB_ENTRY_CHANGED); - new_selected = best; - } + best = rib_choose_best(select, rib); + if (select && best != select) + UNSET_FLAG (select->status, RIB_ENTRY_CHANGED); if (best != rib) UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED); - } /* RNODE_FOREACH_RIB */ - - /* If no FIB override route, use the selected route also for FIB */ - if (new_fib == NULL) - new_fib = new_selected; + select = best; + } /* RNODE_FOREACH_RIB_SAFE */ /* After the cycle is finished, the following pointers will be set: - * old_selected --- RIB entry currently having SELECTED - * new_selected --- RIB entry that is newly SELECTED - * old_fib --- RIB entry currently in kernel FIB - * new_fib --- RIB entry that is newly to be in kernel FIB - * - * new_selected will get SELECTED flag, and is going to be redistributed - * the zclients. new_fib (which can be new_selected) will be installed in kernel. + * select --- the winner RIB entry, if any was found, otherwise NULL + * fib --- the SELECTED RIB entry, if any, otherwise NULL + * del --- equal to fib, if fib is queued for deletion, NULL otherwise + * rib --- NULL */ - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - { - zlog_debug ("%u:%s/%d: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", - vrf_id, buf, rn->p.prefixlen, - (void *)old_selected, - (void *)new_selected, - (void *)old_fib, - (void *)new_fib); - } + zlog_debug ("%u:%s/%d: After processing: select %p fib %p del %p", + vrf_id, buf, rn->p.prefixlen, select, fib, del); - /* Buffer RIB_ENTRY_CHANGED here, because it will get cleared if - * fib == selected */ - bool selected_changed = new_selected && CHECK_FLAG(new_selected->status, - RIB_ENTRY_CHANGED); - - /* Update fib according to selection results */ - if (new_fib && old_fib) - rib_process_update_fib (zvrf, rn, old_fib, new_fib); - else if (new_fib) - rib_process_add_fib (zvrf, rn, new_fib); - else if (old_fib) - rib_process_del_fib (zvrf, rn, old_fib); - - /* Redistribute SELECTED entry */ - if (old_selected != new_selected || selected_changed) - { - struct nexthop *nexthop, *tnexthop; - int recursing; - - /* Check if we have a FIB route for the destination, otherwise, - * don't redistribute it */ - for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop, - tnexthop, recursing)) - { - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) - { - break; - } - } - if (!nexthop) - new_selected = NULL; - - if (new_selected && new_selected != new_fib) - { - nexthop_active_update(rn, new_selected, 1); - UNSET_FLAG(new_selected->status, RIB_ENTRY_CHANGED); - } - - if (old_selected) - { - if (!new_selected) - redistribute_delete(&rn->p, old_selected); - if (old_selected != new_selected) - UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED); - } - - if (new_selected) - { - /* Install new or replace existing redistributed entry */ - SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED); - redistribute_update (&rn->p, new_selected, old_selected); - } - } + /* Same RIB entry is selected. Update FIB and finish. */ + if (select && select == fib) + rib_process_update_route (zvrf, rn, select, select); + else if (select && fib) + rib_process_update_route (zvrf, rn, select, fib); + else if (select) + rib_process_add_route (zvrf, rn, select); + else if (fib) + rib_process_del_route (zvrf, rn, fib); #if 0 if (select && select == fib) @@ -1992,18 +1940,12 @@ rib_process (struct route_node *rn) } #endif - /* Remove all RIB entries queued for removal */ - RNODE_FOREACH_RIB_SAFE (rn, rib, next) + /* FIB route was removed, should be deleted */ + if (del) { - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) - { - if (IS_ZEBRA_DEBUG_RIB) - { - rnode_debug (rn, vrf_id, "rn %p, removing rib %p", - (void *)rn, (void *)rib); - } - rib_unlink(rn, rib); - } + if (IS_ZEBRA_DEBUG_RIB) + rnode_debug (rn, vrf_id, "Deleting fib %p, rn %p", (void *)del, (void *)rn); + rib_unlink (rn, del); } /* @@ -2570,7 +2512,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id) */ RNODE_FOREACH_RIB (rn, rib) { - if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB) && + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) && ! RIB_SYSTEM_ROUTE (rib)) { changed = 1; @@ -2716,7 +2658,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) continue; - if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) fib = rib; if (rib->type != type) @@ -2777,7 +2719,7 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB); + UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); } else { @@ -3154,7 +3096,7 @@ rib_close_table (struct route_table *table) for (rn = route_top (table); rn; rn = route_next (rn)) RNODE_FOREACH_RIB (rn, rib) { - if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) + if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) continue; if (info->safi == SAFI_UNICAST) diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 1dc54e171c..f2362e6871 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -320,21 +320,13 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ /* If there are other active nexthops, do an update. */ if (rib->nexthop_active_num > 1) { - /* Update route in kernel if it's in fib */ - if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_install_kernel (rn, rib, 1); - /* Update redistribution if it's selected */ - if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_update (&rn->p, rib, NULL); + rib_install_kernel (rn, rib, 1); + redistribute_update (&rn->p, rib, NULL); } else { - /* Remove from redistribute if selected route becomes inactive */ - if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_delete (&rn->p, rib); - /* Remove from kernel if fib route becomes inactive */ - if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_uninstall_kernel (rn, rib); + redistribute_delete (&rn->p, rib); + rib_uninstall_kernel (rn, rib); } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 41e1293e7c..e76e4ab8fa 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2023,10 +2023,6 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) } if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) vty_out (vty, ", best"); - else if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) - vty_out (vty, ", fib"); - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) - vty_out (vty, ", fib-override"); if (rib->refcnt) vty_out (vty, ", refcnt %ld", rib->refcnt); if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) @@ -2303,8 +2299,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib, len += vty_out (vty, "[%d]", rib->instance); len += vty_out (vty, "%c%c %s", CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) - ? '>' : CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB) - ? '!' : ' ', + ? '>' : ' ', CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ', prefix2str (&rn->p, buf, sizeof buf)); diff --git a/zebra/zserv.c b/zebra/zserv.c index 969d860c20..3b2095d656 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -668,7 +668,8 @@ zsend_redistribute_route (int cmd, struct zserv *client, struct prefix *p, break; } - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) + || nexthop_has_fib_child(nexthop)) { SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); @@ -926,7 +927,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struc * are looking up. Therefore, we will just iterate over the top * chain of nexthops. */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) num += zsend_write_nexthop (s, nexthop); stream_putc_at (s, nump, num); /* store nexthop_num */