Acked-by: Donald Sharp <[email protected]> On Wed, Dec 23, 2015 at 9:47 AM, Timo Teräs <[email protected]> wrote:
> FIB override routes are for routing protocols that establish > shortcut routes, or establish point-to-point routes that should > not be redistributed. Namely this is useful NHRP daemon to come. > > Zebra is extended to select two entries from RIB the "best" entry > from routing protocols, and the FIB entry to install to kernel. > FIB override routes are never selected as best entry, and thus > are never adverticed to other routing daemons. The best FIB > override, or if it does not exist the otherwise best RIB is > selected as FIB entry to be installed. > > Signed-off-by: Timo Teräs <[email protected]> > --- > lib/zebra.h | 1 + > zebra/rib.h | 1 + > zebra/zebra_fpm.c | 2 +- > zebra/zebra_rib.c | 82 > +++++++++++++++++++++++++++++++++++++++---------------- > zebra/zebra_vty.c | 4 +++ > zebra/zserv.c | 12 ++++---- > 6 files changed, 71 insertions(+), 31 deletions(-) > > diff --git a/lib/zebra.h b/lib/zebra.h > index a607437..bf5980c 100644 > --- a/lib/zebra.h > +++ b/lib/zebra.h > @@ -464,6 +464,7 @@ extern const char *zserv_command_string (unsigned int > command); > #define ZEBRA_FLAG_BLACKHOLE 0x04 > #define ZEBRA_FLAG_IBGP 0x08 > #define ZEBRA_FLAG_SELECTED 0x10 > +#define ZEBRA_FLAG_FIB_OVERRIDE 0x20 > #define ZEBRA_FLAG_STATIC 0x40 > #define ZEBRA_FLAG_REJECT 0x80 > > diff --git a/zebra/rib.h b/zebra/rib.h > index ffe7e2f..67ffe8d 100644 > --- a/zebra/rib.h > +++ b/zebra/rib.h > @@ -83,6 +83,7 @@ struct rib > u_char status; > #define RIB_ENTRY_REMOVED (1 << 0) > #define RIB_ENTRY_CHANGED (1 << 1) > +#define RIB_ENTRY_SELECTED_FIB (1 << 2) > > /* Nexthop information. */ > u_char nexthop_num; > diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c > index 292dbb6..cb04f21 100644 > --- a/zebra/zebra_fpm.c > +++ b/zebra/zebra_fpm.c > @@ -889,7 +889,7 @@ zfpm_route_for_update (rib_dest_t *dest) > > RIB_DEST_FOREACH_ROUTE (dest, rib) > { > - if (!CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > + if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > continue; > > return rib; > diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c > index 9264087..d06382c 100644 > --- a/zebra/zebra_rib.c > +++ b/zebra/zebra_rib.c > @@ -387,7 +387,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop > *nexthop, int set, > { > if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) > continue; > - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -521,7 +521,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->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -633,7 +633,7 @@ rib_match_ipv4_safi (struct in_addr addr, safi_t safi, > int skip_bgp, > { > if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) > continue; > - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -778,7 +778,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->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -838,7 +838,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->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -904,7 +904,7 @@ rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id) > { > if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) > continue; > - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) > break; > } > > @@ -1139,7 +1139,7 @@ rib_uninstall (struct route_node *rn, struct rib > *rib) > { > rib_table_info_t *info = rn->table->info; > > - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > { > if (info->safi == SAFI_UNICAST) > zfpm_trigger_update (rn, "rib_uninstall"); > @@ -1259,6 +1259,8 @@ 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; > int installed = 0; > @@ -1275,6 +1277,11 @@ rib_process (struct route_node *rn) > /* Currently installed rib. */ > if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > { > + assert (old_selected == NULL); > + old_selected = rib; > + } > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > + { > assert (old_fib == NULL); > old_fib = rib; > } > @@ -1291,17 +1298,31 @@ rib_process (struct route_node *rn) > if (rib->distance == DISTANCE_INFINITY) > continue; > > - new_fib = rib_choose_best(new_fib, rib); > + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) > + new_fib = rib_choose_best(new_fib, rib); > + else > + new_selected = rib_choose_best(new_selected, rib); > } /* RNODE_FOREACH_RIB_SAFE */ > > + /* If no FIB override route, use the selected route also for FIB */ > + if (new_fib == NULL) > + new_fib = new_selected; > + > /* After the cycle is finished, the following pointers will be set: > - * old_fib --- RIB entry currently having SELECTED > - * new_fib --- RIB entry that is newly SELECTED > + * 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. > */ > > /* Set real nexthops. */ > if (new_fib) > nexthop_active_update (rn, new_fib, 1); > + if (new_selected && new_selected != new_fib) > + nexthop_active_update (rn, new_selected, 1); > > /* Update kernel if FIB entry has changed */ > if (old_fib != new_fib > @@ -1309,20 +1330,15 @@ rib_process (struct route_node *rn) > { > if (old_fib && old_fib != new_fib) > { > - if (! new_fib) > - redistribute_delete (&rn->p, old_fib); > - > if (! RIB_SYSTEM_ROUTE (old_fib) && (! new_fib || > RIB_SYSTEM_ROUTE (new_fib))) > rib_update_kernel (rn, old_fib, NULL); > - UNSET_FLAG (old_fib->flags, ZEBRA_FLAG_SELECTED); > + UNSET_FLAG (old_fib->status, RIB_ENTRY_SELECTED_FIB); > } > > if (new_fib) > { > /* Install new or replace existing FIB entry */ > - SET_FLAG (new_fib->flags, ZEBRA_FLAG_SELECTED); > - redistribute_add (&rn->p, new_fib); > - > + SET_FLAG (new_fib->status, RIB_ENTRY_SELECTED_FIB); > if (! RIB_SYSTEM_ROUTE (new_fib)) > rib_update_kernel (rn, old_fib, new_fib); > } > @@ -1346,6 +1362,26 @@ rib_process (struct route_node *rn) > rib_update_kernel (rn, NULL, new_fib); > } > > + /* Redistribute SELECTED entry */ > + if (old_selected != new_selected > + || (new_selected && CHECK_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_add (&rn->p, new_selected); > + } > + } > + > /* Remove all RIB entries queued for removal */ > RNODE_FOREACH_RIB_SAFE (rn, rib, next) > { > @@ -1947,7 +1983,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p) > */ > RNODE_FOREACH_RIB (rn, rib) > { > - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) && > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB) && > ! RIB_SYSTEM_ROUTE (rib)) > { > changed = 1; > @@ -2098,7 +2134,7 @@ rib_delete_ipv4 (int type, int flags, struct > prefix_ipv4 *p, > if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) > continue; > > - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > fib = rib; > > if (rib->type != type) > @@ -2146,7 +2182,7 @@ rib_delete_ipv4 (int type, int flags, struct > prefix_ipv4 *p, > for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) > UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); > > - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); > + UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB); > } > else > { > @@ -2675,7 +2711,7 @@ rib_delete_ipv6 (int type, int flags, struct > prefix_ipv6 *p, > if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) > continue; > > - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > fib = rib; > > if (rib->type != type) > @@ -2724,7 +2760,7 @@ rib_delete_ipv6 (int type, int flags, struct > prefix_ipv6 *p, > for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) > UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); > > - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); > + UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB); > } > else > { > @@ -3058,7 +3094,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->flags, ZEBRA_FLAG_SELECTED)) > + if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > continue; > > if (info->safi == SAFI_UNICAST) > diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c > index 656f55d..21b92ea 100644 > --- a/zebra/zebra_vty.c > +++ b/zebra/zebra_vty.c > @@ -1295,6 +1295,10 @@ vty_show_ip_route_detail (struct vty *vty, struct > route_node *rn, int mcast) > vty_out (vty, ", vrf %u", rib->vrf_id); > if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) > vty_out (vty, ", best"); > + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) > + vty_out (vty, ", fib-override"); > + if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) > + vty_out (vty, ", fib"); > if (rib->refcnt) > vty_out (vty, ", refcnt %ld", rib->refcnt); > if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) > diff --git a/zebra/zserv.c b/zebra/zserv.c > index 7a75ed4..600b0e5 100644 > --- a/zebra/zserv.c > +++ b/zebra/zserv.c > @@ -397,8 +397,7 @@ zsend_route_multipath (int cmd, struct zserv *client, > struct prefix *p, > > for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) > { > - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) > - || nexthop_has_fib_child(nexthop)) > + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) > { > SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); > SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); > @@ -504,7 +503,7 @@ zsend_ipv6_nexthop_lookup (struct zserv *client, > struct in6_addr *addr, > * 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_FIB)) > + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) > { > stream_putc (s, nexthop->type); > switch (nexthop->type) > @@ -574,7 +573,7 @@ zsend_ipv4_nexthop_lookup (struct zserv *client, > struct in_addr addr, > * 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_FIB)) > + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) > { > stream_putc (s, nexthop->type); > switch (nexthop->type) > @@ -644,7 +643,7 @@ zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, > struct in_addr addr, > * 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_FIB)) > + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) > { > stream_putc (s, nexthop->type); > switch (nexthop->type) > @@ -709,8 +708,7 @@ zsend_ipv4_import_lookup (struct zserv *client, struct > prefix_ipv4 *p, > nump = stream_get_endp(s); > stream_putc (s, 0); > for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) > - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) > - || nexthop_has_fib_child(nexthop)) > + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) > { > stream_putc (s, nexthop->type); > switch (nexthop->type) > -- > 2.6.4 > > > _______________________________________________ > Quagga-dev mailing list > [email protected] > https://lists.quagga.net/mailman/listinfo/quagga-dev
_______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
