diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-06-22 11:05:03 -0400 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-07-24 13:51:40 -0400 |
| commit | 0885a9f1f4352996d95766b69fc29e464adee01c (patch) | |
| tree | 93cca0199ebd05321ecc31928f5c43eed9a6f89a /pimd/pim_ifchannel.c | |
| parent | 96ceedc7a27404a148bc9cc513b5b60e286cffc2 (diff) | |
pimd: Fix code to not send joins when SGRPT Prune is received
When we receive a SGRPT Prune we were switching the upstream
to JOINED and immediately sending a join. This was not
the right thing to do.
This was happening because we were making decisions about the
new ifchannel before it was fully formed.
Rework ifchannel startup to provide enough information to
the pim upstream data structure to make the right decisions
Ticket: CM-16425
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'pimd/pim_ifchannel.c')
| -rw-r--r-- | pimd/pim_ifchannel.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 5f3901e49b..922ee647a5 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -509,7 +509,8 @@ static struct pim_ifchannel *pim_ifchannel_find_parent(struct pim_ifchannel *ch) } struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, - struct prefix_sg *sg, int flags) + struct prefix_sg *sg, + uint8_t source_flags, int up_flags) { struct pim_interface *pim_ifp; struct pim_ifchannel *ch; @@ -521,27 +522,19 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_ifp = ifp->info; - up = pim_upstream_add(pim_ifp->pim, sg, NULL, flags, - __PRETTY_FUNCTION__); - if (!up) { - zlog_err( - "%s: could not attach upstream (S,G)=%s on interface %s", - __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); - return NULL; - } - ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch)); if (!ch) { zlog_warn( "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s", __PRETTY_FUNCTION__, up->sg_str, ifp->name); - - pim_upstream_del(pim_ifp->pim, up, __PRETTY_FUNCTION__); return NULL; } ch->flags = 0; - ch->upstream = up; + if ((source_flags & PIM_ENCODE_RPT_BIT) + && !(source_flags & PIM_ENCODE_WC_BIT)) + PIM_IF_FLAG_SET_S_G_RPT(ch->flags); + ch->interface = ifp; ch->sg = *sg; pim_str_sg_set(sg, ch->sg_str); @@ -561,6 +554,32 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, ch->t_ifjoin_prune_pending_timer = NULL; ch->ifjoin_creation = 0; + /* Attach to list */ + listnode_add_sort(pim_ifp->pim_ifchannel_list, ch); + ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern); + listnode_add_sort(pim_ifp->pim->ifchannel_list, ch); + + up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags, + __PRETTY_FUNCTION__, ch); + + if (!up) { + zlog_err( + "%s: could not attach upstream (S,G)=%s on interface %s", + __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); + + pim_ifchannel_remove_children(ch); + if (ch) + list_delete(ch->sources); + + listnode_delete(pim_ifp->pim_ifchannel_list, ch); + hash_release(pim_ifp->pim_ifchannel_hash, ch); + listnode_delete(pim_ifp->pim->ifchannel_list, ch); + XFREE(MTYPE_PIM_IFCHANNEL, ch); + return NULL; + } + + listnode_add_sort(up->ifchannels, ch); + ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch); ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval(ch); @@ -580,13 +599,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, else PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags); - /* Attach to list */ - listnode_add_sort(pim_ifp->pim_ifchannel_list, ch); - ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern); - listnode_add_sort(pim_ifp->pim->ifchannel_list, ch); - - listnode_add_sort(up->ifchannels, ch); - if (PIM_DEBUG_PIM_TRACE) zlog_debug("%s: ifchannel %s is created ", __PRETTY_FUNCTION__, ch->sg_str); @@ -772,7 +784,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr, return; } - ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM); + ch = pim_ifchannel_add(ifp, sg, source_flags, + PIM_UPSTREAM_FLAG_MASK_SRC_PIM); if (!ch) return; @@ -914,7 +927,8 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, return; } - ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM); + ch = pim_ifchannel_add(ifp, sg, source_flags, + PIM_UPSTREAM_FLAG_MASK_SRC_PIM); if (!ch) return; @@ -1027,7 +1041,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp, } } - ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); + ch = pim_ifchannel_add(ifp, sg, 0, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); if (!ch) { return 0; } |
