[BRIDGE] netfilter: vlan + hw checksum = bug?
It looks like the bridge netfilter code does not correctly update the hardware checksum after popping off the VLAN header. This is by inspection, I have *not* tested this. To test you would need to set up a filtering bridge with vlans and a device the does hardware receive checksum (skge, or sungem) Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a20a855479
commit
ee02b3a613
@ -394,7 +394,8 @@ inhdr_error:
|
|||||||
* target in particular. Save the original destination IP
|
* target in particular. Save the original destination IP
|
||||||
* address to be able to detect DNAT afterwards. */
|
* address to be able to detect DNAT afterwards. */
|
||||||
static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
||||||
const struct net_device *in, const struct net_device *out,
|
const struct net_device *in,
|
||||||
|
const struct net_device *out,
|
||||||
int (*okfn)(struct sk_buff *))
|
int (*okfn)(struct sk_buff *))
|
||||||
{
|
{
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
@ -412,8 +413,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||||
|
u8 *vhdr = skb->data;
|
||||||
skb_pull(skb, VLAN_HLEN);
|
skb_pull(skb, VLAN_HLEN);
|
||||||
(skb)->nh.raw += VLAN_HLEN;
|
skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
|
||||||
|
skb->nh.raw += VLAN_HLEN;
|
||||||
}
|
}
|
||||||
return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
|
return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
|
||||||
}
|
}
|
||||||
@ -429,8 +432,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
|
||||||
|
u8 *vhdr = skb->data;
|
||||||
skb_pull(skb, VLAN_HLEN);
|
skb_pull(skb, VLAN_HLEN);
|
||||||
(skb)->nh.raw += VLAN_HLEN;
|
skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
|
||||||
|
skb->nh.raw += VLAN_HLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
|
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user