summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_cmd.c5
-rw-r--r--pimd/pim_mroute.c46
-rw-r--r--pimd/pim_mroute.h2
-rw-r--r--pimd/pim_oil.c43
4 files changed, 53 insertions, 43 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 25ea42473b..e49566089f 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -5405,6 +5405,11 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
& PIM_OIF_FLAG_MUTE)
continue;
+ if (c_oil->oil.mfcc_parent == oif_vif_index &&
+ !pim_mroute_allow_iif_in_oil(c_oil,
+ oif_vif_index))
+ continue;
+
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
pim_time_uptime(
mroute_uptime, sizeof(mroute_uptime),
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 7b8ea5f7f7..39ced27278 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -878,6 +878,46 @@ int pim_mroute_del_vif(struct interface *ifp)
return 0;
}
+/*
+ * Prevent creating MFC entry with OIF=IIF.
+ *
+ * This is a protection against implementation mistakes.
+ *
+ * PIM protocol implicitely ensures loopfree multicast topology.
+ *
+ * IGMP must be protected against adding looped MFC entries created
+ * by both source and receiver attached to the same interface. See
+ * TODO T22.
+ * We shall allow igmp to create upstream when it is DR for the intf.
+ * Assume RP reachable via non DR.
+ */
+bool pim_mroute_allow_iif_in_oil(struct channel_oil *c_oil,
+ int oif_index)
+{
+#ifdef PIM_ENFORCE_LOOPFREE_MFC
+ struct interface *ifp_out;
+ struct pim_interface *pim_ifp;
+
+ if (c_oil->up &&
+ PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL(c_oil->up->flags))
+ return true;
+
+ ifp_out = pim_if_find_by_vif_index(c_oil->pim, oif_index);
+ if (!ifp_out)
+ return false;
+ pim_ifp = ifp_out->info;
+ if (!pim_ifp)
+ return false;
+ if ((c_oil->oif_flags[oif_index] & PIM_OIF_FLAG_PROTO_IGMP) &&
+ PIM_I_am_DR(pim_ifp))
+ return true;
+
+ return false;
+#else
+ return true;
+#endif
+}
+
static inline void pim_mroute_copy(struct mfcctl *oil,
struct channel_oil *c_oil)
{
@@ -888,6 +928,12 @@ static inline void pim_mroute_copy(struct mfcctl *oil,
oil->mfcc_parent = c_oil->oil.mfcc_parent;
for (i = 0; i < MAXVIFS; ++i) {
+ if ((oil->mfcc_parent == i) &&
+ !pim_mroute_allow_iif_in_oil(c_oil, i)) {
+ oil->mfcc_ttls[i] = 0;
+ continue;
+ }
+
if (c_oil->oif_flags[i] & PIM_OIF_FLAG_MUTE)
oil->mfcc_ttls[i] = 0;
else
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index eadd39eece..2d8e1b01fb 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -183,4 +183,6 @@ void pim_static_mroute_iif_update(struct channel_oil *c_oil,
int pim_mroute_del(struct channel_oil *c_oil, const char *name);
void pim_mroute_update_counters(struct channel_oil *c_oil);
+bool pim_mroute_allow_iif_in_oil(struct channel_oil *c_oil,
+ int oif_index);
#endif /* PIM_MROUTE_H */
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index ed404ba498..178ba27bc8 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -460,7 +460,6 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
{
struct pim_interface *pim_ifp;
int old_ttl;
- bool allow_iif_in_oil = false;
/*
* If we've gotten here we've gone bad, but let's
@@ -473,48 +472,6 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
pim_ifp = oif->info;
-#ifdef PIM_ENFORCE_LOOPFREE_MFC
- /*
- Prevent creating MFC entry with OIF=IIF.
-
- This is a protection against implementation mistakes.
-
- PIM protocol implicitely ensures loopfree multicast topology.
-
- IGMP must be protected against adding looped MFC entries created
- by both source and receiver attached to the same interface. See
- TODO T22.
- We shall allow igmp to create upstream when it is DR for the intf.
- Assume RP reachable via non DR.
- */
- if ((channel_oil->up &&
- PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL(channel_oil->up->flags)) ||
- ((proto_mask == PIM_OIF_FLAG_PROTO_IGMP) && PIM_I_am_DR(pim_ifp))) {
- allow_iif_in_oil = true;
- }
-
- if (!allow_iif_in_oil &&
- pim_ifp->mroute_vif_index == channel_oil->oil.mfcc_parent) {
- channel_oil->oil_inherited_rescan = 1;
- if (PIM_DEBUG_MROUTE) {
- char group_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<group?>",
- channel_oil->oil.mfcc_mcastgrp,
- group_str, sizeof(group_str));
- pim_inet4_dump("<source?>",
- channel_oil->oil.mfcc_origin, source_str,
- sizeof(source_str));
- zlog_debug(
- "%s %s: refusing protocol mask %u request for IIF=OIF=%s (vif_index=%d) for channel (S,G)=(%s,%s)",
- __FILE__, __PRETTY_FUNCTION__, proto_mask,
- oif->name, pim_ifp->mroute_vif_index,
- source_str, group_str);
- }
- return -2;
- }
-#endif
-
/* Prevent single protocol from subscribing same interface to
channel (S,G) multiple times */
if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {