Esempio n. 1
0
void pim_vxlan_del_term_dev(struct pim_instance *pim)
{
	struct interface *ifp = pim->vxlan.term_if;
	struct pim_interface *pim_ifp;

	if (PIM_DEBUG_VXLAN)
		zlog_debug("vxlan term oif changed from %s to -", ifp->name);

	pim->vxlan.term_if = NULL;

	if (pim->vxlan.sg_hash)
		hash_iterate(pim->vxlan.sg_hash,
				pim_vxlan_term_mr_oif_update, NULL);

	pim_ifp = (struct pim_interface *)ifp->info;
	if (pim_ifp) {
		PIM_IF_DONT_PIM(pim_ifp->options);
		if (!PIM_IF_TEST_IGMP(pim_ifp->options))
			pim_if_delete(ifp);
	}

}
struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  zassert(!ifp->info);

  pim_ifp = XMALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
  if (!pim_ifp) {
    zlog_err("PIM XMALLOC(%zu) failure", sizeof(*pim_ifp));
    return 0;
  }

  pim_ifp->options                           = 0;
  pim_ifp->mroute_vif_index                  = -1;

  pim_ifp->igmp_default_robustness_variable           = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
  pim_ifp->igmp_default_query_interval                = IGMP_GENERAL_QUERY_INTERVAL;
  pim_ifp->igmp_query_max_response_time_dsec          = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;
  pim_ifp->igmp_specific_query_max_response_time_dsec = IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;

  /*
    RFC 3376: 8.3. Query Response Interval
    The number of seconds represented by the [Query Response Interval]
    must be less than the [Query Interval].
   */
  zassert(pim_ifp->igmp_query_max_response_time_dsec < pim_ifp->igmp_default_query_interval);

  if (pim)
    PIM_IF_DO_PIM(pim_ifp->options);
  if (igmp)
    PIM_IF_DO_IGMP(pim_ifp->options);

#if 0
  /* FIXME: Should join? */
  PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
