예제 #1
0
파일: pim_vxlan.c 프로젝트: ton31337/frr
static void pim_vxlan_term_mr_oif_add(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 term-oif %s add",
			vxlan_sg->sg_str, vxlan_sg->term_oif->name);

	if (pim_ifchannel_local_membership_add(vxlan_sg->term_oif,
				&vxlan_sg->sg)) {
		vxlan_sg->flags |= PIM_VXLAN_SGF_OIF_INSTALLED;
	} else {
		zlog_warn("vxlan SG %s term-oif %s add failed",
			vxlan_sg->sg_str, vxlan_sg->term_oif->name);
	}
}
예제 #2
0
void igmp_source_forward_start(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 installing multicast route multiple
     times */
  if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) {
    return;
  }

  group = source->source_group;

  if (!source->source_channel_oil) {
    struct pim_interface *pim_oif;
    int input_iface_vif_index = fib_lookup_if_vif_index(source->source_addr);
    if (input_iface_vif_index < 1) {
      char source_str[100];
      pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
      zlog_warn("%s %s: could not find input interface for source %s",
		__FILE__, __PRETTY_FUNCTION__,
		source_str);
      return;
    }

    /*
      Protect IGMP against adding looped MFC entries created by both
      source and receiver attached to the same interface. See TODO
      T22.
    */
    pim_oif = source->source_group->group_igmp_sock->interface->info;
    if (!pim_oif) {
      zlog_warn("%s: multicast not enabled on oif=%s ?",
		__PRETTY_FUNCTION__,
		source->source_group->group_igmp_sock->interface->name);
      return;
    }
    if (pim_oif->mroute_vif_index < 1) {
      zlog_warn("%s %s: oif=%s vif_index=%d < 1",
		__FILE__, __PRETTY_FUNCTION__,
		source->source_group->group_igmp_sock->interface->name,
		pim_oif->mroute_vif_index);
      return;
    }
    if (input_iface_vif_index == pim_oif->mroute_vif_index) {
      /* ignore request for looped MFC entry */
      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: ignoring request for looped MFC entry (S,G)=(%s,%s): igmp_sock=%d oif=%s vif_index=%d",
		   __PRETTY_FUNCTION__,
		   source_str, group_str,
		   source->source_group->group_igmp_sock->fd,
		   source->source_group->group_igmp_sock->interface->name,
		   input_iface_vif_index);
      }
      return;
    }

    source->source_channel_oil = pim_channel_oil_add(group->group_addr,
						     source->source_addr,
						     input_iface_vif_index);
    if (!source->source_channel_oil) {
      char group_str[100]; 
      char source_str[100];
      pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
      pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
      zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
		__FILE__, __PRETTY_FUNCTION__,
		source_str, group_str);
      return;
    }
  }

  result = add_oif(source->source_channel_oil,
		   group->group_igmp_sock->interface,
		   PIM_OIF_FLAG_PROTO_IGMP);
  if (result) {
    zlog_warn("%s: add_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_add(group->group_igmp_sock->interface,
				     source->source_addr, group->group_addr);

  IGMP_SOURCE_DO_FORWARDING(source->source_flags);
}