diff options
Diffstat (limited to 'zebra/zebra_nhg.c')
| -rw-r--r-- | zebra/zebra_nhg.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 9bfd7aacb7..43bf745896 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1775,6 +1775,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, struct interface *ifp; rib_dest_t *dest; struct zebra_vrf *zvrf; + struct in_addr ipv4; if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) @@ -1835,13 +1836,23 @@ static int nexthop_active(afi_t afi, struct route_entry *re, return 0; } + /* Validation for ipv4 mapped ipv6 nexthop. */ + if (IS_MAPPED_IPV6(&nexthop->gate.ipv6)) { + afi = AFI_IP; + } + /* Make lookup prefix. */ memset(&p, 0, sizeof(struct prefix)); switch (afi) { case AFI_IP: p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; - p.u.prefix4 = nexthop->gate.ipv4; + if (IS_MAPPED_IPV6(&nexthop->gate.ipv6)) { + ipv4_mapped_ipv6_to_ipv4(&nexthop->gate.ipv6, &ipv4); + p.u.prefix4 = ipv4; + } else { + p.u.prefix4 = nexthop->gate.ipv4; + } break; case AFI_IP6: p.family = AF_INET6; @@ -1951,8 +1962,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re, goto done_with_match; } - /* Examine installed nexthops */ - nhg = &match->nhe->nhg; + /* Examine installed nexthops; note that there + * may not be any installed primary nexthops if + * only backups are installed. + */ + nhg = rib_get_fib_nhg(match); for (ALL_NEXTHOPS_PTR(nhg, newhop)) { if (!nexthop_valid_resolve(nexthop, newhop)) continue; @@ -1973,8 +1987,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, * dedicated fib list. */ nhg = rib_get_fib_backup_nhg(match); - if (nhg == NULL || - nhg == zebra_nhg_get_backup_nhg(match->nhe)) + if (nhg == NULL || nhg->nexthop == NULL) goto done_with_match; for (ALL_NEXTHOPS_PTR(nhg, newhop)) { |
