aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@free.fr>2011-03-14 02:08:07 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-14 19:54:44 -0400
commit12a2856b604476c27d85a5f9a57ae1661fc46019 (patch)
tree7537a26d442f4d03e2b97535f12923f7f8cecb60 /drivers/net/macvlan.c
parentb5ccd07337489fa9c9d32e0b628a2168b7953adf (diff)
macvlan : fix checksums error when we are in bridge mode
When the lower device has offloading capabilities, the packets checksums are not computed. That leads to have any macvlan port in bridge mode to not work because the packets are dropped due to a bad checksum. If the macvlan is in bridge mode, the packet is forwarded to another macvlan port and reach the network stack where it looks for a checksum but this one was not computed due to the offloading of the lower device. In this case, we have to set the packet with CHECKSUM_UNNECESSARY when it is forwarded to a bridged port and restore the previous value of ip_summed when the packet goes to the lowerdev. Signed-off-by: Daniel Lezcano <daniel.lezcano@free.fr> Cc: Patrick McHardy <kaber@trash.net> Cc: Andrian Nord <nightnord@gmail.com> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 6ed577b065df..497991bd3b64 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -219,9 +219,11 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
219 const struct macvlan_dev *vlan = netdev_priv(dev); 219 const struct macvlan_dev *vlan = netdev_priv(dev);
220 const struct macvlan_port *port = vlan->port; 220 const struct macvlan_port *port = vlan->port;
221 const struct macvlan_dev *dest; 221 const struct macvlan_dev *dest;
222 __u8 ip_summed = skb->ip_summed;
222 223
223 if (vlan->mode == MACVLAN_MODE_BRIDGE) { 224 if (vlan->mode == MACVLAN_MODE_BRIDGE) {
224 const struct ethhdr *eth = (void *)skb->data; 225 const struct ethhdr *eth = (void *)skb->data;
226 skb->ip_summed = CHECKSUM_UNNECESSARY;
225 227
226 /* send to other bridge ports directly */ 228 /* send to other bridge ports directly */
227 if (is_multicast_ether_addr(eth->h_dest)) { 229 if (is_multicast_ether_addr(eth->h_dest)) {
@@ -241,6 +243,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
241 } 243 }
242 244
243xmit_world: 245xmit_world:
246 skb->ip_summed = ip_summed;
244 skb_set_dev(skb, vlan->lowerdev); 247 skb_set_dev(skb, vlan->lowerdev);
245 return dev_queue_xmit(skb); 248 return dev_queue_xmit(skb);
246} 249}