Date: Tue, 7 Jun 2005 22:19:29 +1200 From: Matthew Luckie <mjl@luckie.org.nz> To: freebsd-net@freebsd.org Subject: Re: bpf writes on tun device Message-ID: <20050607101927.GA99034@lycra.luckie.org.nz> In-Reply-To: <20050606204008.GA91353@lycra.luckie.org.nz> References: <4295A6CA.8080409@luckie.org.nz> <20050606081637.GA73886@lycra.luckie.org.nz> <20050606120851.GD734@empiric.icir.org> <20050606204008.GA91353@lycra.luckie.org.nz>
next in thread | previous in thread | raw e-mail | index | archive | help
> is there a good reason why _all_ DLT_NULL bpf devices could not simply > have writes supported? the user space application would pass the > address family in the first 4 bytes of the packet; this is currently > done anyway for if_disc, if_loop, if_tun, if_faith, and ng_iface. > ip_carp could get bpf writes for free with AF_UNSPEC added to the > carp_looutput() switch statement. http://www.wand.net.nz/~mjl12/freebsd-current-dlt_null-write.diff I spent some time going through all drivers in -current that export DLT_NULL bpf devices that may support writing raw packets using BPF. I did this by running egrep -r 'bpfattach.+DLT_NULL' * which corresponded to the following drivers: sys/net/if_disc.c: bpfattach(ifp, DLT_NULL, sizeof(u_int)); sys/net/if_faith.c: bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); sys/net/if_gif.c: bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int)); sys/net/if_gre.c: bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t)); sys/net/if_loop.c: bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); sys/net/if_stf.c: bpfattach(ifp, DLT_NULL, sizeof(u_int)); sys/net/if_tun.c: bpfattach(ifp, DLT_NULL, sizeof(u_int)); sys/netgraph/ng_iface.c: bpfattach(ifp, DLT_NULL, sizeof(u_int)); sys/netgraph/ng_sppp.c: bpfattach (&pp->pp_if, DLT_NULL, sizeof(u_int)); sys/dev/iicbus/if_ic.c: bpfattach(ifp, DLT_NULL, ICHDRLEN); sys/dev/ppbus/if_plip.c: bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); sys/i4b/driver/i4b_ipr.c: bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); sys/netinet/ip_carp.c: bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int32_t)); BPF writes were already supported (for packets up to 4 bytes less than the IP MTU of the interface) for the following drivers: - if_disc - if_faith - if_gif - if_gre - if_loop - if_tun - ng_iface I went through and altered the way BPF writes are handled in these drivers. The code was basically changed as follows: /* BPF write needs to be handled specially */ if (dst->sa_family == AF_UNSPEC) { - dst->sa_family = *(mtod(m0, int *)); - m0->m_len -= sizeof(int); - m0->m_pkthdr.len -= sizeof(int); - m0->m_data += sizeof(int); + bcopy(dst->sa_data, &af, sizeof(af)); + dst->sa_family = af; } The exception is if_loop.c, where the bpf write handling was in a weird place. BPF write was checked in if_simloop, rather than looutput. However, anything supplying if_simloop a packet to write is not a DLT_NULL BPF device, unless it is looutput. So I shifted the BPF write check to looutput. Otherwise, i added BPF write support to the remaining drivers (if_stf, if_ic, if_plip, i4b_ipr.c, and ip_carp.c). I did not determine how to include the appropriate bpf write code in ng_sppp.c - it does not appear to require it. Please review. Matthew
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050607101927.GA99034>