Merge pull request #2896 from dslicenc/zebra_select_vrf

zebra: if multiple connecteds, select loopback or vrf if present
This commit is contained in:
David Lamparter 2018-08-24 04:19:02 +02:00 committed by GitHub
commit ff0c9e7a0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 15 deletions

View File

@ -472,6 +472,14 @@ int if_is_vrf(struct interface *ifp)
return CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
}
bool if_is_loopback_or_vrf(struct interface *ifp)
{
if (if_is_loopback(ifp) || if_is_vrf(ifp))
return true;
return false;
}
/* Does this interface support broadcast ? */
int if_is_broadcast(struct interface *ifp)
{

View File

@ -497,6 +497,7 @@ extern int if_is_operative(struct interface *);
extern int if_is_no_ptm_operative(struct interface *);
extern int if_is_loopback(struct interface *);
extern int if_is_vrf(struct interface *ifp);
extern bool if_is_loopback_or_vrf(struct interface *ifp);
extern int if_is_broadcast(struct interface *);
extern int if_is_pointopoint(struct interface *);
extern int if_is_multicast(struct interface *);

View File

@ -1495,14 +1495,6 @@ int pim_if_connected_to_source(struct interface *ifp, struct in_addr src)
return 0;
}
bool pim_if_is_loopback(struct interface *ifp)
{
if (if_is_loopback(ifp) || if_is_vrf(ifp))
return true;
return false;
}
bool pim_if_is_vrf_device(struct interface *ifp)
{
if (if_is_vrf(ifp))

View File

@ -207,8 +207,6 @@ void pim_if_create_pimreg(struct pim_instance *pim);
int pim_if_connected_to_source(struct interface *ifp, struct in_addr src);
int pim_update_source_set(struct interface *ifp, struct in_addr source);
bool pim_if_is_loopback(struct interface *ifp);
bool pim_if_is_vrf_device(struct interface *ifp);
int pim_if_ifchannel_count(struct pim_interface *pim_ifp);

View File

@ -655,7 +655,7 @@ static int pim_hello_send(struct interface *ifp, uint16_t holdtime)
{
struct pim_interface *pim_ifp = ifp->info;
if (pim_if_is_loopback(ifp))
if (if_is_loopback_or_vrf(ifp))
return 0;
if (hello_send(ifp, holdtime)) {
@ -757,7 +757,7 @@ void pim_hello_restart_triggered(struct interface *ifp)
/*
* No need to ever start loopback or vrf device hello's
*/
if (pim_if_is_loopback(ifp))
if (if_is_loopback_or_vrf(ifp))
return;
/*

View File

@ -1501,17 +1501,37 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
/* filter route selection in following order:
* - connected beats other types
* - if both connected, loopback or vrf wins
* - lower distance beats higher
* - lower metric beats higher for equal distance
* - last, hence oldest, route wins tie break.
*/
/* Connected routes. Pick the last connected
/* Connected routes. Check to see if either are a vrf
* or loopback interface. If not, 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)
if (current->type != ZEBRA_ROUTE_CONNECT)
return alternate;
/* both are connected. are either loop or vrf? */
struct nexthop *nexthop = NULL;
for (ALL_NEXTHOPS(alternate->ng, nexthop)) {
if (if_is_loopback_or_vrf(if_lookup_by_index(
nexthop->ifindex, alternate->vrf_id)))
return alternate;
}
for (ALL_NEXTHOPS(current->ng, nexthop)) {
if (if_is_loopback_or_vrf(if_lookup_by_index(
nexthop->ifindex, current->vrf_id)))
return current;
}
/* Neither are loop or vrf so pick best metric */
if (alternate->metric <= current->metric)
return alternate;
return current;