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.c159
1 files changed, 68 insertions, 91 deletions
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 90eb8ae407..2e5c0598c0 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -52,11 +52,11 @@
void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
struct pim_nexthop_cache *pnc, int command)
{
- struct prefix *p;
+ struct prefix p;
int ret;
- p = &(pnc->rpf.rpf_addr);
- ret = zclient_send_rnh(zclient, command, p, SAFI_UNICAST, false, false,
+ pim_addr_to_prefix(&p, pnc->rpf.rpf_addr);
+ ret = zclient_send_rnh(zclient, command, &p, SAFI_UNICAST, false, false,
pim->vrf->vrf_id);
if (ret == ZCLIENT_SEND_FAILURE)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
@@ -65,7 +65,7 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
zlog_debug(
"%s: NHT %sregistered addr %pFX(%s) with Zebra ret:%d ",
__func__,
- (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", p,
+ (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", &p,
pim->vrf->name, ret);
return;
@@ -98,7 +98,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
pnc->rp_list = list_new();
pnc->rp_list->cmp = pim_rp_list_cmp;
- snprintfrr(hash_name, sizeof(hash_name), "PNC %pFX(%s) Upstream Hash",
+ snprintfrr(hash_name, sizeof(hash_name), "PNC %pPA(%s) Upstream Hash",
&pnc->rpf.rpf_addr, pim->vrf->name);
pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
pim_upstream_equal, hash_name);
@@ -107,7 +107,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
}
static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
- struct prefix *addr)
+ pim_addr addr)
{
struct pim_nexthop_cache *pnc = NULL;
struct pim_rpf rpf;
@@ -115,7 +115,7 @@ static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
zclient = pim_zebra_zclient_get();
memset(&rpf, 0, sizeof(rpf));
- rpf.rpf_addr = *addr;
+ rpf.rpf_addr = addr;
pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) {
@@ -124,8 +124,8 @@ static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
ZEBRA_NEXTHOP_REGISTER);
if (PIM_DEBUG_PIM_NHT_DETAIL)
zlog_debug(
- "%s: NHT cache and zebra notification added for %pFX(%s)",
- __func__, addr, pim->vrf->name);
+ "%s: NHT cache and zebra notification added for %pPA(%s)",
+ __func__, &addr, pim->vrf->name);
}
return pnc;
@@ -134,7 +134,7 @@ static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
/* TBD: this does several distinct things and should probably be split up.
* (checking state vs. returning pnc vs. adding upstream vs. adding rp)
*/
-int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
+int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up, struct rp_info *rp,
struct pim_nexthop_cache *out_pnc)
{
@@ -143,7 +143,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
pnc = pim_nht_get(pim, addr);
- assertf(up || rp, "addr=%pFX", addr);
+ assertf(up || rp, "addr=%pPA", &addr);
if (rp != NULL) {
ch_node = listnode_lookup(pnc->rp_list, rp);
@@ -163,28 +163,21 @@ 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;
- pnc = pim_nht_get(pim, &pfx);
+ pnc = pim_nht_get(pim, addr);
pnc->bsr_count++;
}
-#endif /* PIM_IPV == 4 */
static void pim_nht_drop_maybe(struct pim_instance *pim,
struct pim_nexthop_cache *pnc)
{
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
- "%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld BSR count:%u",
+ "%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u",
__func__, &pnc->rpf.rpf_addr, pim->vrf->name,
pnc->rp_list->count, pnc->upstream_hash->count,
pnc->bsr_count);
@@ -206,7 +199,7 @@ static void pim_nht_drop_maybe(struct pim_instance *pim,
}
}
-void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
+void pim_delete_tracked_nexthop(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up, struct rp_info *rp)
{
struct pim_nexthop_cache *pnc = NULL;
@@ -214,11 +207,11 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
struct pim_upstream *upstream = NULL;
/* Remove from RPF hash if it is the last entry */
- lookup.rpf.rpf_addr = *addr;
+ lookup.rpf.rpf_addr = addr;
pnc = hash_lookup(pim->rpf_hash, &lookup);
if (!pnc) {
- zlog_warn("attempting to delete nonexistent NHT entry %pFX",
- addr);
+ zlog_warn("attempting to delete nonexistent NHT entry %pPA",
+ &addr);
return;
}
@@ -247,8 +240,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;
@@ -258,28 +250,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;
+ 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;
@@ -288,9 +278,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;
+ lookup.rpf.rpf_addr = bsr_addr;
pnc = hash_lookup(pim->rpf_hash, &lookup);
if (!pnc || !CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED)) {
@@ -396,12 +384,11 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
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)
{
@@ -427,7 +414,7 @@ static void pim_update_rp_nh(struct pim_instance *pim,
// Compute PIM RPF using cached nexthop
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
- &rp_info->rp.rpf_addr,
+ rp_info->rp.rpf_addr,
&rp_info->group, 1))
pim_rp_nexthop_del(rp_info);
}
@@ -497,9 +484,8 @@ uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
static int pim_ecmp_nexthop_search(struct pim_instance *pim,
struct pim_nexthop_cache *pnc,
- struct pim_nexthop *nexthop,
- struct prefix *src, struct prefix *grp,
- int neighbor_needed)
+ struct pim_nexthop *nexthop, pim_addr src,
+ struct prefix *grp, int neighbor_needed)
{
struct pim_neighbor *nbrs[router->multipath], *nbr = NULL;
struct interface *ifps[router->multipath];
@@ -510,7 +496,6 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
uint8_t nh_iter = 0, found = 0;
uint32_t i, num_nbrs = 0;
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);
if (!pnc || !pnc->nexthop_num || !nexthop)
@@ -544,7 +529,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
if (curr_route_valid &&
!pim_if_connected_to_source(nexthop->interface,
- src_addr)) {
+ src)) {
nbr = pim_neighbor_find(
nexthop->interface,
nexthop->mrib_nexthop_addr);
@@ -565,7 +550,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: (%pPA,%pPA)(%s) current nexthop %s is valid, skipping new path selection",
- __func__, &src_addr,
+ __func__, &src,
&grp_addr,
pim->vrf->name,
nexthop->interface->name);
@@ -590,12 +575,12 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
pim_addr nhaddr = nh_node->gate.ipv6;
#endif
nbrs[i] = pim_neighbor_find(ifps[i], nhaddr);
- if (nbrs[i] ||
- pim_if_connected_to_source(ifps[i], src_addr))
+ if (nbrs[i] || pim_if_connected_to_source(ifps[i], src))
num_nbrs++;
}
}
if (pim->ecmp_enable) {
+ struct prefix src_pfx;
uint32_t consider = pnc->nexthop_num;
if (neighbor_needed && num_nbrs < consider)
@@ -605,7 +590,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
return 0;
// PIM ECMP flag is enable then choose ECMP path.
- hash_val = pim_compute_ecmp_hash(src, grp);
+ pim_addr_to_prefix(&src_pfx, src);
+ hash_val = pim_compute_ecmp_hash(&src_pfx, grp);
mod_val = hash_val % consider;
}
@@ -617,8 +603,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
- __FILE__, __func__, first_ifindex,
- &src_addr, pim->vrf->name);
+ __FILE__, __func__, first_ifindex, &src,
+ pim->vrf->name);
if (nh_iter == mod_val)
mod_val++; // Select nexthpath
nh_iter++;
@@ -629,15 +615,14 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
zlog_debug(
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
__func__, ifp->name, pim->vrf->name,
- first_ifindex, &src_addr);
+ first_ifindex, &src);
if (nh_iter == mod_val)
mod_val++; // Select nexthpath
nh_iter++;
continue;
}
- if (neighbor_needed &&
- !pim_if_connected_to_source(ifp, src_addr)) {
+ if (neighbor_needed && !pim_if_connected_to_source(ifp, src)) {
nbr = nbrs[nh_iter];
if (!nbr && !if_is_loopback(ifp)) {
if (PIM_DEBUG_PIM_NHT)
@@ -661,14 +646,14 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
#endif
nexthop->mrib_metric_preference = pnc->distance;
nexthop->mrib_route_metric = pnc->metric;
- nexthop->last_lookup = src_addr;
+ nexthop->last_lookup = src;
nexthop->last_lookup_time = pim_time_monotonic_usec();
nexthop->nbr = nbr;
found = 1;
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: (%pPA,%pPA)(%s) selected nhop interface %s addr %pPAs mod_val %u iter %d ecmp %d",
- __func__, &src_addr, &grp_addr,
+ __func__, &src, &grp_addr,
pim->vrf->name, ifp->name, &nh_addr,
mod_val, nh_iter, pim->ecmp_enable);
}
@@ -708,12 +693,12 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
}
if (cmd == ZEBRA_NEXTHOP_UPDATE) {
- prefix_copy(&rpf.rpf_addr, &match);
+ rpf.rpf_addr = pim_addr_from_prefix(&match);
pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
- "%s: Skipping NHT update, addr %pFX is not in local cached DB.",
+ "%s: Skipping NHT update, addr %pPA is not in local cached DB.",
__func__, &rpf.rpf_addr);
return 0;
}
@@ -740,12 +725,10 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
*/
#if PIM_IPV == 4
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- nexthop->gate.ipv4 =
- pnc->rpf.rpf_addr.u.prefix4;
+ nexthop->gate.ipv4 = pnc->rpf.rpf_addr;
#else
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- nexthop->gate.ipv6 =
- pnc->rpf.rpf_addr.u.prefix6;
+ nexthop->gate.ipv6 = pnc->rpf.rpf_addr;
#endif
break;
#if PIM_IPV == 4
@@ -884,7 +867,7 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
}
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
- struct pim_nexthop *nexthop, struct prefix *src,
+ struct pim_nexthop *nexthop, pim_addr src,
struct prefix *grp, int neighbor_needed)
{
struct pim_nexthop_cache *pnc;
@@ -898,14 +881,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
uint8_t i = 0;
uint32_t hash_val = 0, mod_val = 0;
uint32_t num_nbrs = 0;
- pim_addr src_addr = pim_addr_from_prefix(src);
if (PIM_DEBUG_PIM_NHT_DETAIL)
zlog_debug("%s: Looking up: %pPA(%s), last lookup time: %lld",
- __func__, &src_addr, pim->vrf->name,
+ __func__, &src, pim->vrf->name,
nexthop->last_lookup_time);
- rpf.rpf_addr = *src;
+ rpf.rpf_addr = src;
pnc = pim_nexthop_cache_find(pim, &rpf);
if (pnc) {
@@ -917,13 +899,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
memset(nexthop_tab, 0,
sizeof(struct pim_zlookup_nexthop) * router->multipath);
num_ifindex =
- zclient_lookup_nexthop(pim, nexthop_tab, router->multipath,
- src_addr, PIM_NEXTHOP_LOOKUP_MAX);
+ zclient_lookup_nexthop(pim, nexthop_tab, router->multipath, src,
+ PIM_NEXTHOP_LOOKUP_MAX);
if (num_ifindex < 1) {
if (PIM_DEBUG_PIM_NHT)
zlog_warn(
"%s: could not find nexthop ifindex for address %pPA(%s)",
- __func__, &src_addr, pim->vrf->name);
+ __func__, &src, pim->vrf->name);
return 0;
}
@@ -940,14 +922,14 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
if (ifps[i]) {
nbrs[i] = pim_neighbor_find(
ifps[i], nexthop_tab[i].nexthop_addr);
- if (nbrs[i] ||
- pim_if_connected_to_source(ifps[i], src_addr))
+ if (nbrs[i] || pim_if_connected_to_source(ifps[i], src))
num_nbrs++;
}
}
// If PIM ECMP enable then choose ECMP path.
if (pim->ecmp_enable) {
+ struct prefix src_pfx;
uint32_t consider = num_ifindex;
if (neighbor_needed && num_nbrs < consider)
@@ -956,7 +938,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
if (consider == 0)
return 0;
- hash_val = pim_compute_ecmp_hash(src, grp);
+ pim_addr_to_prefix(&src_pfx, src);
+ hash_val = pim_compute_ecmp_hash(&src_pfx, grp);
mod_val = hash_val % consider;
if (PIM_DEBUG_PIM_NHT_DETAIL)
zlog_debug("%s: hash_val %u mod_val %u", __func__,
@@ -972,8 +955,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
- __FILE__, __func__, first_ifindex,
- &src_addr, pim->vrf->name);
+ __FILE__, __func__, first_ifindex, &src,
+ pim->vrf->name);
if (i == mod_val)
mod_val++;
i++;
@@ -985,14 +968,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
zlog_debug(
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
__func__, ifp->name, pim->vrf->name,
- first_ifindex, &src_addr);
+ first_ifindex, &src);
if (i == mod_val)
mod_val++;
i++;
continue;
}
- if (neighbor_needed &&
- !pim_if_connected_to_source(ifp, src_addr)) {
+ if (neighbor_needed && !pim_if_connected_to_source(ifp, src)) {
nbr = nbrs[i];
if (PIM_DEBUG_PIM_NHT_DETAIL)
zlog_debug("ifp name: %s(%s), pim nbr: %p",
@@ -1006,7 +988,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
__func__,
&nexthop_tab[i].nexthop_addr,
ifp->name, pim->vrf->name,
- &src_addr);
+ &src);
i++;
continue;
}
@@ -1017,7 +999,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
zlog_debug(
"%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,
+ &src, ifp->name, pim->vrf->name,
nexthop_tab[i].route_metric,
nexthop_tab[i].protocol_distance);
/* update nexthop data */
@@ -1028,7 +1010,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
nexthop_tab[i].protocol_distance;
nexthop->mrib_route_metric =
nexthop_tab[i].route_metric;
- nexthop->last_lookup = src_addr;
+ nexthop->last_lookup = src;
nexthop->last_lookup_time = pim_time_monotonic_usec();
nexthop->nbr = nbr;
found = 1;
@@ -1042,24 +1024,19 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
return 0;
}
-int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
- struct prefix *src, struct prefix *grp)
+int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim, pim_addr src,
+ struct prefix *grp)
{
struct pim_nexthop nhop;
int vif_index;
ifindex_t ifindex;
- pim_addr src_addr;
-
- if (PIM_DEBUG_PIM_NHT_DETAIL) {
- src_addr = pim_addr_from_prefix(src);
- }
memset(&nhop, 0, sizeof(nhop));
if (!pim_ecmp_nexthop_lookup(pim, &nhop, src, grp, 1)) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: could not find nexthop ifindex for address %pPA(%s)",
- __func__, &src_addr, pim->vrf->name);
+ __func__, &src, pim->vrf->name);
return -1;
}
@@ -1069,7 +1046,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
"%s: found nexthop ifindex=%d (interface %s(%s)) for address %pPA",
__func__, ifindex,
ifindex2ifname(ifindex, pim->vrf->vrf_id),
- pim->vrf->name, &src_addr);
+ pim->vrf->name, &src);
vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
@@ -1077,7 +1054,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
if (PIM_DEBUG_PIM_NHT) {
zlog_debug(
"%s: low vif_index=%d(%s) < 1 nexthop for address %pPA",
- __func__, vif_index, pim->vrf->name, &src_addr);
+ __func__, vif_index, pim->vrf->name, &src);
}
return -2;
}