mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 18:52:04 +00:00
Revert "zebra: support FIB override routes"
This reverts commit 7569ae8bb7
.
This commit is contained in:
parent
7569ae8bb7
commit
510dc06033
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user