#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);
* and causing us to consider them.
*/
c_oil = pim_channel_oil_add(pim_ifp->pim, &sg,
- pim_ifp->mroute_vif_index);
+ pim_ifp->mroute_vif_index,
+ __PRETTY_FUNCTION__);
pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
return 0;
if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)) {
// No if channel, but upstream we are at the RP.
if (pim_nexthop_lookup(pim_ifp->pim, &source,
- up->upstream_register, 0)
- == 0) {
+ up->upstream_register, 0)) {
pim_register_stop_send(source.interface, &sg,
pim_ifp->primary_address,
up->upstream_register);
if (!up->channel_oil)
up->channel_oil = pim_channel_oil_add(
pim_ifp->pim, &sg,
- pim_ifp->mroute_vif_index);
+ pim_ifp->mroute_vif_index,
+ __PRETTY_FUNCTION__);
pim_upstream_inherited_olist(pim_ifp->pim, up);
if (!up->channel_oil->installed)
pim_mroute_add(up->channel_oil,
} else {
if (I_am_RP(pim_ifp->pim, up->sg.grp)) {
if (pim_nexthop_lookup(pim_ifp->pim, &source,
- up->upstream_register, 0)
- == 0)
+ up->upstream_register,
+ 0))
pim_register_stop_send(
source.interface, &sg,
pim_ifp->primary_address,
}
pim_ifp = ifp->info;
- oil = pim_channel_oil_add(pim_ifp->pim, &sg, pim_ifp->mroute_vif_index);
+ oil = pim_channel_oil_add(pim_ifp->pim, &sg, pim_ifp->mroute_vif_index,
+ __PRETTY_FUNCTION__);
if (!oil->installed)
pim_mroute_add(oil, __PRETTY_FUNCTION__);
if (pim_if_connected_to_source(ifp, sg.src)) {
int err;
int orig = 0;
int orig_iif_vif = 0;
+ struct pim_interface *pim_reg_ifp = NULL;
+ int orig_pimreg_ttl = 0;
+ bool pimreg_ttl_reset = false;
+ struct pim_interface *vxlan_ifp = NULL;
+ int orig_term_ttl = 0;
+ bool orig_term_ttl_reset = false;
pim->mroute_add_last = pim_time_monotonic_sec();
++pim->mroute_add_events;
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
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) {
+ assert(pim_reg_ifp);
+ 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",
}
c_oil->installed = 1;
+ c_oil->mroute_creation = pim_time_monotonic_sec();
+
return 0;
}
sg.grp = c_oil->oil.mfcc_mcastgrp;
if (PIM_DEBUG_MROUTE)
zlog_debug(
- "Channel(%s) is not installed no need to collect data from kernel",
+ "Channel%s is not installed no need to collect data from kernel",
pim_str_sg_dump(&sg));
}
return;
sg.grp = c_oil->oil.mfcc_mcastgrp;
zlog_warn(
- "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s): errno=%d: %s",
+ "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=%s: errno=%d: %s",
(unsigned long)SIOCGETSGCNT,
pim_str_sg_dump(&sg), errno,
safe_strerror(errno));