Example #1
0
/*
  igmp_source_forward_stop: stop fowarding, but keep the source
  igmp_source_delete:       stop fowarding, and delete the source
 */
void igmp_source_forward_stop(struct igmp_source *source)
{
  struct igmp_group *group;
  int result;

  if (PIM_DEBUG_IGMP_TRACE) {
    char source_str[100];
    char group_str[100]; 
    pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
    pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
    zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
	       __PRETTY_FUNCTION__,
	       source_str, group_str,
	       source->source_group->group_igmp_sock->fd,
	       source->source_group->group_igmp_sock->interface->name,
	       IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
  }

  /* Prevent IGMP interface from removing multicast route multiple
     times */
  if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
    return;
  }

  group = source->source_group;

  /*
   It appears that in certain circumstances that 
   igmp_source_forward_stop is called when IGMP forwarding
   was not enabled in oif_flags for this outgoing interface.
   Possibly because of multiple calls. When that happens, we
   enter the below if statement and this function returns early
   which in turn triggers the calling function to assert.
   Making the call to del_oif and ignoring the return code 
   fixes the issue without ill effect, similar to 
   pim_forward_stop below.   
  */
  result = del_oif(source->source_channel_oil,
		   group->group_igmp_sock->interface,
		   PIM_OIF_FLAG_PROTO_IGMP);
  if (result) {
    zlog_warn("%s: del_oif() failed with return=%d",
	      __func__, result);
    return;
  }

  /*
    Feed IGMPv3-gathered local membership information into PIM
    per-interface (S,G) state.
   */
  pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
				     source->source_addr, group->group_addr);

  IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
}
Example #2
0
static void pim_vxlan_term_mr_oif_del(struct pim_vxlan_sg *vxlan_sg)
{
	if (!(vxlan_sg->flags & PIM_VXLAN_SGF_OIF_INSTALLED))
		return;

	if (PIM_DEBUG_VXLAN)
		zlog_debug("vxlan SG %s oif %s del",
			vxlan_sg->sg_str, vxlan_sg->term_oif->name);

	vxlan_sg->flags &= ~PIM_VXLAN_SGF_OIF_INSTALLED;
	pim_ifchannel_local_membership_del(vxlan_sg->term_oif, &vxlan_sg->sg);
}