pimd: Always create upstream reference when adding channel oil

Modify the code to create an upstream reference whenever the code
creates an channel_oil via the pim_mroute.c code.  This code also
starts a keep alive timer to clean up the reference if we do
nothing with it after the normal time.

I've left alone the source->channel_oil creation because these
are kept and tracked independently already.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2019-07-09 00:00:43 +00:00 committed by Donald Sharp
parent 46dd6edb06
commit 02434c43a5
3 changed files with 32 additions and 13 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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,