this has reads from tun load the AF out of the data rather than point to it, then has the switch statement compare to the swapped AF values.
ok? Index: if_tun.c =================================================================== RCS file: /cvs/src/sys/net/if_tun.c,v retrieving revision 1.184 diff -u -p -r1.184 if_tun.c --- if_tun.c 3 Feb 2019 23:04:49 -0000 1.184 +++ if_tun.c 4 Feb 2019 00:18:54 -0000 @@ -833,7 +833,7 @@ int tun_dev_write(struct tun_softc *tp, struct uio *uio, int ioflag) { struct ifnet *ifp; - u_int32_t *th; + u_int32_t th; struct mbuf *top, **mp, *m; int error = 0, tlen; size_t mlen; @@ -842,7 +842,7 @@ tun_dev_write(struct tun_softc *tp, stru TUNDEBUG(("%s: tunwrite\n", ifp->if_xname)); if (uio->uio_resid == 0 || uio->uio_resid > ifp->if_mtu + - (tp->tun_flags & TUN_LAYER2 ? ETHER_HDR_LEN : sizeof(*th))) { + (tp->tun_flags & TUN_LAYER2 ? ETHER_HDR_LEN : sizeof(th))) { TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid)); return (EMSGSIZE); } @@ -917,11 +917,11 @@ tun_dev_write(struct tun_softc *tp, stru } #endif - th = mtod(top, u_int32_t *); + th = *mtod(top, u_int32_t *); /* strip the tunnel header */ - top->m_data += sizeof(*th); - top->m_len -= sizeof(*th); - top->m_pkthdr.len -= sizeof(*th); + top->m_data += sizeof(th); + top->m_len -= sizeof(th); + top->m_pkthdr.len -= sizeof(th); top->m_pkthdr.ph_rtableid = ifp->if_rdomain; top->m_pkthdr.ph_ifidx = ifp->if_index; @@ -930,17 +930,17 @@ tun_dev_write(struct tun_softc *tp, stru NET_LOCK(); - switch (ntohl(*th)) { - case AF_INET: + switch (th) { + case htonl(AF_INET): ipv4_input(ifp, top); break; #ifdef INET6 - case AF_INET6: + case htonl(AF_INET6): ipv6_input(ifp, top); break; #endif #ifdef MPLS - case AF_MPLS: + case htonl(AF_MPLS): mpls_input(ifp, top); break; #endif