aboutsummaryrefslogtreecommitdiff
path: root/datapath/actions.c
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2010-02-28 12:17:16 -0500
committerJesse Gross <jesse@nicira.com>2010-02-28 15:45:00 -0500
commita063b0dff0ccb6639f7e95969843d1c7cc2e15ae (patch)
tree5c9813b7266967689472fe1a2e5b20b28fcc733e /datapath/actions.c
parent79554078d08b849059389f007a00c85b471d9e3d (diff)
datapath: Consistently maintain checksum offloading state.
When adding a VLAN tag it is necessary for us to setup checksum pointers for offloaded packets manually. However, this process clobbers some of the fields that other components need to determine the current status. Here we mark the packet with its status upon ingress in our own format that does not get clobbered and is consistent across kernel versions. Bug #2436
Diffstat (limited to 'datapath/actions.c')
-rw-r--r--datapath/actions.c36
1 files changed, 2 insertions, 34 deletions
diff --git a/datapath/actions.c b/datapath/actions.c
index b39d8307..b20873bf 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -215,42 +215,10 @@ static void update_csum(__sum16 *sum, struct sk_buff *skb,
{
__be32 diff[] = { ~from, to };
-/* On older kernels, CHECKSUM_PARTIAL and CHECKSUM_COMPLETE are both defined
- * as CHECKSUM_HW. However, we can make some inferences so that we can update
- * the checksums appropriately. */
- enum {
- CSUM_PARTIAL, /* Partial checksum, skb->csum undefined. */
- CSUM_PACKET, /* In-packet checksum, skb->csum undefined. */
- CSUM_COMPLETE, /* In-packet checksum, skb->csum valid. */
- } csum_type;
-
- csum_type = CSUM_PACKET;
-#ifndef CHECKSUM_HW
- /* Newer kernel, just map between kernel types and ours. */
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- csum_type = CSUM_PARTIAL;
- else if (skb->ip_summed == CHECKSUM_COMPLETE)
- csum_type = CSUM_COMPLETE;
-#else
- /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE.
- * However, we should only get CHECKSUM_PARTIAL packets from Xen, which
- * uses some special fields to represent this (see below). Since we
- * can only make one type work, pick the one that actually happens in
- * practice. */
- if (skb->ip_summed == CHECKSUM_HW)
- csum_type = CSUM_COMPLETE;
-#endif
-#if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
- /* Xen has a special way of representing CHECKSUM_PARTIAL on older
- * kernels. */
- if (skb->proto_csum_blank)
- csum_type = CSUM_PARTIAL;
-#endif
-
- if (csum_type != CSUM_PARTIAL) {
+ if (OVS_CB(skb)->ip_summed != CSUM_PARTIAL) {
*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
~csum_unfold(*sum)));
- if (csum_type == CSUM_COMPLETE && pseudohdr)
+ if (OVS_CB(skb)->ip_summed == CSUM_COMPLETE && pseudohdr)
skb->csum = ~csum_partial((char *)diff, sizeof(diff),
~skb->csum);
} else if (pseudohdr)