summaryrefslogtreecommitdiff
path: root/pimd/pim_nht.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_nht.c')
-rw-r--r--pimd/pim_nht.c133
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 =