Skip to content
Permalink
Browse files

Merge pull request #2896 from dslicenc/zebra_select_vrf

zebra: if multiple connecteds, select loopback or vrf if present
  • Loading branch information...
eqvinox committed Aug 24, 2018
2 parents 3391232 + fec4ca1 commit ff0c9e7a0abf46750b40a41464ecd7aabea0e97c
Showing with 34 additions and 15 deletions.
  1. +8 −0 lib/if.c
  2. +1 −0 lib/if.h
  3. +0 −8 pimd/pim_iface.c
  4. +0 −2 pimd/pim_iface.h
  5. +2 −2 pimd/pim_pim.c
  6. +23 −3 zebra/zebra_rib.c
@@ -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)
{
@@ -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 *);
@@ -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))
@@ -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);
@@ -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;

/*
@@ -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;

0 comments on commit ff0c9e7

Please sign in to comment.
You can’t perform that action at this time.