memset(&sg, 0, sizeof(struct prefix_sg));
sg.src = source_addr;
sg.grp = group_addr;
- ch = pim_ifchannel_add(ifp, &sg, 0);
+ ch = pim_ifchannel_add(ifp, &sg, 0, 0);
if (!ch) {
zlog_warn(
"%s: (S,G)=%s failure creating channel on interface %s",
}
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;
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);
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);
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);
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;
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;
}
}
- 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;
}
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
struct prefix_sg *sg);
struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
- struct prefix_sg *sg, int flags);
+ struct prefix_sg *sg, uint8_t ch_flags,
+ int up_flags);
void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
struct in_addr upstream, struct prefix_sg *sg,
uint8_t source_flags, uint16_t holdtime);
if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) {
up = pim_upstream_add(pim_ifp->pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_SRC_LHR,
- __PRETTY_FUNCTION__);
+ __PRETTY_FUNCTION__, NULL);
if (!up) {
if (PIM_DEBUG_MROUTE)
zlog_debug(
if (pim_if_connected_to_source(ifp, sg.src)) {
up = pim_upstream_add(pim_ifp->pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_FHR,
- __PRETTY_FUNCTION__);
+ __PRETTY_FUNCTION__, NULL);
if (!up) {
if (PIM_DEBUG_MROUTE)
zlog_debug(
* as if a JP message was rxed addressed to the RP itself." */
up = pim_upstream_add(sa->pim, &sa->sg, NULL /* iif */,
PIM_UPSTREAM_FLAG_MASK_SRC_MSDP,
- __PRETTY_FUNCTION__);
+ __PRETTY_FUNCTION__, NULL);
sa->up = up;
if (up) {
upstream = pim_upstream_add(
pim_ifp->pim, &sg, ifp,
PIM_UPSTREAM_FLAG_MASK_SRC_STREAM,
- __PRETTY_FUNCTION__);
+ __PRETTY_FUNCTION__, NULL);
if (!upstream) {
zlog_warn("Failure to create upstream state");
return 1;
static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
struct prefix_sg *sg,
struct interface *incoming,
- int flags)
+ int flags,
+ struct pim_ifchannel *ch)
{
enum pim_rpf_result rpf_result;
struct pim_interface *pim_ifp;
up->sg = *sg;
pim_str_sg_set(sg, up->sg_str);
+ if (ch)
+ ch->upstream = up;
+
up = hash_get(pim->upstream_hash, up, hash_alloc_intern);
if (!pim_rp_set_upstream_addr(pim, &up->upstream_addr, sg->src,
sg->grp)) {
up->ref_count);
}
} else
- up = pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name);
+ up = pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name,
+ NULL);
return up;
}
struct pim_upstream *pim_upstream_add(struct pim_instance *pim,
struct prefix_sg *sg,
struct interface *incoming, int flags,
- const char *name)
+ const char *name,
+ struct pim_ifchannel *ch)
{
struct pim_upstream *up = NULL;
int found = 0;
pim_upstream_ref(up, flags, name);
found = 1;
} else {
- up = pim_upstream_new(pim, sg, incoming, flags);
+ up = pim_upstream_new(pim, sg, incoming, flags, ch);
}
if (PIM_DEBUG_TRACE) {
struct pim_upstream *pim_upstream_add(struct pim_instance *pim,
struct prefix_sg *sg,
struct interface *ifp, int flags,
- const char *name);
+ const char *name,
+ struct pim_ifchannel *ch);
void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name);
struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
struct pim_upstream *up,