summaryrefslogtreecommitdiff
path: root/zebra/zebra_nhg.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_nhg.c')
-rw-r--r--zebra/zebra_nhg.c23
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)) {