mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-03 17:07:05 +00:00
Merge pull request #2896 from dslicenc/zebra_select_vrf
zebra: if multiple connecteds, select loopback or vrf if present
This commit is contained in:
commit
ff0c9e7a0a
8
lib/if.c
8
lib/if.c
@ -472,6 +472,14 @@ int if_is_vrf(struct interface *ifp)
|
|||||||
return CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
|
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 ? */
|
/* Does this interface support broadcast ? */
|
||||||
int if_is_broadcast(struct interface *ifp)
|
int if_is_broadcast(struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
1
lib/if.h
1
lib/if.h
@ -497,6 +497,7 @@ extern int if_is_operative(struct interface *);
|
|||||||
extern int if_is_no_ptm_operative(struct interface *);
|
extern int if_is_no_ptm_operative(struct interface *);
|
||||||
extern int if_is_loopback(struct interface *);
|
extern int if_is_loopback(struct interface *);
|
||||||
extern int if_is_vrf(struct interface *ifp);
|
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_broadcast(struct interface *);
|
||||||
extern int if_is_pointopoint(struct interface *);
|
extern int if_is_pointopoint(struct interface *);
|
||||||
extern int if_is_multicast(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;
|
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)
|
bool pim_if_is_vrf_device(struct interface *ifp)
|
||||||
{
|
{
|
||||||
if (if_is_vrf(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_if_connected_to_source(struct interface *ifp, struct in_addr src);
|
||||||
int pim_update_source_set(struct interface *ifp, struct in_addr source);
|
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);
|
bool pim_if_is_vrf_device(struct interface *ifp);
|
||||||
|
|
||||||
int pim_if_ifchannel_count(struct pim_interface *pim_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;
|
struct pim_interface *pim_ifp = ifp->info;
|
||||||
|
|
||||||
if (pim_if_is_loopback(ifp))
|
if (if_is_loopback_or_vrf(ifp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (hello_send(ifp, holdtime)) {
|
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
|
* 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;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1501,17 +1501,37 @@ static struct route_entry *rib_choose_best(struct route_entry *current,
|
|||||||
|
|
||||||
/* filter route selection in following order:
|
/* filter route selection in following order:
|
||||||
* - connected beats other types
|
* - connected beats other types
|
||||||
|
* - if both connected, loopback or vrf wins
|
||||||
* - lower distance beats higher
|
* - lower distance beats higher
|
||||||
* - lower metric beats higher for equal distance
|
* - lower metric beats higher for equal distance
|
||||||
* - last, hence oldest, route wins tie break.
|
* - 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.
|
* route of the set of lowest metric connected routes.
|
||||||
*/
|
*/
|
||||||
if (alternate->type == ZEBRA_ROUTE_CONNECT) {
|
if (alternate->type == ZEBRA_ROUTE_CONNECT) {
|
||||||
if (current->type != ZEBRA_ROUTE_CONNECT
|
if (current->type != ZEBRA_ROUTE_CONNECT)
|
||||||
|| alternate->metric <= current->metric)
|
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 alternate;
|
||||||
|
|
||||||
return current;
|
return current;
|
||||||
|
Loading…
Reference in New Issue
Block a user