Skip to content

Commit

Permalink
bridge: Fix network header pointer for vlan tagged packets
Browse files Browse the repository at this point in the history
There are several devices that can receive vlan tagged packets with
CHECKSUM_PARTIAL like tap, possibly veth and xennet.
When (multiple) vlan tagged packets with CHECKSUM_PARTIAL are forwarded
by bridge to a device with the IP_CSUM feature, they end up with checksum
error because before entering bridge, the network header is set to
ETH_HLEN (not including vlan header length) in __netif_receive_skb_core(),
get_rps_cpu(), or drivers' rx functions, and nobody fixes the pointer later.

Since the network header is exepected to be ETH_HLEN in flow-dissection
and hash-calculation in RPS in rx path, and since the header pointer fix
is needed only in tx path, set the appropriate network header on forwarding
packets.

Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Toshiaki Makita authored and David S. Miller committed Jul 29, 2015
1 parent dbd46ab commit df356d5
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions net/bridge/br_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,30 @@ static inline int should_deliver(const struct net_bridge_port *p,

int br_dev_queue_push_xmit(struct sock *sk, struct sk_buff *skb)
{
if (!is_skb_forwardable(skb->dev, skb)) {
kfree_skb(skb);
} else {
skb_push(skb, ETH_HLEN);
br_drop_fake_rtable(skb);
skb_sender_cpu_clear(skb);
dev_queue_xmit(skb);
if (!is_skb_forwardable(skb->dev, skb))
goto drop;

skb_push(skb, ETH_HLEN);
br_drop_fake_rtable(skb);
skb_sender_cpu_clear(skb);

if (skb->ip_summed == CHECKSUM_PARTIAL &&
(skb->protocol == htons(ETH_P_8021Q) ||
skb->protocol == htons(ETH_P_8021AD))) {
int depth;

if (!__vlan_get_protocol(skb, skb->protocol, &depth))
goto drop;

skb_set_network_header(skb, depth);
}

dev_queue_xmit(skb);

return 0;

drop:
kfree_skb(skb);
return 0;
}
EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);
Expand Down

0 comments on commit df356d5

Please sign in to comment.