diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 417906fecf13..1c66007fbb46 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -190,8 +190,6 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, sg.grp = msg->im_dst; if (!(PIM_I_am_DR(pim_ifp))) { - struct channel_oil *c_oil; - if (PIM_DEBUG_MROUTE_DETAIL) zlog_debug("%s: Interface is not the DR blackholing incoming traffic for %s", __PRETTY_FUNCTION__, pim_str_sg_dump(&sg)); @@ -206,10 +204,10 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp, * that I see no way to get rid of. Just noting * this for future reference. */ - c_oil = pim_channel_oil_add(pim_ifp->pim, &sg, - pim_ifp->mroute_vif_index, - __PRETTY_FUNCTION__); - pim_mroute_add(c_oil, __PRETTY_FUNCTION__); + up = pim_upstream_find_or_add( + &sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE, + __PRETTY_FUNCTION__); + pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__); return 0; } @@ -454,7 +452,6 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, struct pim_upstream *up; struct prefix_sg star_g; struct prefix_sg sg; - struct channel_oil *oil; pim_ifp = ifp->info; @@ -543,10 +540,6 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, } pim_ifp = ifp->info; - 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)) { up = pim_upstream_add(pim_ifp->pim, &sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, @@ -561,13 +554,18 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp, PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags); pim_upstream_keep_alive_timer_start( up, pim_ifp->pim->keep_alive_time); - up->channel_oil = oil; up->channel_oil->cc.pktcnt++; pim_register_join(up); pim_upstream_inherited_olist(pim_ifp->pim, up); // Send the packet to the RP pim_mroute_msg_wholepkt(fd, ifp, buf); + } else { + up = pim_upstream_add(pim_ifp->pim, &sg, ifp, + PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE, + __PRETTY_FUNCTION__, NULL); + if (!up->channel_oil->installed) + pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__); } return 0; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index f89e315423f6..c0651561ac47 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -737,13 +737,18 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, if (up->sg.src.s_addr != INADDR_ANY) wheel_add_item(pim->upstream_sg_wheel, up); - if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) { + if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags) + || PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)) { pim_upstream_fill_static_iif(up, incoming); pim_ifp = up->rpf.source_nexthop.interface->info; assert(pim_ifp); pim_channel_oil_change_iif(pim, up->channel_oil, pim_ifp->mroute_vif_index, __PRETTY_FUNCTION__); + + if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)) + pim_upstream_keep_alive_timer_start( + up, pim->keep_alive_time); } else if (up->upstream_addr.s_addr != INADDR_ANY) { rpf_result = pim_rpf_update(pim, up, NULL); if (rpf_result == PIM_RPF_FAILURE) { @@ -1179,6 +1184,13 @@ struct pim_upstream *pim_upstream_keep_alive_timer_proc( if (!pim_upstream_del(pim, up, __PRETTY_FUNCTION__)) return NULL; } + if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags)) { + PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(up->flags); + + if (!pim_upstream_del(pim, up, __PRETTY_FUNCTION__)) + return NULL; + } + /* upstream reference would have been added to track the local * membership if it is LHR. We have to clear it when KAT expires. * Otherwise would result in stale entry with uncleared ref count. diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 02ae99829057..c6c9291eed49 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -74,6 +74,13 @@ * blackholing the traffic pulled down to the LHR. */ #define PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF (1 << 17) +/* + * We are creating a non-joined upstream data structure + * for this S,G as that we want to have a channel oil + * associated with an upstream + */ +#define PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE (1 << 19) + #define PIM_UPSTREAM_FLAG_ALL 0xFFFFFFFF #define PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) @@ -95,6 +102,7 @@ #define PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN(flags) ((flags) & (PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_ORIG | PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)) #define PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN) #define PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF) +#define PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(flags) ((flags) &PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE) #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED) #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED) @@ -133,6 +141,7 @@ #define PIM_UPSTREAM_FLAG_UNSET_SRC_VXLAN_TERM(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM) #define PIM_UPSTREAM_FLAG_UNSET_MLAG_VXLAN(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN) #define PIM_UPSTREAM_FLAG_UNSET_MLAG_NON_DF(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF) +#define PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE) enum pim_upstream_state { PIM_UPSTREAM_NOTJOINED,