This is a backport of part of a bug fix that''s already in mainline Linux. The first part of the original fix was applied to 2.6.18, the subsequent parts to 2.6.19. As a result, Xen currently only has the first part in the linux-2.6.18-xen.hg tree. The patch in question was originally posted here: http://marc.info/?l=linux-netdev&m=115629237505025&w=2 I''m sure adding backported fixes isn''t something you want to do regularly, but as this was found and fixed for a problem on Xen it might be more applicable. The bug I saw (if I remember correctly - it''s been some time since I found and backported this fix) was one where netfilter would try to pull 16 bytes (rather than ETH_HLEN) off the front of a socket buffer, and this would drop us two bytes from the end of the previous page. This caused a seg fault as the previous page was not in use. For many drivers this wouldn''t be a problem as they have an extra two bytes of head room thanks to NET_IP_ALIGN, or they just get lucky with the previous page - I think the reason this was originally found on Xen was due to it being much more likely that you''ll be unlucky. If I''m honest I didn''t look too deeply once I found this fixed it. To keep it short and simple, I''ve only backported the functional bits of the above patch. I.e. I''ve left out the code rearrangement and clarity changes. Signed-off-by: Kieran Mansley <kmansley@solarflare.com> Kieran Backport 2.6.19 netfilter ETH_HLEN bug fix diff -r 9bf1ddd0f6bf include/linux/netfilter_bridge.h --- a/include/linux/netfilter_bridge.h Wed Oct 17 09:24:03 2007 +0100 +++ b/include/linux/netfilter_bridge.h Fri Oct 19 10:53:27 2007 +0100 @@ -7,6 +7,7 @@ #include <linux/netfilter.h> #if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) #include <linux/if_ether.h> +#include <linux/if_vlan.h> #endif /* Bridge Hooks */ @@ -54,16 +55,19 @@ int nf_bridge_maybe_copy_header(struct s if (skb->nf_bridge) { if (skb->protocol == __constant_htons(ETH_P_8021Q)) { - err = skb_cow(skb, 18); + int header_size = ETH_HLEN + VLAN_HLEN; + + err = skb_cow(skb, header_size); if (err) return err; - memcpy(skb->data - 18, skb->nf_bridge->data, 18); - skb_push(skb, 4); + memcpy(skb->data - header_size, skb->nf_bridge->data, + header_size); + skb_push(skb, VLAN_HLEN); } else { - err = skb_cow(skb, 16); + err = skb_cow(skb, ETH_HLEN); if (err) return err; - memcpy(skb->data - 16, skb->nf_bridge->data, 16); + memcpy(skb->data - ETH_HLEN, skb->nf_bridge->data, ETH_HLEN); } } return 0; diff -r 9bf1ddd0f6bf net/bridge/br_netfilter.c --- a/net/bridge/br_netfilter.c Wed Oct 17 09:24:03 2007 +0100 +++ b/net/bridge/br_netfilter.c Fri Oct 19 10:37:06 2007 +0100 @@ -127,10 +127,10 @@ static inline struct nf_bridge_info *nf_ static inline void nf_bridge_save_header(struct sk_buff *skb) { - int header_size = 16; + int header_size = ETH_HLEN; if (skb->protocol == htons(ETH_P_8021Q)) - header_size = 18; + header_size += VLAN_HLEN; memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel