Download raw body.
neuter tun(4)/tap(4) ioctls that change interface flags
On Wed, Oct 09, 2024 at 03:34:06PM +1000, David Gwynne wrote:
> once upon a time there was just tun(4) and it handled both layer 3 (ipv4
> and ipv6) and ethernet. flipping interface type around at runtime was a
> recipe for disaster, so we've been progressively locking this down
> as time goes by splitting ethernet support out into the tap(4)
> interface. tun(4) is set up as a p2p interface with the right interface
> flags for p2p, and tap(4) is set up as an ethernet interface with the
> right interface flags for ethernet.
>
> we locked down the ability for userland to reconfigure the interface
> type of tun/tap interfaces at runtime, but we still allow the flags to
> change. this diff removes that ability. it still allows the TUNSIFMODE
> and TUNSIFINFO ioctls, but you have to specify the interface flags
> appropriate for the interface type.
>
> it also removes the ability to set IFF_UP using these ioctls.
>
> nothing in base uses them, so if there's going to be any fallout it's
> from ports. eg, openvpn does TUNGIFINFO, sets IFF_MULTICAST, and then
> TUNSIFINFO to apply it. because IFF_MULTICAST is set for both tun and
> tap, this is just a waste of cpu time more than anything else, but is
> otherwise handled by this diff. other software may be cleverer^Wdumber
> though.
>
> thoughts? ok?
I'm partially or even fully responsible for this. I'm all for it to go
away.
Now this probably needs to go in soon so we can shake out the
cleverer^Wdumber ports. Since that will take some time.
OK claudio@
> Index: if_tun.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_tun.c,v
> diff -u -p -r1.240 if_tun.c
> --- if_tun.c 23 Dec 2023 10:52:54 -0000 1.240
> +++ if_tun.c 8 Oct 2024 12:09:25 -0000
> @@ -101,8 +101,8 @@ int tundebug = TUN_DEBUG;
> #define TUNDEBUG(a) /* (tundebug? printf a : 0) */
> #endif
>
> -/* Only these IFF flags are changeable by TUNSIFINFO */
> -#define TUN_IFF_FLAGS (IFF_UP|IFF_POINTOPOINT|IFF_MULTICAST|IFF_BROADCAST)
> +/* Pretend that these IFF flags are changeable by TUNSIFINFO */
> +#define TUN_IFF_FLAGS (IFF_POINTOPOINT|IFF_MULTICAST|IFF_BROADCAST)
>
> void tunattach(int);
>
> @@ -709,17 +709,18 @@ tun_dev_ioctl(dev_t dev, u_long cmd, voi
> error = EINVAL;
> break;
> }
> + if (tunp->flags != (sc->sc_if.if_flags & TUN_IFF_FLAGS)) {
> + error = EINVAL;
> + break;
> + }
> sc->sc_if.if_mtu = tunp->mtu;
> - sc->sc_if.if_flags =
> - (tunp->flags & TUN_IFF_FLAGS) |
> - (sc->sc_if.if_flags & ~TUN_IFF_FLAGS);
> sc->sc_if.if_baudrate = tunp->baudrate;
> break;
> case TUNGIFINFO:
> tunp = (struct tuninfo *)data;
> tunp->mtu = sc->sc_if.if_mtu;
> tunp->type = sc->sc_if.if_type;
> - tunp->flags = sc->sc_if.if_flags;
> + tunp->flags = sc->sc_if.if_flags & TUN_IFF_FLAGS;
> tunp->baudrate = sc->sc_if.if_baudrate;
> break;
> #ifdef TUN_DEBUG
> @@ -731,13 +732,7 @@ tun_dev_ioctl(dev_t dev, u_long cmd, voi
> break;
> #endif
> case TUNSIFMODE:
> - switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
> - case IFF_POINTOPOINT:
> - case IFF_BROADCAST:
> - sc->sc_if.if_flags &= ~TUN_IFF_FLAGS;
> - sc->sc_if.if_flags |= *(int *)data & TUN_IFF_FLAGS;
> - break;
> - default:
> + if (*(int *)data != (sc->sc_if.if_flags & TUN_IFF_FLAGS)) {
> error = EINVAL;
> break;
> }
>
--
:wq Claudio
neuter tun(4)/tap(4) ioctls that change interface flags