bridge: Fix network header pointer for vlan tagged packets
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>
This commit is contained in:
Родитель
dbd46ab412
Коммит
df356d5e81
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче