diff options
author | Jesse Gross <jesse@nicira.com> | 2011-05-27 15:53:49 -0700 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2011-06-16 14:48:12 -0700 |
commit | c3729ee42dc25a8240cee6c0041b7db3e4070414 (patch) | |
tree | 2f65993edb1c3e1aa06b5468d3565ab168592f24 /datapath/vport-internal_dev.c | |
parent | e6269c12f294f71c9e6a31c153a12cf26124c235 (diff) |
datapath: Further mirror checksum offloading state on old kernels.
Older kernels (those before 2.6.22) rely on implicit assumptions
to determine checksum offloading status. These assumptions tend
to break down when doing switching because it sits in the middle
of the transmit and receive path. Newer kernels deal with this
problem by adding more explicit information about how to checksum.
This replicates that behavior by mirroring the state from newer
kernels in private OVS storage on the kernels that lack it. On
ingress and egress we then map that state onto the appropriate
location for the given kernel and can consistently manipulate it
within OVS. Some of this was already done for the checksum type
but this makes it more robust and expands it to the checksum start
and offset as well.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath/vport-internal_dev.c')
-rw-r--r-- | datapath/vport-internal_dev.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c index fff4f4e5..b7bcbce6 100644 --- a/datapath/vport-internal_dev.c +++ b/datapath/vport-internal_dev.c @@ -73,7 +73,11 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p) /* Called with rcu_read_lock and bottom-halves disabled. */ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) { - compute_ip_summed(skb, true); + if (unlikely(compute_ip_summed(skb, true))) { + kfree_skb(skb); + return 0; + } + vlan_copy_skb_tci(skb); OVS_CB(skb)->flow = NULL; @@ -252,6 +256,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) skb->dev = netdev; skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, netdev); + forward_ip_summed(skb, false); if (in_interrupt()) netif_rx(skb); |