diff options
author | Jesse Gross <jesse@nicira.com> | 2010-02-28 12:17:16 -0500 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2010-02-28 15:45:00 -0500 |
commit | a063b0dff0ccb6639f7e95969843d1c7cc2e15ae (patch) | |
tree | 5c9813b7266967689472fe1a2e5b20b28fcc733e /datapath/actions.c | |
parent | 79554078d08b849059389f007a00c85b471d9e3d (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.c | 36 |
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) |