Esempio n. 1
0
void pim_vxlan_add_term_dev(struct pim_instance *pim,
		struct interface *ifp)
{
	struct pim_interface *pim_ifp;

	if (pim->vxlan.term_if == ifp)
		return;

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

	/* enable pim on the term ifp */
	pim_ifp = (struct pim_interface *)ifp->info;
	if (pim_ifp) {
		PIM_IF_DO_PIM(pim_ifp->options);
	} else {
		pim_ifp = pim_if_new(ifp, false /*igmp*/, true /*pim*/,
				false /*pimreg*/, true /*vxlan_term*/);
		/* ensure that pimreg existss before using the newly created
		 * vxlan termination device
		 */
		pim_if_create_pimreg(pim);
	}

	pim->vxlan.term_if = ifp;

	if (pim->vxlan.sg_hash)
		hash_iterate(pim_ifp->pim->vxlan.sg_hash,
				pim_vxlan_term_mr_oif_update, 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;
}