Exemple #1
0
/*
 * Update the register vif in the multicast routing daemon and the
 * kernel because the interface used initially to get its local address
 * is DOWN. register_vifi is the index to the Register vif which needs
 * to be updated. As a result the Register vif has a new uv_lcl_addr and
 * is UP (virtually :))
 */
int
update_reg_vif( mifi_t register_vifi )
{
    register struct uvif *v;
    register mifi_t vifi;

    /* Find the first useable vif with solid physical background */
    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
	if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN | MIFF_REGISTER))
	    continue;
        /* Found. Stop the bogus Register vif first */
	stop_vif(register_vifi);
	add_phaddr(v, &uvifs[vifi].uv_linklocal->pa_addr,
		   &uvifs[vifi].uv_linklocal->pa_subnetmask,
		   &uvifs[vifi].uv_linklocal->pa_prefix); 
	start_vif(register_vifi);
	IF_DEBUG(DEBUG_PIM_REGISTER | DEBUG_IF)
	    log_msg(LOG_NOTICE, 0, "%s has come up; vif #%u now in service",
		uvifs[register_vifi].uv_name, register_vifi);
	return 0;
    }
    vifs_down = TRUE;
    log_msg(LOG_WARNING, 0, "Cannot start Register vif: %s",
	uvifs[vifi].uv_name);
    return(-1);
}
Exemple #2
0
void start_all_vifs()
{
	mifi_t vifi;
	struct uvif *v;
	u_int action;


	/* Start first the NON-REGISTER vifs */
	for (action = 0; ; action = MIFF_REGISTER) {
		for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
			/*
			 * If starting non-registers but the vif is a register
			 * or if starting registers, but the interface is not
			 * a register, then just continue.
			 */
			if ((v->uv_flags & MIFF_REGISTER) ^ action)
				continue;

			if (v->uv_flags & (VIFF_DISABLED | VIFF_DOWN)) {
				IF_DEBUG(DEBUG_IF)
					log_msg(LOG_DEBUG, 0,
					    "%s is %s; vif #%u out of service",
					    v->uv_name,
					    v->uv_flags & VIFF_DISABLED ? "DISABLED" : "DOWN",
					    vifi); 
				continue;
			}
			start_vif(vifi);
		}
		if (action == MIFF_REGISTER)
			break;
	}
}
Exemple #3
0
/*
 * See if any interfaces have changed from up state to down, or vice versa,
 * including any non-multicast-capable interfaces that are in use as local
 * tunnel end-points.  Ignore interfaces that have been administratively
 * disabled.
 */
void check_vif_state(void)
{
    vifi_t vifi;
    struct uvif *v;
    struct ifreq ifr;
    static int checking_vifs = 0;

    /*
     * If we get an error while checking, (e.g. two interfaces go down
     * at once, and we decide to send a prune out one of the failed ones)
     * then don't go into an infinite loop!
     */
    if (checking_vifs)
	return;

    vifs_down = FALSE;
    checking_vifs = 1;
    for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {

	if (v->uv_flags & VIFF_DISABLED)
	    continue;

	memcpy(ifr.ifr_name, v->uv_name, sizeof(ifr.ifr_name));
	if (ioctl(udp_socket, SIOCGIFFLAGS, (char *)&ifr) < 0)
	    logit(LOG_ERR, errno, "Failed ioctl SIOCGIFFLAGS for %s", ifr.ifr_name);

	if (v->uv_flags & VIFF_DOWN) {
	    if (ifr.ifr_flags & IFF_UP) {
		logit(LOG_NOTICE, 0, "%s has come up; vif #%u now in service",
		      v->uv_name, vifi);
		v->uv_flags &= ~VIFF_DOWN;
		start_vif(vifi);
	    } else {
		vifs_down = TRUE;
	    }
	} else {
	    if (!(ifr.ifr_flags & IFF_UP)) {
		logit(LOG_NOTICE, 0, "%s has gone down; vif #%u taken out of service",
		    v->uv_name, vifi);
		stop_vif(vifi);
		v->uv_flags |= VIFF_DOWN;
		vifs_down = TRUE;
	    }
	}
    }

    checking_vifs = 0;
}