コード例 #1
0
ファイル: if_clone.c プロジェクト: wan721/DragonFlyBSD
/*
 * Create a clone network interface.
 */
int
if_clone_create(char *name, int len, caddr_t params)
{
	struct if_clone *ifc;
	char *dp;
	int wildcard, bytoff, bitoff;
	int unit;
	int err;

	ifc = if_clone_lookup(name, &unit);
	if (ifc == NULL)
		return (EINVAL);

	ifnet_lock();
	if (ifunit(name) != NULL) {
		ifnet_unlock();
		return (EEXIST);
	}
	ifnet_unlock();

	bytoff = bitoff = 0;
	wildcard = (unit < 0);
	/*
	 * Find a free unit if none was given.
	 */
	if (wildcard) {
		while (bytoff < ifc->ifc_bmlen &&
		    ifc->ifc_units[bytoff] == 0xff)
			bytoff++;
		if (bytoff >= ifc->ifc_bmlen)
			return (ENOSPC);
		while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
			bitoff++;
		unit = (bytoff << 3) + bitoff;
	}

	if (unit > ifc->ifc_maxunit)
		return (ENXIO);

	err = (*ifc->ifc_create)(ifc, unit, params);
	if (err != 0)
		return (err);

	if (!wildcard) {
		bytoff = unit >> 3;
		bitoff = unit - (bytoff << 3);
	}
コード例 #2
0
ファイル: if_pair.c プロジェクト: darksoul42/bitrig
int
pairioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
	struct pair_softc	*sc = (struct pair_softc *)ifp->if_softc;
	struct ifreq		*ifr = (struct ifreq *)data;
	struct if_clone		*ifc;
	struct pair_softc	*pairedsc = ifp->if_softc;
	struct ifnet		*oldifp = NULL, *newifp = NULL;
	int			 error = 0, unit;

	switch (cmd) {
	case SIOCSIFADDR:
		ifp->if_flags |= IFF_UP;
		/* FALLTHROUGH */

	case SIOCSIFFLAGS:
		if (ifp->if_flags & IFF_UP)
			ifp->if_flags |= IFF_RUNNING;
		else
			ifp->if_flags &= ~IFF_RUNNING;
		break;

	case SIOCADDMULTI:
	case SIOCDELMULTI:
		break;

	case SIOCGIFMEDIA:
	case SIOCSIFMEDIA:
		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
		break;

	case SIOCSIFPAIR:
		if (sc->sc_pairedif == ifr->ifr_index)
			break;

		/* Cannot link to myself */
		if (ifr->ifr_index == ifp->if_index) {
			error = EINVAL;
			break;
		}

		oldifp = if_get(sc->sc_pairedif);
		newifp = if_get(ifr->ifr_index);

		if (newifp != NULL) {
			pairedsc = newifp->if_softc;

			if (pairedsc->sc_pairedif != 0) {
				error = EBUSY;
				break;
			}

			/* Only allow pair(4) interfaces for the pair */
			if ((ifc = if_clone_lookup(newifp->if_xname,
			    &unit)) == NULL || strcmp("pair",
			    ifc->ifc_name) != 0) {
				error = ENODEV;
				break;
			}

			pairedsc->sc_pairedif = ifp->if_index;
			sc->sc_pairedif = ifr->ifr_index;
		} else
			sc->sc_pairedif = 0;

		if (oldifp != NULL) {
			pairedsc = oldifp->if_softc;
			pairedsc->sc_pairedif = 0;
		}
		break;

	case SIOCGIFPAIR:
		ifr->ifr_index = sc->sc_pairedif;
		break;

	default:
		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
	}

	if (newifp != NULL || oldifp != NULL)
		pair_link_state(ifp);
	if (oldifp != NULL) {
		pair_link_state(oldifp);
		if_put(oldifp);
	}
	if (newifp != NULL) {
		pair_link_state(newifp);
		if_put(newifp);
	}

	return (error);
}