FreeBSD/sys/netinet6/ip6_mroute.c
/*
 * Add a mif to the mif table
 */
Add a mif to the mif table
Add a mif to the mif table
static int
add_m6if(struct mif6ctl *mifcp)
{
	struct mif6 *mifp;
	struct ifnet *ifp;
	int error;
	MIF6_LOCK();
	if (mifcp->mif6c_mifi >= MAXMIFS) {
		MIF6_UNLOCK();
		return (EINVAL);
	}
	mifp = mif6table + mifcp->mif6c_mifi;
	if (mifp->m6_ifp != NULL) {
		MIF6_UNLOCK();
		return (EADDRINUSE); 
	}
	if (mifcp->mif6c_pifi == 0 || mifcp->mif6c_pifi > V_if_index) {
		MIF6_UNLOCK();
		return (ENXIO);
	}
	ifp = ifnet_byindex(mifcp->mif6c_pifi);
	if (mifcp->mif6c_flags & MIFF_REGISTER) {
		if (reg_mif_num == (mifi_t)-1) {
			ifp = if_alloc(IFT_OTHER);
			if_initname(ifp, "register_mif", 0);
			ifp->if_flags |= IFF_LOOPBACK;
			if_attach(ifp);
			multicast_register_if6 = ifp;
			reg_mif_num = mifcp->mif6c_mifi;
			mifcp->mif6c_pifi = ifp->if_index;
		} else {
			ifp = multicast_register_if6;
		}
	} else {
		if ((ifp->if_flags & IFF_MULTICAST) == 0) {
			MIF6_UNLOCK();
			return (EOPNOTSUPP);
		}
		error = if_allmulti(ifp, 1);
		if (error) {
			MIF6_UNLOCK();
			return (error);
		}
	}
	mifp->m6_flags     = mifcp->mif6c_flags;
	mifp->m6_ifp       = ifp;
	mifp->m6_pkt_in    = 0;
	mifp->m6_pkt_out   = 0;
	mifp->m6_bytes_in  = 0;
	mifp->m6_bytes_out = 0;
	if (nummifs <= mifcp->mif6c_mifi)
		nummifs = mifcp->mif6c_mifi + 1;
	MIF6_UNLOCK();
	MRT6_DLOG(DEBUG_ANY, "mif #%d, phyint %s", mifcp->mif6c_mifi,
	    if_name(ifp));
	return (0);
}
static int add_m6if ( struct mif6ctl * mifcp ) { struct mif6 * mifp ; struct ifnet * ifp ; int error ; MIF6_LOCK ( ) ; if ( mifcp -> mif6c_mifi >= MAXMIFS ) { MIF6_UNLOCK ( ) ; return ( EINVAL ) ; } mifp = mif6table + mifcp -> mif6c_mifi ; if ( mifp -> m6_ifp != NULL ) { MIF6_UNLOCK ( ) ; return ( EADDRINUSE ) ; } if ( mifcp -> mif6c_pifi == 0 || mifcp -> mif6c_pifi > V_if_index ) { MIF6_UNLOCK ( ) ; return ( ENXIO ) ; } ifp = ifnet_byindex ( mifcp -> mif6c_pifi ) ; if ( mifcp -> mif6c_flags & MIFF_REGISTER ) { if ( reg_mif_num == ( mifi_t ) - 1 ) { ifp = if_alloc ( IFT_OTHER ) ; if_initname ( ifp , " " , 0 ) ; ifp -> if_flags |= IFF_LOOPBACK ; if_attach ( ifp ) ; multicast_register_if6 = ifp ; reg_mif_num = mifcp -> mif6c_mifi ; mifcp -> mif6c_pifi = ifp -> if_index ; } else { ifp = multicast_register_if6 ; } } else { if ( ( ifp -> if_flags & IFF_MULTICAST ) == 0 ) { MIF6_UNLOCK ( ) ; return ( EOPNOTSUPP ) ; } error = if_allmulti ( ifp , 1 ) ; if ( error ) { MIF6_UNLOCK ( ) ; return ( error ) ; } } mifp -> m6_flags = mifcp -> mif6c_flags ; mifp -> m6_ifp = ifp ; mifp -> m6_pkt_in = 0 ; mifp -> m6_pkt_out = 0 ; mifp -> m6_bytes_in = 0 ; mifp -> m6_bytes_out = 0 ; if ( nummifs <= mifcp -> mif6c_mifi ) nummifs = mifcp -> mif6c_mifi + 1 ; MIF6_UNLOCK ( ) ; MRT6_DLOG ( DEBUG_ANY , " " , mifcp -> mif6c_mifi , if_name ( ifp ) ) ; return ( 0 ) ; }
Add a mif to the mif table
Add a mif to the mif table
/* XXX: is it appropriate? */ /*
			 * it is impossible to guess the ifindex of the
			 * register interface.  So mif6c_pifi is automatically
			 * calculated.
			 */ /* Make sure the interface supports multicast */ /* initialize per mif pkt counters */ /* Adjust nummifs up if the mifi is higher than nummifs */