diff options
Diffstat (limited to 'pimd/pim_nht.c')
| -rw-r--r-- | pimd/pim_nht.c | 133 |
1 files changed, 60 insertions, 73 deletions
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index f1508f7631..e4f6b5c8a5 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -162,21 +162,16 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr, return 0; } -#if PIM_IPV == 4 -void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr addr) +void pim_nht_bsr_add(struct pim_instance *pim, pim_addr addr) { struct pim_nexthop_cache *pnc; struct prefix pfx; - pfx.family = AF_INET; - pfx.prefixlen = IPV4_MAX_BITLEN; - pfx.u.prefix4 = addr; - + pim_addr_to_prefix(&pfx, addr); pnc = pim_nht_get(pim, &pfx); pnc->bsr_count++; } -#endif /* PIM_IPV == 4 */ static void pim_nht_drop_maybe(struct pim_instance *pim, struct pim_nexthop_cache *pnc) @@ -246,8 +241,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr, pim_nht_drop_maybe(pim, pnc); } -#if PIM_IPV == 4 -void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr) +void pim_nht_bsr_del(struct pim_instance *pim, pim_addr addr) { struct pim_nexthop_cache *pnc = NULL; struct pim_nexthop_cache lookup; @@ -257,28 +251,26 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr) * is 0.0.0.0 as that the BSR has not been registered * for tracking yet. */ - if (addr.s_addr == INADDR_ANY) + if (pim_addr_is_any(addr)) return; - lookup.rpf.rpf_addr.family = AF_INET; - lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN; - lookup.rpf.rpf_addr.u.prefix4 = addr; + pim_addr_to_prefix(&lookup.rpf.rpf_addr, addr); pnc = hash_lookup(pim->rpf_hash, &lookup); if (!pnc) { - zlog_warn("attempting to delete nonexistent NHT BSR entry %pI4", + zlog_warn("attempting to delete nonexistent NHT BSR entry %pPA", &addr); return; } - assertf(pnc->bsr_count > 0, "addr=%pI4", &addr); + assertf(pnc->bsr_count > 0, "addr=%pPA", &addr); pnc->bsr_count--; pim_nht_drop_maybe(pim, pnc); } -bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr, +bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr, struct interface *src_ifp, pim_addr src_ip) { struct pim_nexthop_cache *pnc = NULL; @@ -287,9 +279,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr, struct nexthop *nh; struct interface *ifp; - lookup.rpf.rpf_addr.family = AF_INET; - lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN; - lookup.rpf.rpf_addr.u.prefix4 = bsr_addr; + pim_addr_to_prefix(&lookup.rpf.rpf_addr, bsr_addr); pnc = hash_lookup(pim->rpf_hash, &lookup); if (!pnc || !CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED)) { @@ -331,13 +321,12 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr, if (if_is_loopback(ifp) && if_is_loopback(src_ifp)) return true; - nbr = pim_neighbor_find_prefix(ifp, &znh->nexthop_addr); + nbr = pim_neighbor_find(ifp, znh->nexthop_addr); if (!nbr) continue; - return znh->ifindex == src_ifp->ifindex - && znh->nexthop_addr.u.prefix4.s_addr - == src_ip.s_addr; + return znh->ifindex == src_ifp->ifindex && + (!pim_addr_cmp(znh->nexthop_addr, src_ip)); } return false; } @@ -395,19 +384,16 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr, nbr = pim_neighbor_find(ifp, nhaddr); if (!nbr) continue; - - return nh->ifindex == src_ifp->ifindex - && nhaddr.s_addr == src_ip.s_addr; + return nh->ifindex == src_ifp->ifindex && + (!pim_addr_cmp(nhaddr, src_ip)); } return false; } -#endif /* PIM_IPV == 4 */ void pim_rp_nexthop_del(struct rp_info *rp_info) { rp_info->rp.source_nexthop.interface = NULL; - pim_addr_to_prefix(&rp_info->rp.source_nexthop.mrib_nexthop_addr, - PIMADDR_ANY); + rp_info->rp.source_nexthop.mrib_nexthop_addr = PIMADDR_ANY; rp_info->rp.source_nexthop.mrib_metric_preference = router->infinite_assert_metric.metric_preference; rp_info->rp.source_nexthop.mrib_route_metric = @@ -541,7 +527,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim, uint32_t hash_val = 0, mod_val = 0; uint8_t nh_iter = 0, found = 0; uint32_t i, num_nbrs = 0; - pim_addr nh_addr = pim_addr_from_prefix(&(nexthop->mrib_nexthop_addr)); + pim_addr nh_addr = nexthop->mrib_nexthop_addr; pim_addr src_addr = pim_addr_from_prefix(src); pim_addr grp_addr = pim_addr_from_prefix(grp); @@ -578,9 +564,9 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim, if (curr_route_valid && !pim_if_connected_to_source(nexthop->interface, src_addr)) { - nbr = pim_neighbor_find_prefix( + nbr = pim_neighbor_find( nexthop->interface, - &nexthop->mrib_nexthop_addr); + nexthop->mrib_nexthop_addr); if (!nbr && !if_is_loopback(nexthop->interface)) { if (PIM_DEBUG_PIM_NHT) @@ -701,14 +687,10 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim, if (nh_iter == mod_val) { nexthop->interface = ifp; - nexthop->mrib_nexthop_addr.family = PIM_AF; - nexthop->mrib_nexthop_addr.prefixlen = PIM_MAX_BITLEN; #if PIM_IPV == 4 - nexthop->mrib_nexthop_addr.u.prefix4 = - nh_node->gate.ipv4; + nexthop->mrib_nexthop_addr = nh_node->gate.ipv4; #else - nexthop->mrib_nexthop_addr.u.prefix6 = - nh_node->gate.ipv6; + nexthop->mrib_nexthop_addr = nh_node->gate.ipv6; #endif nexthop->mrib_metric_preference = pnc->distance; nexthop->mrib_route_metric = pnc->metric; @@ -742,9 +724,7 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) int i; struct pim_rpf rpf; struct pim_nexthop_cache *pnc = NULL; - struct pim_neighbor *nbr = NULL; struct interface *ifp = NULL; - struct interface *ifp1 = NULL; struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct pim_instance *pim; struct zapi_route nhr; @@ -785,11 +765,6 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) for (i = 0; i < nhr.nexthop_num; i++) { nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]); switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_BLACKHOLE: - break; case NEXTHOP_TYPE_IFINDEX: /* * Connected route (i.e. no nexthop), use @@ -806,31 +781,44 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) pnc->rpf.rpf_addr.u.prefix6; #endif break; - case NEXTHOP_TYPE_IPV6_IFINDEX: +#if PIM_IPV == 4 + /* RFC5549 IPv4-over-IPv6 nexthop handling: + * if we get an IPv6 nexthop in IPv4 PIM, hunt down a + * PIM neighbor and use that instead. + */ + case NEXTHOP_TYPE_IPV6_IFINDEX: { + struct interface *ifp1 = NULL; + struct pim_neighbor *nbr = NULL; + ifp1 = if_lookup_by_index(nexthop->ifindex, pim->vrf->vrf_id); if (!ifp1) nbr = NULL; else + /* FIXME: should really use nbr's + * secondary address list here + */ nbr = pim_neighbor_find_if(ifp1); + /* Overwrite with Nbr address as NH addr */ if (nbr) -#if PIM_IPV == 4 nexthop->gate.ipv4 = nbr->source_addr; -#else - nexthop->gate.ipv6 = nbr->source_addr; -#endif - else { + else // Mark nexthop address to 0 until PIM // Nbr is resolved. -#if PIM_IPV == 4 nexthop->gate.ipv4 = PIMADDR_ANY; + + break; + } #else - nexthop->gate.ipv6 = PIMADDR_ANY; + case NEXTHOP_TYPE_IPV6_IFINDEX: #endif - } - + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + /* nothing to do for the other nexthop types */ break; } @@ -850,13 +838,18 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) continue; } - if (PIM_DEBUG_PIM_NHT) + if (PIM_DEBUG_PIM_NHT) { +#if PIM_IPV == 4 + pim_addr nhaddr = nexthop->gate.ipv4; +#else + pim_addr nhaddr = nexthop->gate.ipv6; +#endif zlog_debug( - "%s: NHT addr %pFX(%s) %d-nhop via %pI4(%s) type %d distance:%u metric:%u ", + "%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ", __func__, &match, pim->vrf->name, i + 1, - &nexthop->gate.ipv4, ifp->name, - nexthop->type, nhr.distance, - nhr.metric); + &nhaddr, ifp->name, nexthop->type, + nhr.distance, nhr.metric); + } if (!ifp->info) { /* @@ -977,8 +970,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim, ifps[i] = if_lookup_by_index(nexthop_tab[i].ifindex, pim->vrf->vrf_id); if (ifps[i]) { - nbrs[i] = pim_neighbor_find_prefix( - ifps[i], &nexthop_tab[i].nexthop_addr); + nbrs[i] = pim_neighbor_find( + ifps[i], nexthop_tab[i].nexthop_addr); if (nbrs[i] || pim_if_connected_to_source(ifps[i], src_addr)) num_nbrs++; @@ -1056,7 +1049,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim, mod_val++; if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: NBR (%pFXh) not found on input interface %s(%s) (RPF for source %pPA)", + "%s: NBR (%pPA) not found on input interface %s(%s) (RPF for source %pPA)", __func__, &nexthop_tab[i].nexthop_addr, ifp->name, pim->vrf->name, @@ -1067,19 +1060,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim, } if (i == mod_val) { - if (PIM_DEBUG_PIM_NHT) { - char nexthop_str[PREFIX_STRLEN]; - - pim_addr_dump("<nexthop?>", - &nexthop_tab[i].nexthop_addr, - nexthop_str, sizeof(nexthop_str)); + if (PIM_DEBUG_PIM_NHT) zlog_debug( - "%s: found nhop %s for addr %pPA interface %s(%s) metric %d dist %d", - __func__, nexthop_str, &src_addr, - ifp->name, pim->vrf->name, + "%s: found nhop %pPA for addr %pPA interface %s(%s) metric %d dist %d", + __func__, &nexthop_tab[i].nexthop_addr, + &src_addr, ifp->name, pim->vrf->name, nexthop_tab[i].route_metric, nexthop_tab[i].protocol_distance); - } /* update nexthop data */ nexthop->interface = ifp; nexthop->mrib_nexthop_addr = |
