summaryrefslogtreecommitdiff
path: root/pimd/pim_mroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_mroute.c')
-rw-r--r--pimd/pim_mroute.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index a2d50aba51..866a19fc98 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -42,6 +42,7 @@
#include "pim_zlookup.h"
#include "pim_ssm.h"
#include "pim_sock.h"
+#include "pim_vxlan.h"
static void mroute_read_on(struct pim_instance *pim);
@@ -896,6 +897,12 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
int err;
int orig = 0;
int orig_iif_vif = 0;
+ struct pim_interface *pim_reg_ifp;
+ int orig_pimreg_ttl;
+ bool pimreg_ttl_reset = false;
+ struct pim_interface *vxlan_ifp;
+ int orig_term_ttl;
+ bool orig_term_ttl_reset = false;
pim->mroute_add_last = pim_time_monotonic_sec();
++pim->mroute_add_events;
@@ -921,6 +928,37 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = 1;
}
+ if (c_oil->up) {
+ /* suppress pimreg in the OIL if the mroute is not supposed to
+ * trigger register encapsulated data
+ */
+ if (PIM_UPSTREAM_FLAG_TEST_NO_PIMREG_DATA(c_oil->up->flags)) {
+ pim_reg_ifp = pim->regiface->info;
+ orig_pimreg_ttl =
+ c_oil->oil.mfcc_ttls[pim_reg_ifp->mroute_vif_index];
+ c_oil->oil.mfcc_ttls[pim_reg_ifp->mroute_vif_index] = 0;
+ /* remember to flip it back after MFC programming */
+ pimreg_ttl_reset = true;
+ }
+
+ vxlan_ifp = pim_vxlan_get_term_ifp(pim);
+ /* 1. vxlan termination device must never be added to the
+ * origination mroute (and that can actually happen because
+ * of XG inheritance from the termination mroute) otherwise
+ * traffic will end up looping.
+ * 2. vxlan termination device should be removed from the non-DF
+ * to prevent duplicates to the overlay rxer
+ */
+ if (vxlan_ifp &&
+ (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(c_oil->up->flags) ||
+ PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(c_oil->up->flags))) {
+ orig_term_ttl_reset = true;
+ orig_term_ttl =
+ c_oil->oil.mfcc_ttls[vxlan_ifp->mroute_vif_index];
+ c_oil->oil.mfcc_ttls[vxlan_ifp->mroute_vif_index] = 0;
+ }
+ }
+
/*
* If we have an unresolved cache entry for the S,G
* it is owned by the pimreg for the incoming IIF
@@ -947,6 +985,14 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
c_oil->oil.mfcc_ttls[c_oil->oil.mfcc_parent] = orig;
+ if (pimreg_ttl_reset)
+ c_oil->oil.mfcc_ttls[pim_reg_ifp->mroute_vif_index] =
+ orig_pimreg_ttl;
+
+ if (orig_term_ttl_reset)
+ c_oil->oil.mfcc_ttls[vxlan_ifp->mroute_vif_index] =
+ orig_term_ttl;
+
if (err) {
zlog_warn(
"%s %s: failure: setsockopt(fd=%d,IPPROTO_IP,MRT_ADD_MFC): errno=%d: %s",