tap(4) should go UP if opened
Frank Behrens
frank at pinky.sax.de
Fri Mar 9 13:26:52 UTC 2007
Bruce, thanks for your answer!
Bruce M. Simpson <bms at FreeBSD.org> wrote on 9 Mar 2007 12:30:
> Frank Behrens wrote:
> > How does tun(4) handle this? tun(4) is also set to down, when closed. It is not set to up, when
> > ist is opened, but when an address is assigned by the user process. This is fine, because it
> > needs always an ip address. tap(4) as layer 2 tunnel device does not need an ip address, so
> > setting it up on open is IMHO the best solution.
> >
> This isn't consistent with the other software cloneable interfaces which
> emulate certain layer 2 semantics, e.g. bridge, trunk, vlan; see below.
May be, but we have for tap(4) the possibility to attach a non root user process.
> I recently committed Landon Fuller's code which makes tap and tun
> cloneable interfaces which may then be created via 'ifconfig tap0 create'.
I appreciate that. :-) It was the reason to build a new 6.2 kernel and to try to run the attached
process not as root.
> Automatically setting the interface to IFF_UP is not consistent with the
> semantics for other network interfaces; it requires specific privileges
> (usually super-user or PRIV_NET_SETIFFLAGS in -CURRENT) to do.
My idea is to set it to IFF_UP when the process _opens_ the interface. It can happen only if
1. the process has root provileges OR
2. net.link.tap.user_open=1 AND special rights are set on /dev/tapx
> A more involved patch is needed to do this right for all cases -- we
> should not do this by default.
But when it is useful to open a tap device by a non root process, when the tap is not IFF_UP?
May be my patch had not enough context to see immediately, where it fits into the game. To
make it easier for the reviewers I show the complete function:
/*
* tapopen
*
* to open tunnel. must be superuser
*/
static int
tapopen(struct cdev *dev, int flag, int mode, struct thread *td)
{
struct tap_softc *tp = NULL;
struct ifnet *ifp = NULL;
int error, s;
if (tapuopen == 0) {
error = suser(td);
if (error != 0)
return (error);
}
if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT)
return (ENXIO);
tp = dev->si_drv1;
mtx_lock(&tp->tap_mtx);
if (tp->tap_flags & TAP_OPEN) {
mtx_unlock(&tp->tap_mtx);
return (EBUSY);
}
bcopy(IFP2ENADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr));
tp->tap_pid = td->td_proc->p_pid;
tp->tap_flags |= TAP_OPEN;
ifp = tp->tap_ifp;
mtx_unlock(&tp->tap_mtx);
s = splimp();
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ifp->if_flags |= IFF_UP; /* ------- new line ------ */
splx(s);
TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, minor(dev));
return (0);
} /* tapopen */
Regards,
Frank
--
Frank Behrens, Osterwieck, Germany
PGP-key 0x5B7C47ED on public servers available.
More information about the freebsd-net
mailing list