ipfw and bridge: unaligned payload pointers panicing perfectly
performing MIPS boxes
adrian.chadd at gmail.com
Tue Nov 23 08:21:37 UTC 2010
bz and I have done a bit of sleuthing. There's a few problems!
Firstly - bridge_pfil() in sys/net/if_bridge.c calls a couple of
functions to check the validity and alignment of ipv4/ipv6 packets
(ie, bridge_ip_checkbasic() and bridge_ip6_checkbasic().) But
bridge_ip6_checkbasic() is only called if the kernel is compiled with
INET6. This MIPS platform I'm working on currently doesn't have INET6
compiled in, so:
* IPv6 packet arrives in if_bridge
* It doesn't get passed to bridge_ip6_checkbasic()
* It gets punted to ipfw_chk() (I have net.link.bridge.ipfw set to 1)
* ipfw_chk() sees the ethertype being IPv6 so it does the check
whether the IP header version is IPv6 = but at that stage (struct ip
*) ip is unaligned and an exception occurs.
The fix - compile in INET6. :-/ I'd like to not rely on that though!
Secondly - other misaligned packets were sneaking in. That's fine for
now - the payload shouldn't be being fondled. But the ethertype was
garbage. What bz and I found is that it's a SNAP packet (the ethertype
being 0x001b) and although if_bridge.c::bridge_pfil() strips the SNAP
header from the mbuf, the copy of the ethernet header it passes to
ipfw_chk() still has the old ethertype set.
Suggestion - when stripping off the SNAP header, set eh2.ether_type to
the "correct" ether type, rather than the SNAP length field.
More information about the freebsd-net