mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 23:53:49 +00:00
zebra: Replace SELECTED_FIB flag with a rib_dest_t pointer
The SELECTED_FIB flag was placed upon the entry that we have inserted into the kernel. Remove this flag and replace with a `rib_dest_t` *selected_fib. Just keep track of the selected_fib as we modify it. This removes allot of FOREACH_RE loops as that we do not need to find the entry anymore. At this point in time I think this is a very minor performance boost. Most `rib_dest_t` structures do not typically carry more than 1 route_entry, but the minute you start having more than one entry you can and will start having significant processing time spent finding the selected_fib. A future commit may re-order the route entries and possibly keep more pointers on `rib_dest_t` to avoid lookup. This is a bit tricky because of the FIB_OVERRIDE code. Signed-off-by Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
17473b9a45
commit
5f7a4718e2
@ -85,8 +85,7 @@ struct route_entry {
|
|||||||
/* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */
|
/* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */
|
||||||
#define ROUTE_ENTRY_NEXTHOPS_CHANGED 0x2
|
#define ROUTE_ENTRY_NEXTHOPS_CHANGED 0x2
|
||||||
#define ROUTE_ENTRY_CHANGED 0x4
|
#define ROUTE_ENTRY_CHANGED 0x4
|
||||||
#define ROUTE_ENTRY_SELECTED_FIB 0x8
|
#define ROUTE_ENTRY_LABELS_CHANGED 0x8
|
||||||
#define ROUTE_ENTRY_LABELS_CHANGED 0x10
|
|
||||||
|
|
||||||
/* Nexthop information. */
|
/* Nexthop information. */
|
||||||
u_char nexthop_num;
|
u_char nexthop_num;
|
||||||
@ -122,6 +121,8 @@ typedef struct rib_dest_t_ {
|
|||||||
*/
|
*/
|
||||||
struct route_entry *routes;
|
struct route_entry *routes;
|
||||||
|
|
||||||
|
struct route_entry *selected_fib;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags, see below.
|
* Flags, see below.
|
||||||
*/
|
*/
|
||||||
|
@ -842,19 +842,7 @@ static inline int zfpm_encode_route(rib_dest_t *dest, struct route_entry *re,
|
|||||||
*/
|
*/
|
||||||
struct route_entry *zfpm_route_for_update(rib_dest_t *dest)
|
struct route_entry *zfpm_route_for_update(rib_dest_t *dest)
|
||||||
{
|
{
|
||||||
struct route_entry *re;
|
return dest->selected_fib;
|
||||||
|
|
||||||
RE_DEST_FOREACH_ROUTE (dest, re) {
|
|
||||||
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return re;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We have no route for this destination.
|
|
||||||
*/
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -383,10 +383,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match = NULL;
|
||||||
int resolved;
|
int resolved;
|
||||||
struct nexthop *newhop;
|
struct nexthop *newhop;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
if ((nexthop->type == NEXTHOP_TYPE_IPV4)
|
if ((nexthop->type == NEXTHOP_TYPE_IPV4)
|
||||||
|| nexthop->type == NEXTHOP_TYPE_IPV6)
|
|| nexthop->type == NEXTHOP_TYPE_IPV6)
|
||||||
@ -466,17 +467,12 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
&& !nh_resolve_via_default(p.family))
|
&& !nh_resolve_via_default(p.family))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
RNODE_FOREACH_RE (rn, match) {
|
dest = rib_dest_from_rnode(rn);
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED))
|
if (dest && dest->selected_fib &&
|
||||||
continue;
|
!CHECK_FLAG(dest->selected_fib->status,
|
||||||
|
ROUTE_ENTRY_REMOVED) &&
|
||||||
/* if the next hop is imported from another table, skip
|
dest->selected_fib->type != ZEBRA_ROUTE_TABLE)
|
||||||
* it */
|
match = dest->selected_fib;
|
||||||
if (match->type == ZEBRA_ROUTE_TABLE)
|
|
||||||
continue;
|
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there is no selected route or matched route is EGP, go up
|
/* If there is no selected route or matched route is EGP, go up
|
||||||
tree. */
|
tree. */
|
||||||
@ -553,7 +549,7 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
|
|||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match = NULL;
|
||||||
struct nexthop *newhop;
|
struct nexthop *newhop;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
@ -574,15 +570,14 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
|
|||||||
rn = route_node_match(table, (struct prefix *)&p);
|
rn = route_node_match(table, (struct prefix *)&p);
|
||||||
|
|
||||||
while (rn) {
|
while (rn) {
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
|
|
||||||
/* Pick up selected route. */
|
dest = rib_dest_from_rnode(rn);
|
||||||
RNODE_FOREACH_RE (rn, match) {
|
if (dest && dest->selected_fib &&
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED))
|
!CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
|
||||||
continue;
|
match = dest->selected_fib;
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there is no selected route or matched route is EGP, go up
|
/* If there is no selected route or matched route is EGP, go up
|
||||||
tree. */
|
tree. */
|
||||||
@ -689,8 +684,9 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match = NULL;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
|
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
@ -705,13 +701,11 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
|
|
||||||
/* Unlock node. */
|
/* Unlock node. */
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
RNODE_FOREACH_RE (rn, match) {
|
if (dest && dest->selected_fib &&
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED))
|
!CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
|
||||||
continue;
|
match = dest->selected_fib;
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -743,9 +737,10 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
|
|||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *match;
|
struct route_entry *match = NULL;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
int nexthops_active;
|
int nexthops_active;
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
|
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
@ -761,15 +756,13 @@ int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
|
|||||||
|
|
||||||
/* Unlock node. */
|
/* Unlock node. */
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
/* Find out if a "selected" RR for the discovered RIB entry exists ever.
|
/* Find out if a "selected" RR for the discovered RIB entry exists ever.
|
||||||
*/
|
*/
|
||||||
RNODE_FOREACH_RE (rn, match) {
|
if (dest && dest->selected_fib &&
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED))
|
!CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
|
||||||
continue;
|
match = dest->selected_fib;
|
||||||
if (CHECK_FLAG(match->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* None such found :( */
|
/* None such found :( */
|
||||||
if (!match)
|
if (!match)
|
||||||
@ -1115,8 +1108,9 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
|
|||||||
static void rib_uninstall(struct route_node *rn, struct route_entry *re)
|
static void rib_uninstall(struct route_node *rn, struct route_entry *re)
|
||||||
{
|
{
|
||||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||||
|
rib_dest_t *dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB)) {
|
if (dest && dest->selected_fib == re) {
|
||||||
if (info->safi == SAFI_UNICAST)
|
if (info->safi == SAFI_UNICAST)
|
||||||
hook_call(rib_update, rn, "rib_uninstall");
|
hook_call(rib_update, rn, "rib_uninstall");
|
||||||
|
|
||||||
@ -1127,7 +1121,7 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
|
|||||||
if (zebra_rib_labeled_unicast(re))
|
if (zebra_rib_labeled_unicast(re))
|
||||||
zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
|
zebra_mpls_lsp_uninstall(info->zvrf, rn, re);
|
||||||
|
|
||||||
UNSET_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB);
|
dest->selected_fib = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
|
||||||
@ -1201,6 +1195,8 @@ int rib_gc_dest(struct route_node *rn)
|
|||||||
static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct route_entry *new)
|
struct route_entry *new)
|
||||||
{
|
{
|
||||||
|
rib_dest_t *dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
hook_call(rib_update, rn, "new route selected");
|
hook_call(rib_update, rn, "new route selected");
|
||||||
|
|
||||||
/* Update real nexthop. This may actually determine if nexthop is active
|
/* Update real nexthop. This may actually determine if nexthop is active
|
||||||
@ -1210,7 +1206,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_FLAG(new->status, ROUTE_ENTRY_SELECTED_FIB);
|
dest->selected_fib = new;
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
char buf[SRCDEST2STR_BUFFER];
|
char buf[SRCDEST2STR_BUFFER];
|
||||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||||
@ -1231,6 +1227,7 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||||
struct route_entry *old)
|
struct route_entry *old)
|
||||||
{
|
{
|
||||||
|
rib_dest_t *dest = rib_dest_from_rnode(rn);
|
||||||
hook_call(rib_update, rn, "removing existing route");
|
hook_call(rib_update, rn, "removing existing route");
|
||||||
|
|
||||||
/* Uninstall from kernel. */
|
/* Uninstall from kernel. */
|
||||||
@ -1248,7 +1245,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
if (!RIB_SYSTEM_ROUTE(old))
|
if (!RIB_SYSTEM_ROUTE(old))
|
||||||
rib_uninstall_kernel(rn, old);
|
rib_uninstall_kernel(rn, old);
|
||||||
|
|
||||||
UNSET_FLAG(old->status, ROUTE_ENTRY_SELECTED_FIB);
|
dest->selected_fib = NULL;
|
||||||
|
|
||||||
/* Update nexthop for route, reset changed flag. */
|
/* Update nexthop for route, reset changed flag. */
|
||||||
nexthop_active_update(rn, old, 1);
|
nexthop_active_update(rn, old, 1);
|
||||||
@ -1263,6 +1260,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
|
|||||||
struct nexthop *nexthop = NULL;
|
struct nexthop *nexthop = NULL;
|
||||||
int nh_active = 0;
|
int nh_active = 0;
|
||||||
int installed = 1;
|
int installed = 1;
|
||||||
|
rib_dest_t *dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to install or update if a new route has been selected or
|
* We have to install or update if a new route has been selected or
|
||||||
@ -1329,7 +1327,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
|
|||||||
|
|
||||||
/* Update for redistribution. */
|
/* Update for redistribution. */
|
||||||
if (installed)
|
if (installed)
|
||||||
SET_FLAG(new->status, ROUTE_ENTRY_SELECTED_FIB);
|
dest->selected_fib = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1364,7 +1362,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
|
|||||||
|
|
||||||
if (!RIB_SYSTEM_ROUTE(old))
|
if (!RIB_SYSTEM_ROUTE(old))
|
||||||
rib_uninstall_kernel(rn, old);
|
rib_uninstall_kernel(rn, old);
|
||||||
UNSET_FLAG(new->status, ROUTE_ENTRY_SELECTED_FIB);
|
dest->selected_fib = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -1392,8 +1390,6 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
|
|||||||
|
|
||||||
/* Update prior route. */
|
/* Update prior route. */
|
||||||
if (new != old) {
|
if (new != old) {
|
||||||
UNSET_FLAG(old->status, ROUTE_ENTRY_SELECTED_FIB);
|
|
||||||
|
|
||||||
/* Set real nexthop. */
|
/* Set real nexthop. */
|
||||||
nexthop_active_update(rn, old, 1);
|
nexthop_active_update(rn, old, 1);
|
||||||
UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
|
UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
|
||||||
@ -1475,6 +1471,8 @@ static void rib_process(struct route_node *rn)
|
|||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug("%u:%s: Processing rn %p", vrf_id, buf, rn);
|
zlog_debug("%u:%s: Processing rn %p", vrf_id, buf, rn);
|
||||||
|
|
||||||
|
old_fib = dest->selected_fib;
|
||||||
|
|
||||||
RNODE_FOREACH_RE_SAFE (rn, re, next) {
|
RNODE_FOREACH_RE_SAFE (rn, re, next) {
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -1490,11 +1488,6 @@ static void rib_process(struct route_node *rn)
|
|||||||
assert(old_selected == NULL);
|
assert(old_selected == NULL);
|
||||||
old_selected = re;
|
old_selected = re;
|
||||||
}
|
}
|
||||||
/* Currently in fib */
|
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB)) {
|
|
||||||
assert(old_fib == NULL);
|
|
||||||
old_fib = re;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip deleted entries from selection */
|
/* Skip deleted entries from selection */
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
|
||||||
@ -2183,8 +2176,8 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *re;
|
|
||||||
unsigned changed = 0;
|
unsigned changed = 0;
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) {
|
if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) {
|
||||||
zlog_err("%s: zebra_vrf_table() returned NULL", __func__);
|
zlog_err("%s: zebra_vrf_table() returned NULL", __func__);
|
||||||
@ -2198,6 +2191,7 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
/* Unlock node. */
|
/* Unlock node. */
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
|
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
/* Check all RE entries. In case any changes have to be done, requeue
|
/* Check all RE entries. In case any changes have to be done, requeue
|
||||||
* the RN into RIBQ head. If the routing message about the new connected
|
* the RN into RIBQ head. If the routing message about the new connected
|
||||||
* route (generated by the IP address we are going to assign very soon)
|
* route (generated by the IP address we are going to assign very soon)
|
||||||
@ -2206,20 +2200,17 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
|||||||
* revalidation
|
* revalidation
|
||||||
* of the rest of the RE.
|
* of the rest of the RE.
|
||||||
*/
|
*/
|
||||||
RNODE_FOREACH_RE (rn, re) {
|
if (dest->selected_fib && !RIB_SYSTEM_ROUTE(dest->selected_fib)) {
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB)
|
changed = 1;
|
||||||
&& !RIB_SYSTEM_ROUTE(re)) {
|
if (IS_ZEBRA_DEBUG_RIB) {
|
||||||
changed = 1;
|
char buf[PREFIX_STRLEN];
|
||||||
if (IS_ZEBRA_DEBUG_RIB) {
|
|
||||||
char buf[PREFIX_STRLEN];
|
zlog_debug("%u:%s: freeing way for connected prefix",
|
||||||
zlog_debug(
|
dest->selected_fib->vrf_id,
|
||||||
"%u:%s: freeing way for connected prefix",
|
prefix2str(&rn->p, buf, sizeof(buf)));
|
||||||
re->vrf_id,
|
route_entry_dump(&rn->p, NULL, dest->selected_fib);
|
||||||
prefix2str(&rn->p, buf, sizeof(buf)));
|
|
||||||
route_entry_dump(&rn->p, NULL, re);
|
|
||||||
}
|
|
||||||
rib_uninstall(rn, re);
|
|
||||||
}
|
}
|
||||||
|
rib_uninstall(rn, dest->selected_fib);
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed)
|
||||||
rib_queue_add(rn);
|
rib_queue_add(rn);
|
||||||
@ -2325,6 +2316,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
struct route_entry *same = NULL;
|
struct route_entry *same = NULL;
|
||||||
struct nexthop *rtnh;
|
struct nexthop *rtnh;
|
||||||
char buf2[INET6_ADDRSTRLEN];
|
char buf2[INET6_ADDRSTRLEN];
|
||||||
|
rib_dest_t *dest;
|
||||||
|
|
||||||
assert(!src_p || afi == AFI_IP6);
|
assert(!src_p || afi == AFI_IP6);
|
||||||
|
|
||||||
@ -2357,14 +2349,14 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
|
fib = dest->selected_fib;
|
||||||
|
|
||||||
/* Lookup same type route. */
|
/* Lookup same type route. */
|
||||||
RNODE_FOREACH_RE (rn, re) {
|
RNODE_FOREACH_RE (rn, re) {
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
fib = re;
|
|
||||||
|
|
||||||
if (re->type != type)
|
if (re->type != type)
|
||||||
continue;
|
continue;
|
||||||
if (re->instance != instance)
|
if (re->instance != instance)
|
||||||
@ -2427,8 +2419,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
UNSET_FLAG(rtnh->flags,
|
UNSET_FLAG(rtnh->flags,
|
||||||
NEXTHOP_FLAG_FIB);
|
NEXTHOP_FLAG_FIB);
|
||||||
|
|
||||||
UNSET_FLAG(fib->status,
|
dest->selected_fib = NULL;
|
||||||
ROUTE_ENTRY_SELECTED_FIB);
|
|
||||||
} else {
|
} else {
|
||||||
/* This means someone else, other than Zebra,
|
/* This means someone else, other than Zebra,
|
||||||
* has deleted
|
* has deleted
|
||||||
@ -2740,24 +2731,24 @@ void rib_close_table(struct route_table *table)
|
|||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
rib_table_info_t *info;
|
rib_table_info_t *info;
|
||||||
struct route_entry *re;
|
rib_dest_t *dest;
|
||||||
|
|
||||||
if (!table)
|
if (!table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info = table->info;
|
info = table->info;
|
||||||
|
|
||||||
for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
|
||||||
RNODE_FOREACH_RE (rn, re) {
|
dest = rib_dest_from_rnode(rn);
|
||||||
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
if (dest && dest->selected_fib) {
|
||||||
if (info->safi == SAFI_UNICAST)
|
if (info->safi == SAFI_UNICAST)
|
||||||
hook_call(rib_update, rn, NULL);
|
hook_call(rib_update, rn, NULL);
|
||||||
|
|
||||||
if (!RIB_SYSTEM_ROUTE(re))
|
if (!RIB_SYSTEM_ROUTE(dest->selected_fib))
|
||||||
rib_uninstall_kernel(rn, re);
|
rib_uninstall_kernel(rn, dest->selected_fib);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routing information base initialize. */
|
/* Routing information base initialize. */
|
||||||
|
@ -331,11 +331,12 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
}
|
}
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
|
||||||
|
rib_dest_t *dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
/* If there are other active nexthops, do an update. */
|
/* If there are other active nexthops, do an update. */
|
||||||
if (re->nexthop_active_num > 1) {
|
if (re->nexthop_active_num > 1) {
|
||||||
/* Update route in kernel if it's in fib */
|
/* Update route in kernel if it's in fib */
|
||||||
if (CHECK_FLAG(re->status,
|
if (dest->selected_fib)
|
||||||
ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
rib_install_kernel(rn, re, re);
|
rib_install_kernel(rn, re, re);
|
||||||
/* Update redistribution if it's selected */
|
/* Update redistribution if it's selected */
|
||||||
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
||||||
@ -350,8 +351,7 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
|
|||||||
p, (struct prefix *)src_p, re);
|
p, (struct prefix *)src_p, re);
|
||||||
/* Remove from kernel if fib route becomes
|
/* Remove from kernel if fib route becomes
|
||||||
* inactive */
|
* inactive */
|
||||||
if (CHECK_FLAG(re->status,
|
if (dest->selected_fib)
|
||||||
ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
rib_uninstall_kernel(rn, re);
|
rib_uninstall_kernel(rn, re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -961,6 +961,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
|
|||||||
u_short ospf_instance_id)
|
u_short ospf_instance_id)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
|
rib_dest_t *dest;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_entry *re;
|
struct route_entry *re;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
@ -998,10 +999,11 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
|
|||||||
|
|
||||||
/* Show all routes. */
|
/* Show all routes. */
|
||||||
for (rn = route_top(table); rn; rn = route_next(rn)) {
|
for (rn = route_top(table); rn; rn = route_next(rn)) {
|
||||||
|
dest = rib_dest_from_rnode(rn);
|
||||||
|
|
||||||
RNODE_FOREACH_RE (rn, re) {
|
RNODE_FOREACH_RE (rn, re) {
|
||||||
if (use_fib
|
if (use_fib
|
||||||
&& !CHECK_FLAG(re->status,
|
&& re != dest->selected_fib)
|
||||||
ROUTE_ENTRY_SELECTED_FIB))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (tag && re->tag != tag)
|
if (tag && re->tag != tag)
|
||||||
|
Loading…
Reference in New Issue
Block a user