summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2018-08-27 22:13:30 +0000
committervivek <vivek@cumulusnetworks.com>2018-08-27 22:13:30 +0000
commitf190902f523abaa1035cbbb385387bc6c72dd1dc (patch)
tree9472de5fb49314eba45868ed7b66376f7329b2fe /zebra/zebra_rib.c
parent9df2b997b975c7a7807e9e491989d5123d87458f (diff)
parent95d8c3ce78cdd800f4c39d196e865c2ec9213f03 (diff)
Merge remote-tracking branch 'upstream/master' into evpn-extended-mobility
Conflicts: zebra/zebra_vxlan.c
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b477cd4706..ab07549ec2 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -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;
@@ -2651,8 +2671,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
}
/* Schedule routes of a particular table (address-family) based on event. */
-static void rib_update_table(struct route_table *table,
- rib_update_event_t event)
+void rib_update_table(struct route_table *table, rib_update_event_t event)
{
struct route_node *rn;
struct route_entry *re, *next;
@@ -2732,12 +2751,18 @@ void rib_update(vrf_id_t vrf_id, rib_update_event_t event)
/* Process routes of interested address-families. */
table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (table)
+ if (table) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP event %d", __func__, event);
rib_update_table(table, event);
+ }
table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id);
- if (table)
+ if (table) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%s : AFI_IP6 event %d", __func__, event);
rib_update_table(table, event);
+ }
}
/* Delete self installed routes after zebra is relaunched. */