From e711cd3cece039d91a59834e6a9396f878b99c56 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 10 Mar 2017 10:26:00 -0500 Subject: [PATCH] pimd: Carefully Reconstruct FHR state when interface bounces When an interface bounces and we receive a packet before pim has a chance to fully bring the 'struct pim_usptream' back up correctly, first check to see if we already have an associated data structure before creating it again. This removes a case where both the c_oil and up ref counts were being incremented and never removed properly. Signed-off-by: Donald Sharp --- pimd/pim_mroute.c | 30 ++++++++++-------------------- pimd/pim_upstream.c | 23 +++++++++++++++++++++++ pimd/pim_upstream.h | 3 +++ 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index a244534ab4..04b6a4c697 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -118,7 +118,6 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg struct pim_upstream *up; struct pim_rpf *rpg; struct prefix_sg sg; - struct channel_oil *oil; rpg = RP(msg->im_dst); /* @@ -153,25 +152,17 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg sg.src = msg->im_src; sg.grp = msg->im_dst; - oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index); - if (!oil) { - if (PIM_DEBUG_MROUTE) { - zlog_debug("%s: Failure to add channel oil for %s", - __PRETTY_FUNCTION__, - pim_str_sg_dump (&sg)); - } - return 0; - } - - up = pim_upstream_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__); - if (!up) { - if (PIM_DEBUG_MROUTE) { - zlog_debug("%s: Failure to add upstream information for %s", - __PRETTY_FUNCTION__, - pim_str_sg_dump (&sg)); + up = pim_upstream_find_or_add (&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR, __PRETTY_FUNCTION__); + if (!up) + { + if (PIM_DEBUG_MROUTE) + { + zlog_debug("%s: Failure to add upstream information for %s", + __PRETTY_FUNCTION__, + pim_str_sg_dump (&sg)); + } + return 0; } - return 0; - } /* * I moved this debug till after the actual add because @@ -185,7 +176,6 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg PIM_UPSTREAM_FLAG_SET_SRC_STREAM(up->flags); pim_upstream_keep_alive_timer_start (up, qpim_keep_alive_time); - up->channel_oil = oil; up->channel_oil->cc.pktcnt++; PIM_UPSTREAM_FLAG_SET_FHR(up->flags); pim_channel_add_oif (up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 183db532ba..b29e71a334 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -669,6 +669,29 @@ struct pim_upstream *pim_upstream_find(struct prefix_sg *sg) return up; } +struct pim_upstream * +pim_upstream_find_or_add(struct prefix_sg *sg, + struct interface *incoming, + int flags, const char *name) +{ + struct pim_upstream *up; + + up = pim_upstream_find(sg); + + if (up) + { + if (!(up->flags & flags)) + { + up->flags |= flags; + up->ref_count++; + } + } + else + up = pim_upstream_add (sg, incoming, flags, name); + + return up; +} + static void pim_upstream_ref(struct pim_upstream *up, int flags) { up->flags |= flags; diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 0bc4c4410a..21c78021e5 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -129,6 +129,9 @@ struct hash *pim_upstream_hash; void pim_upstream_free(struct pim_upstream *up); struct pim_upstream *pim_upstream_find (struct prefix_sg *sg); +struct pim_upstream *pim_upstream_find_or_add (struct prefix_sg *sg, + struct interface *ifp, int flags, + const char *name); struct pim_upstream *pim_upstream_add (struct prefix_sg *sg, struct interface *ifp, int flags, const char *name); -- 2.39.5