bpf writes on tun device
Matthew Luckie
mjl at luckie.org.nz
Tue Jun 7 10:20:41 GMT 2005
> 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
More information about the freebsd-net
mailing list