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