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-netdev.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-netdev.c')
-rw-r--r-- | datapath/vport-netdev.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 3bab666c..bc3108b9 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -284,7 +284,11 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) skb_warn_if_lro(skb); skb_push(skb, ETH_HLEN); - compute_ip_summed(skb, false); + + if (unlikely(compute_ip_summed(skb, false))) { + kfree_skb(skb); + return; + } vlan_copy_skb_tci(skb); vport_receive(vport, skb); @@ -309,22 +313,15 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) int len; skb->dev = netdev_vport->dev; - forward_ip_summed(skb); + forward_ip_summed(skb, true); if (vlan_tx_tag_present(skb) && !dev_supports_vlan_tx(skb->dev)) { - int err; int features = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) features = skb->dev->features & skb->dev->vlan_features; #endif - err = vswitch_skb_checksum_setup(skb); - if (unlikely(err)) { - kfree_skb(skb); - return 0; - } - if (!vlan_tso) features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO | NETIF_F_FSO); |