diff options
| author | David Lamparter <equinox@diac24.net> | 2018-08-24 04:19:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-24 04:19:02 +0200 |
| commit | ff0c9e7a0abf46750b40a41464ecd7aabea0e97c (patch) | |
| tree | d2be957988ae75889b55dd385d45916f7b237c7c /zebra/zebra_rib.c | |
| parent | 3391232343ee5a92b17755bd29d3a246a660f3be (diff) | |
| parent | fec4ca191ef4e7d9576feba756f728b21819ec45 (diff) | |
Merge pull request #2896 from dslicenc/zebra_select_vrf
zebra: if multiple connecteds, select loopback or vrf if present
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 99b83d5cd9..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; |
