예제 #1
0
/*
 * Initialize the virtual interfaces, but do not install
 * them in the kernel.  Start routing on all vifs that are
 * not down or disabled.
 */
void init_vifs(void)
{
    vifi_t vifi;
    struct uvif *v;
    int enabled_vifs, enabled_phyints;
    extern char *configfilename;

    numvifs = 0;
    vifs_with_neighbors = 0;
    vifs_down = FALSE;

    /*
     * Configure the vifs based on the interface configuration of the
     * the kernel and the contents of the configuration file.
     * (Open a UDP socket for ioctl use in the config procedures if
     * the kernel can't handle IOCTL's on the IGMP socket.)
     */
#ifdef IOCTL_OK_ON_RAW_SOCKET
    udp_socket = igmp_socket;
#else
    if ((udp_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	logit(LOG_ERR, errno, "UDP socket");
#endif
    logit(LOG_INFO,0,"Getting vifs from kernel interfaces");
    config_vifs_from_kernel();
    logit(LOG_INFO,0,"Getting vifs from %s",configfilename);
    config_vifs_from_file();

    /*
     * Quit if there are fewer than two enabled vifs.
     */
    enabled_vifs    = 0;
    enabled_phyints = 0;
    phys_vif	    = -1;
    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
	if (!(v->uv_flags & VIFF_DISABLED)) {
	    ++enabled_vifs;

	    if (!(v->uv_flags & VIFF_TUNNEL)) {
    	    	if (phys_vif == -1)
    	    	    phys_vif = vifi;

		++enabled_phyints;
	    }
	}
    }

    if (enabled_vifs < 2)
	logit(LOG_ERR, 0, "Cannot forward: %s",
	      enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif");

    if (enabled_phyints == 0)
	logit(LOG_WARNING, 0, "No enabled interfaces, forwarding via tunnels only");

    logit(LOG_INFO, 0, "Installing vifs in mrouted ...");
    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
	if (!(v->uv_flags & VIFF_DISABLED)) {
	    if (!(v->uv_flags & VIFF_DOWN)) {
		if (v->uv_flags & VIFF_TUNNEL)
		    logit(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi,
			  inet_fmt(v->uv_lcl_addr, s1, sizeof(s1)),
			  inet_fmt(v->uv_rmt_addr, s2, sizeof(s2)));
		else
		    logit(LOG_INFO, 0, "vif #%d, phyint %s", vifi,
			  inet_fmt(v->uv_lcl_addr, s1, sizeof(s1)));

		start_vif2(vifi);
	    } else {
		logit(LOG_INFO, 0, "%s is not yet up; vif #%u not in service",
		      v->uv_name, vifi);
	    }
	}
    }
}
예제 #2
0
void init_vifs()
{
	mifi_t vifi;
	struct uvif *v;
	int enabled_vifs;

	numvifs = 0;
	reg_vif_num = NO_VIF;

	/*
	 * Configure the vifs based on the interface configuration of
	 * the kernel and the contents of the configuration file.
	 * (Open a UDP socket for ioctl use in the config procedures if
	 * the kernel can't handle IOCTL's on the MLD socket.)
	 */
#ifdef IOCTL_OK_ON_RAW_SOCKET
	udp_socket = mld6_socket;
#else
	if ((udp_socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
		log_msg(LOG_ERR, errno, "UDP6 socket");
#endif

	/* clean all the interfaces ... */

	for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) {
		memset(v, 0, sizeof(*v));
		v->uv_metric = DEFAULT_METRIC;
		v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT;
#ifdef HAVE_STRLCPY
		strlcpy(v->uv_name, "", IFNAMSIZ);
#elif HAVE_STRNCPY
		strncpy(v->uv_name, "", IFNAMSIZ);
#else
		strcpy(v->uv_name, "");
#endif
		v->uv_local_pref = default_source_preference;
		v->uv_local_metric = default_source_metric;
		v->uv_priority = PIM_DEFAULT_DR_PRIORITY;
		v->uv_mld_version = MLD6_DEFAULT_VERSION;
		v->uv_mld_robustness = MLD6_DEFAULT_ROBUSTNESS_VARIABLE;
		v->uv_mld_query_interval = MLD6_DEFAULT_QUERY_INTERVAL;
		v->uv_mld_query_rsp_interval = MLD6_DEFAULT_QUERY_RESPONSE_INTERVAL;
		v->uv_mld_llqi = MLD6_DEFAULT_LAST_LISTENER_QUERY_INTERVAL;
	}
	IF_DEBUG(DEBUG_IF)
		log_msg(LOG_DEBUG, 0, "Interfaces world initialized...");
	IF_DEBUG(DEBUG_IF)
		log_msg(LOG_DEBUG, 0, "Getting vifs from %s", configfilename);

	/* read config from file */
	if (cfparse(1, 0) != 0)
		log_msg(LOG_ERR, 0, "fatal error in parsing the config file");

	enabled_vifs = 0;
	phys_vif = -1;

	IF_DEBUG(DEBUG_IF)
		log_msg(LOG_DEBUG, 0, "Getting vifs from kernel");
	config_vifs_from_kernel();

	/* IPv6 PIM needs one global unicast address (at least for now) */
	if (max_global_address() == NULL)
		log_msg(LOG_ERR, 0, "There's no global address available");

	for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
		struct phaddr *p;
		if (v->uv_flags & (VIFF_DISABLED | MIFF_REGISTER))
			continue;

		enabled_vifs++;
		if (v->uv_flags & VIFF_DOWN)
			continue;
		if (v->uv_linklocal == NULL)
			log_msg(LOG_ERR, 0,
			    "there is no link-local address on vif %s",
			    v->uv_name);

		/* If this vif has a global address, set its id to phys_vif */
		if (phys_vif != -1)
			continue;
		for (p = v->uv_addrs; p; p = p->pa_next) {
			if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr)) {
				phys_vif = vifi;
				break;
			}
		}
	}
	if (enabled_vifs < 2)
		log_msg(LOG_ERR, 0, "can't forward: %s",
		    enabled_vifs == 0 ? "no enabled vifs" :
		     "only one enabled vif");

	memset(&if_nullset, 0, sizeof(if_nullset));
	k_init_pim(mld6_socket);	
	IF_DEBUG(DEBUG_PIM_DETAIL)
		log_msg(LOG_DEBUG, 0, "Pim kernel initialization done");


	/* Add a dummy virtual interface to support Registers in the kernel. */
 	init_reg_vif();

	start_all_vifs();

}