mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 03:10:53 +00:00
zebra: assorted parts of 0abf6796c
Author: Timo Teräs <timo.teras@iki.fi> Date: Fri Jan 15 17:36:29 2016 +0200 zebra: atomic FIB updates This commit updates the kernel API so that route changes are atomically updated using change/replaces messages instead of first sending a withdraw followed with update. Same for zclient updates, changes are sent as single ADD instead of DELETE + ADD. Signed-off-by: Timo Teräs <timo.teras@iki.fi>
This commit is contained in:
parent
020a845924
commit
bab85d4fcb
@ -1574,6 +1574,48 @@ rib_process_update_route (struct zebra_vrf *zvrf, struct route_node *rn,
|
|||||||
UNSET_FLAG(select->status, RIB_ENTRY_CHANGED);
|
UNSET_FLAG(select->status, RIB_ENTRY_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if 'alternate' RIB entry is better than 'current'. */
|
||||||
|
static struct rib *
|
||||||
|
rib_choose_best (struct rib *current, struct rib *alternate)
|
||||||
|
{
|
||||||
|
if (current == NULL)
|
||||||
|
return alternate;
|
||||||
|
|
||||||
|
/* filter route selection in following order:
|
||||||
|
* - connected beats other types
|
||||||
|
* - lower distance beats higher
|
||||||
|
* - lower metric beats higher for equal distance
|
||||||
|
* - last, hence oldest, route wins tie break.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Connected routes. Pick the last connected
|
||||||
|
* route of the set of lowest metric connected routes.
|
||||||
|
*/
|
||||||
|
if (alternate->type == ZEBRA_ROUTE_CONNECT)
|
||||||
|
{
|
||||||
|
if (current->type != ZEBRA_ROUTE_CONNECT
|
||||||
|
|| alternate->metric <= current->metric)
|
||||||
|
return alternate;
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current->type == ZEBRA_ROUTE_CONNECT)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
/* higher distance loses */
|
||||||
|
if (alternate->distance < current->distance)
|
||||||
|
return alternate;
|
||||||
|
if (current->distance < alternate->distance)
|
||||||
|
return current;
|
||||||
|
|
||||||
|
/* metric tie-breaks equal distance */
|
||||||
|
if (alternate->metric <= current->metric)
|
||||||
|
return alternate;
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
/* Core function for processing routing information base. */
|
/* Core function for processing routing information base. */
|
||||||
static void
|
static void
|
||||||
rib_process (struct route_node *rn)
|
rib_process (struct route_node *rn)
|
||||||
@ -1583,6 +1625,7 @@ rib_process (struct route_node *rn)
|
|||||||
struct rib *fib = NULL;
|
struct rib *fib = NULL;
|
||||||
struct rib *select = NULL;
|
struct rib *select = NULL;
|
||||||
struct rib *del = NULL;
|
struct rib *del = NULL;
|
||||||
|
struct rib *best = NULL;
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
rib_dest_t *dest;
|
rib_dest_t *dest;
|
||||||
struct zebra_vrf *zvrf = NULL;
|
struct zebra_vrf *zvrf = NULL;
|
||||||
@ -1683,62 +1726,12 @@ rib_process (struct route_node *rn)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Newly selected rib, the common case. */
|
best = rib_choose_best(select, rib);
|
||||||
if (!select)
|
if (select && best != select)
|
||||||
{
|
UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
|
||||||
select = rib;
|
if (best != rib)
|
||||||
continue;
|
UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
||||||
}
|
select = best;
|
||||||
|
|
||||||
/* filter route selection in following order:
|
|
||||||
* - connected beats other types
|
|
||||||
* - lower distance beats higher
|
|
||||||
* - lower metric beats higher for equal distance
|
|
||||||
* - last, hence oldest, route wins tie break.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Connected routes. Pick the last connected
|
|
||||||
* route of the set of lowest metric connected routes.
|
|
||||||
*/
|
|
||||||
if (rib->type == ZEBRA_ROUTE_CONNECT)
|
|
||||||
{
|
|
||||||
if (select->type != ZEBRA_ROUTE_CONNECT
|
|
||||||
|| rib->metric <= select->metric)
|
|
||||||
{
|
|
||||||
UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
|
|
||||||
select = rib;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (select->type == ZEBRA_ROUTE_CONNECT)
|
|
||||||
{
|
|
||||||
UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* higher distance loses */
|
|
||||||
if (rib->distance > select->distance)
|
|
||||||
{
|
|
||||||
UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lower wins */
|
|
||||||
if (rib->distance < select->distance)
|
|
||||||
{
|
|
||||||
UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
|
|
||||||
select = rib;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* metric tie-breaks equal distance */
|
|
||||||
if (rib->metric <= select->metric)
|
|
||||||
{
|
|
||||||
UNSET_FLAG (select->status, RIB_ENTRY_CHANGED);
|
|
||||||
select = rib;
|
|
||||||
}
|
|
||||||
} /* RNODE_FOREACH_RIB_SAFE */
|
} /* RNODE_FOREACH_RIB_SAFE */
|
||||||
|
|
||||||
/* After the cycle is finished, the following pointers will be set:
|
/* After the cycle is finished, the following pointers will be set:
|
||||||
|
Loading…
Reference in New Issue
Block a user