summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-07-10 14:11:59 -0700
committerBen Pfaff <blp@nicira.com>2012-07-10 15:30:57 -0700
commitfdd80c39b1822db6c8b5c8274ff0c5cebcaa36b7 (patch)
treef5ac0557592ae30c9ae42b0d7e577f43a062e15e
parentf266b3db510655f0d6bff84911c5c0d7806f1e4d (diff)
downloadopenvswitch-fdd80c39b1822db6c8b5c8274ff0c5cebcaa36b7.tar.gz
datapath: Check gso_type for correct sk_buff in queue_gso_packets().
At the point where it was used, skb_shinfo(skb)->gso_type referred to a post-GSO sk_buff. Thus, it would always be 0. We want to know the pre-GSO gso_type, so we need to obtain it before segmenting. Before this change, the kernel would pass inconsistent data to userspace: packets for UDP fragments with nonzero offset would be passed along with flow keys that indicate a zero offset (that is, the flow key for "later" fragments claimed to be "first" fragments). This inconsistency tended to confuse Open vSwitch userspace, causing it to log messages about "failed to flow_del" the flows with "later" fragments. Bug #12394. Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--datapath/datapath.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/datapath/datapath.c b/datapath/datapath.c
index da45cd2de..0f70032b1 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -378,6 +378,7 @@ err:
static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
const struct dp_upcall_info *upcall_info)
{
+ unsigned short gso_type = skb_shinfo(skb)->gso_type;
struct dp_upcall_info later_info;
struct sw_flow_key later_key;
struct sk_buff *segs, *nskb;
@@ -394,7 +395,7 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
if (err)
break;
- if (skb == segs && skb_shinfo(skb)->gso_type & SKB_GSO_UDP) {
+ if (skb == segs && gso_type & SKB_GSO_UDP) {
/* The initial flow key extracted by flow_extract() in
* this case is for a first fragment, so we need to
* properly mark later fragments.