summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_nb_config.c3
-rw-r--r--pimd/pim_nht.c63
-rw-r--r--pimd/pim_nht.h6
-rw-r--r--pimd/pim_rpf.c7
4 files changed, 78 insertions, 1 deletions
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 39c8ae9676..2f72c956f3 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -24,6 +24,7 @@
#include "lib/northbound_cli.h"
#include "pim_igmpv3.h"
#include "pim_neighbor.h"
+#include "pim_nht.h"
#include "pim_pim.h"
#include "pim_mlag.h"
#include "pim_bfd.h"
@@ -146,6 +147,7 @@ static int pim_cmd_interface_add(struct interface *ifp)
pim_ifp->pim_enable = true;
pim_if_addr_add_all(ifp);
+ pim_upstream_nh_if_update(pim_ifp->pim, ifp);
pim_if_membership_refresh(ifp);
pim_if_create_pimreg(pim_ifp->pim);
@@ -171,6 +173,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
if (!pim_ifp->igmp_enable) {
pim_if_addr_del_all(ifp);
+ pim_upstream_nh_if_update(pim_ifp->pim, ifp);
pim_if_delete(ifp);
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index b20f801132..e4f6b5c8a5 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -469,6 +469,37 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
return 0;
}
+static int pim_upstream_nh_if_update_helper(struct hash_bucket *bucket,
+ void *arg)
+{
+ struct pim_nexthop_cache *pnc = bucket->data;
+ struct pnc_hash_walk_data *pwd = arg;
+ struct pim_instance *pim = pwd->pim;
+ struct interface *ifp = pwd->ifp;
+ struct nexthop *nh_node = NULL;
+ ifindex_t first_ifindex;
+
+ for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
+ first_ifindex = nh_node->ifindex;
+ if (ifp != if_lookup_by_index(first_ifindex, pim->vrf->vrf_id))
+ return HASHWALK_CONTINUE;
+
+ if (pnc->upstream_hash->count)
+ pim_update_upstream_nh(pim, pnc);
+ }
+ return HASHWALK_CONTINUE;
+}
+
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp)
+{
+ struct pnc_hash_walk_data pwd;
+
+ pwd.pim = pim;
+ pwd.ifp = ifp;
+
+ hash_walk(pim->rpf_hash, pim_upstream_nh_if_update_helper, &pwd);
+}
+
uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
{
uint32_t hash_val;
@@ -509,6 +540,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
// Current Nexthop is VALID, check to stay on the current path.
if (nexthop->interface && nexthop->interface->info &&
+ ((struct pim_interface *)nexthop->interface->info)->options &&
(!pim_addr_is_any(nh_addr))) {
/* User configured knob to explicitly switch
to new path is disabled or current path
@@ -623,6 +655,19 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
continue;
}
+ if (!PIM_IF_TEST_PIM(
+ ((struct pim_interface *)ifp->info)->options)) {
+ if (PIM_DEBUG_PIM_NHT)
+ zlog_debug(
+ "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pI4)",
+ __func__, ifp->name, pim->vrf->name,
+ first_ifindex, &src->u.prefix4);
+ if (nh_iter == mod_val)
+ mod_val++; // Select nexthpath
+ nh_iter++;
+ continue;
+ }
+
if (neighbor_needed &&
!pim_if_connected_to_source(ifp, src_addr)) {
nbr = nbrs[nh_iter];
@@ -633,7 +678,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
__func__, ifp->name,
pim->vrf->name);
if (nh_iter == mod_val)
- mod_val++; // Select nexthpath
+ /* Select nexthpath */
+ mod_val++;
nh_iter++;
continue;
}
@@ -977,6 +1023,21 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
i++;
continue;
}
+
+
+ if (!PIM_IF_TEST_PIM(
+ ((struct pim_interface *)ifp->info)->options)) {
+ if (PIM_DEBUG_PIM_NHT)
+ zlog_debug(
+ "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pI4)",
+ __func__, ifp->name, pim->vrf->name,
+ first_ifindex, &src->u.prefix4);
+ if (i == mod_val)
+ mod_val++;
+ i++;
+ continue;
+ }
+
if (neighbor_needed &&
!pim_if_connected_to_source(ifp, src_addr)) {
nbr = nbrs[i];
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index 24c67a229c..549329c86f 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -53,6 +53,11 @@ struct pim_nexthop_cache {
uint32_t bsr_count;
};
+struct pnc_hash_walk_data {
+ struct pim_instance *pim;
+ struct interface *ifp;
+};
+
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
struct pim_upstream *up, struct rp_info *rp,
@@ -78,4 +83,5 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_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);
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
#endif
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index 4e812ae3f0..8357536393 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -122,6 +122,13 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
__func__, ifp->name, first_ifindex,
&addr);
i++;
+ } else if (!((struct pim_interface *)ifp->info)->pim_enable) {
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug(
+ "%s: pim not enabled on input interface %s (ifindex=%d, RPF for source %pPA)",
+ __func__, ifp->name, first_ifindex,
+ &addr);
+ i++;
} else if (neighbor_needed
&& !pim_if_connected_to_source(ifp, addr)) {
nbr = pim_neighbor_find(ifp,