tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

(non-)Equivalence of if_type == IFT_ETHER and (struct ethercom*) == (struct ifnet*)



Hey folks,

I just stumbled into an issue with vlan(4):

In -current, if you have a wifi interface - say urtwn0 - and
  configure a vlan for it like this:

	ifconfig urtwn0 up
	ifconfig vlan0 create
	ifconfig vlan0 vlan 6 vlanif urtwn0

you might crash your kernel. This is because the wlan interfaces are of
if_type == IFT_ETHER, which is a small lie, but userland (bpf readers)
rely on it and the traffic captured that way is indeed just like ethernet
traffic. There is a second mode on most wifi interfaces where you can
see the real IEEE80211 frames, and for that bpf uses IFT_IEEE80211.

But: we have separated the ethernet specific stuff from the struct ifnet
generic interface stuff, and use struct ethercom for the things common
to ethernet interfaces. Wifi interface behave kinda like that, but are
not ethernet - and they do not (currently) have a struct ethercom.

Now we have a problem: if_vlan.c checks the "parent" interface for IFT_ETHER
and if that is true, assumes it can cast "struct ifnet *ifp" to "struct
ethercom *" and acces that.

Try that for a wifi interface: *boom*.

For wifi interface (in the new stack) I actually need two fields out of
struct ethercom - the multicast and the vlan list. I originaly planned
to only add those and for the multicast part this is quite simple. But
for vlans it is not easy with the current structure of if_vlan.c.

I see three options:

 - Use (a mostly unused) struct ethercom for wifi interfaces too and make
   sure the ifp and ethercom pointers are castable. This is easy and
   most likely the way I'll go forward.

 - Restructure if_vlan.c to have some indirection in the vlan list and
   capability modifying operations - quite straight forward way: add
   special in-kernel-only ioctl operations for that. For most interfaces
   the common ether_ioctl code would deal with those and invoke the
   vlan helpers in ether_subr.c. For wifi interfaces the ieee80211 ioctl
   handler would catch the operations and either handle them with
   "clones" of the current ether_subr.c helper functions or arrange for
   different args and call them some way.

   This might mean introducing a ethercom sub-structure shared by everything
   that holds mcast and vlan info and becomes part of struct ethercom.

   We could gain type-safety by adding a special "cast" function to struct
   ifnet: if != NULL a caller could invoke that function, passing the struct
   ifnet* and get back a pointer to the new sub-structure. Or we could
   do that via a special ioctl.

 - Just for completeness: in FreeBSD there is no struct ethercom and instead
   the vlan and multicast lists (and associated fields) are in the generic
   interface structure. We could move that way (slightly punishing all
   non-ethernet-alike interfaces), getting rid of all ethercom* casts.


What do you think?

Martin


Home | Main Index | Thread Index | Old Index