#endif

  pim_ifp->igmp_join_list = 0;
  pim_ifp->igmp_socket_list = 0;
  pim_ifp->pim_neighbor_list = 0;
  pim_ifp->pim_ifchannel_list = 0;

  /* list of struct igmp_sock */
  pim_ifp->igmp_socket_list = list_new();
  if (!pim_ifp->igmp_socket_list) {
    zlog_err("%s %s: failure: igmp_socket_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->igmp_socket_list->del = (void (*)(void *)) igmp_sock_free;

  /* list of struct pim_neighbor */
  pim_ifp->pim_neighbor_list = list_new();
  if (!pim_ifp->pim_neighbor_list) {
    zlog_err("%s %s: failure: pim_neighbor_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->pim_neighbor_list->del = (void (*)(void *)) pim_neighbor_free;

  /* list of struct pim_ifchannel */
  pim_ifp->pim_ifchannel_list = list_new();
  if (!pim_ifp->pim_ifchannel_list) {
    zlog_err("%s %s: failure: pim_ifchannel_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->pim_ifchannel_list->del = (void (*)(void *)) pim_ifchannel_free;

  ifp->info = pim_ifp;

  pim_sock_reset(ifp);

  zassert(PIM_IF_TEST_PIM(pim_ifp->options) || PIM_IF_TEST_IGMP(pim_ifp->options));

  if (PIM_MROUTE_IS_ENABLED) {
    pim_if_add_vif(ifp);
  }

  return pim_ifp;
}
void pim_if_addr_add(struct connected *ifc)
{
  struct pim_interface *pim_ifp;
  struct interface *ifp;
  struct in_addr ifaddr;

  zassert(ifc);

  ifp = ifc->ifp;
  zassert(ifp);
  pim_ifp = ifp->info;
  if (!pim_ifp)
    return;

  if (!if_is_operative(ifp))
    return;

  /* if (PIM_DEBUG_ZEBRA) */ {
    char buf[BUFSIZ];
    prefix2str(ifc->address, buf, BUFSIZ);
    zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
	       __PRETTY_FUNCTION__,
	       ifp->name, ifp->ifindex, buf,
	       CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?
	       "secondary" : "primary");
  }

  ifaddr = ifc->address->u.prefix4;

  detect_address_change(ifp, 0, __PRETTY_FUNCTION__);

  if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
    struct igmp_sock *igmp;

    /* lookup IGMP socket */
    igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
				       ifaddr);
    if (!igmp) {
      /* if addr new, add IGMP socket */
      pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
    }
  } /* igmp */

  if (PIM_IF_TEST_PIM(pim_ifp->options)) {

    /* Interface has a valid primary address ? */
    if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {

      /* Interface has a valid socket ? */
      if (pim_ifp->pim_sock_fd < 0) {
	if (pim_sock_add(ifp)) {
	  zlog_warn("Failure creating PIM socket for interface %s",
		    ifp->name);
	}
      }

    }
  } /* pim */

  if (PIM_MROUTE_IS_ENABLED) {
    /*
      PIM or IGMP is enabled on interface, and there is at least one
      address assigned, then try to create a vif_index.
    */
    if (pim_ifp->mroute_vif_index < 0) {
      pim_if_add_vif(ifp);
    }
  }
}
Esempio n. 4
0
int pim_interface_config_write(struct vty *vty)
{
  int writes = 0;
  struct listnode *node;
  struct interface *ifp;

  for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {

    /* IF name */
    vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE);
    ++writes;

    if (ifp->info) {
      struct pim_interface *pim_ifp = ifp->info;

      /* IF ip pim ssm */
      if (PIM_IF_TEST_PIM(pim_ifp->options)) {
	vty_out(vty, " ip pim ssm%s", VTY_NEWLINE);
	++writes;
      }

      /* IF ip pim drpriority */
      if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
	vty_out(vty, " ip pim drpriority %d%s", pim_ifp->pim_dr_priority,
		VTY_NEWLINE);
	++writes;
      }

      /* IF ip pim hello */
      if (pim_ifp->pim_hello_period != PIM_DEFAULT_HELLO_PERIOD) {
	vty_out(vty, " ip pim hello %d", pim_ifp->pim_hello_period);
	if (pim_ifp->pim_default_holdtime != -1)
	  vty_out(vty, " %d", pim_ifp->pim_default_holdtime);
	vty_out(vty, "%s", VTY_NEWLINE);
      }

      /* IF ip igmp */
      if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
	vty_out(vty, " ip igmp%s", VTY_NEWLINE);
	++writes;
      }

      /* IF ip igmp query-interval */
      if (pim_ifp->igmp_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL)
	{
	  vty_out(vty, " %s %d%s",
		  PIM_CMD_IP_IGMP_QUERY_INTERVAL,
		  pim_ifp->igmp_default_query_interval,
		  VTY_NEWLINE);
	  ++writes;
	}

      /* IF ip igmp query-max-response-time */
      if (pim_ifp->igmp_query_max_response_time_dsec != IGMP_QUERY_MAX_RESPONSE_TIME_DSEC)
	{
	  vty_out(vty, " %s %d%s",
		  PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
		  pim_ifp->igmp_query_max_response_time_dsec,
		  VTY_NEWLINE);
	  ++writes;
	}

      /* IF ip igmp join */
      if (pim_ifp->igmp_join_list) {
	struct listnode *node;
	struct igmp_join *ij;
	for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, node, ij)) {
	  char group_str[100];
	  char source_str[100];
	  pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
	  pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
	  vty_out(vty, " ip igmp join %s %s%s",
		  group_str, source_str,
		  VTY_NEWLINE);
	  ++writes;
	}
      }

	writes += pim_static_write_mroute (vty, ifp);
    }
    vty_out(vty, "!%s", VTY_NEWLINE);
    ++writes;
  }

  return writes;
}