diff options
author | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2015-12-05 16:09:10 +0000 |
---|---|---|
committer | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2015-12-05 16:09:10 +0000 |
commit | 56182f399f9a43361b1273373d81fa00c6bcb7d7 (patch) | |
tree | 2874c40aa64b5a6a02acc27c27ba4cfb956a3c6f /sys | |
parent | 4a8ea260bea6afd2af9e739d9aa49ac00ed16510 (diff) |
Make pppx pass packets with npppd through the device. This makes pppx work
without pipex.enable=1. Also fix tun(4) not to pass the packets to pipex
when pipex.enable=0.
"go for it" dlg
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_pppx.c | 107 | ||||
-rw-r--r-- | sys/net/if_tun.c | 6 | ||||
-rw-r--r-- | sys/net/pipex.h | 6 |
3 files changed, 84 insertions, 35 deletions
diff --git a/sys/net/if_pppx.c b/sys/net/if_pppx.c index 9418809f7e4..7608e870cef 100644 --- a/sys/net/if_pppx.c +++ b/sys/net/if_pppx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pppx.c,v 1.47 2015/12/03 17:03:33 bluhm Exp $ */ +/* $OpenBSD: if_pppx.c,v 1.48 2015/12/05 16:09:09 yasuoka Exp $ */ /* * Copyright (c) 2010 Claudio Jeker <claudio@openbsd.org> @@ -149,6 +149,7 @@ struct pppx_if { int pxi_unit; struct ifnet pxi_if; + struct pppx_dev *pxi_dev; struct pipex_session pxi_session; struct pipex_iface_context pxi_ifcontext; }; @@ -306,14 +307,20 @@ pppxread(dev_t dev, struct uio *uio, int ioflag) int pppxwrite(dev_t dev, struct uio *uio, int ioflag) { -/* struct pppx_dev *pxd = pppx_dev2pxd(dev); */ + struct pppx_dev *pxd = pppx_dev2pxd(dev); struct pppx_hdr *th; + struct pppx_if *pxi; + uint32_t proto; struct mbuf *top, **mp, *m; struct niqueue *ifq; int tlen, mlen; int error = 0; +#if NBPFILTER > 0 + int s; +#endif - if (uio->uio_resid < sizeof(*th) || uio->uio_resid > MCLBYTES) + if (uio->uio_resid < sizeof(*th) + sizeof(uint32_t) || + uio->uio_resid > MCLBYTES) return (EMSGSIZE); tlen = uio->uio_resid; @@ -365,11 +372,28 @@ pppxwrite(dev_t dev, struct uio *uio, int ioflag) top->m_pkthdr.len = tlen; - /* strip the tunnel header */ + /* Find the interface */ th = mtod(top, struct pppx_hdr *); m_adj(top, sizeof(struct pppx_hdr)); + pxi = pppx_if_find(pxd, th->pppx_id, th->pppx_proto); + if (pxi == NULL) { + m_freem(top); + return (EINVAL); + } + top->m_pkthdr.ph_ifidx = pxi->pxi_if.if_index; - switch (ntohl(th->pppx_proto)) { +#if NBPFILTER > 0 + if (pxi->pxi_if.if_bpf) { + s = splnet(); + bpf_mtap(pxi->pxi_if.if_bpf, top, BPF_DIRECTION_IN); + splx(s); + } +#endif + /* strip the tunnel header */ + proto = ntohl(*(uint32_t *)(th + 1)); + m_adj(top, sizeof(uint32_t)); + + switch (proto) { case AF_INET: ifq = &ipintrq; break; @@ -800,6 +824,7 @@ pppx_add_session(struct pppx_dev *pxd, struct pipex_session_req *req) pxi->pxi_unit = unit; pxi->pxi_key.pxik_session_id = req->pr_session_id; pxi->pxi_key.pxik_protocol = req->pr_protocol; + pxi->pxi_dev = pxd; /* this is safe without splnet since we're not modifying it */ if (RB_FIND(pppx_ifs, &pppx_ifs, pxi) != NULL) { @@ -986,21 +1011,6 @@ pppx_if_start(struct ifnet *ifp) proto = *mtod(m, int *); m_adj(m, sizeof(proto)); -#if NBPFILTER > 0 - if (ifp->if_bpf) { - switch (proto) { - case PPP_IP: - bpf_mtap_af(ifp->if_bpf, AF_INET, m, - BPF_DIRECTION_OUT); - break; - case PPP_IPV6: - bpf_mtap_af(ifp->if_bpf, AF_INET6, m, - BPF_DIRECTION_OUT); - break; - } - } -#endif - ifp->if_obytes += m->m_pkthdr.len; ifp->if_opackets++; @@ -1012,8 +1022,13 @@ int pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { + struct pppx_if *pxi = (struct pppx_if *)ifp->if_softc; + struct pppx_hdr *th; int error = 0; int proto; +#if NBPFILTER > 0 + int s; +#endif if (!ISSET(ifp->if_flags, IFF_UP)) { m_freem(m); @@ -1021,15 +1036,25 @@ pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, goto out; } - switch (dst->sa_family) { - case AF_INET: - proto = PPP_IP; - break; - default: - m_freem(m); - error = EPFNOSUPPORT; - goto out; +#if NBPFILTER > 0 + if (ifp->if_bpf) { + s = splnet(); + bpf_mtap_af(ifp->if_bpf, dst->sa_family, m, BPF_DIRECTION_OUT); + splx(s); } +#endif + if (pipex_enable) { + switch (dst->sa_family) { + case AF_INET: + proto = PPP_IP; + break; + default: + m_freem(m); + error = EPFNOSUPPORT; + goto out; + } + } else + proto = htonl(dst->sa_family); M_PREPEND(m, sizeof(int), M_DONTWAIT); if (m == NULL) { @@ -1038,7 +1063,31 @@ pppx_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, } *mtod(m, int *) = proto; - error = if_enqueue(ifp, m); + if (pipex_enable) + error = if_enqueue(ifp, m); + else { + M_PREPEND(m, sizeof(struct pppx_hdr), M_DONTWAIT); + if (m == NULL) { + error = ENOBUFS; + goto out; + } + th = mtod(m, struct pppx_hdr *); + th->pppx_proto = 0; /* not used */ + th->pppx_id = pxi->pxi_session.ppp_id; + rw_enter_read(&pppx_devs_lk); + error = mq_enqueue(&pxi->pxi_dev->pxd_svcq, m); + if (error == 0) { + s = splnet(); + if (pxi->pxi_dev->pxd_waiting) { + wakeup((caddr_t)pxi->pxi_dev); + pxi->pxi_dev->pxd_waiting = 0; + } + splx(s); + selwakeup(&pxi->pxi_dev->pxd_rsel); + } + rw_exit_read(&pppx_devs_lk); + } + out: if (error) ifp->if_oerrors++; diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 10e7271b115..efda8b2cae9 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.163 2015/11/20 12:20:30 mpi Exp $ */ +/* $OpenBSD: if_tun.c,v 1.164 2015/12/05 16:09:09 yasuoka Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -564,8 +564,8 @@ tun_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT); #endif #ifdef PIPEX - if ((m0 = pipex_output(m0, dst->sa_family, sizeof(u_int32_t), - &tp->pipex_iface)) == NULL) { + if (pipex_enable && (m0 = pipex_output(m0, dst->sa_family, + sizeof(u_int32_t), &tp->pipex_iface)) == NULL) { splx(s); return (0); } diff --git a/sys/net/pipex.h b/sys/net/pipex.h index 6ebcc4d927c..3a4ca768ad8 100644 --- a/sys/net/pipex.h +++ b/sys/net/pipex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pipex.h,v 1.19 2014/10/21 10:52:53 yasuoka Exp $ */ +/* $OpenBSD: pipex.h,v 1.20 2015/12/05 16:09:09 yasuoka Exp $ */ /* * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -157,8 +157,8 @@ struct pipex_session_config_req { /* for pppx(4) */ struct pppx_hdr { - u_int32_t pppx_proto; - u_int32_t pppx_id; + u_int32_t pppx_proto; /* write: protocol in PIPEX_PROTO_ */ + u_int32_t pppx_id; /* write: session_id, read: ppp_id */ }; struct pipex_session_descr_req { |