aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2012-07-20 17:47:54 -0400
committerJesse Gross <jesse@nicira.com>2012-07-20 17:47:54 -0400
commita1b5d0dd28e9cb4fe42ad2df4ebbe5cce96866d7 (patch)
tree9642e1cee958e5a5cb3b61f112deb66c7b6f9f22 /net
parent92e5dfc34cf39c20ae1087bd5e676238b5d0dfac (diff)
openvswitch: 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. Signed-off-by: Ben Pfaff <blp@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net')
-rw-r--r--net/openvswitch/datapath.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 670e63020667..29dbfcb65d92 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -263,6 +263,7 @@ err:
263static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb, 263static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
264 const struct dp_upcall_info *upcall_info) 264 const struct dp_upcall_info *upcall_info)
265{ 265{
266 unsigned short gso_type = skb_shinfo(skb)->gso_type;
266 struct dp_upcall_info later_info; 267 struct dp_upcall_info later_info;
267 struct sw_flow_key later_key; 268 struct sw_flow_key later_key;
268 struct sk_buff *segs, *nskb; 269 struct sk_buff *segs, *nskb;
@@ -279,7 +280,7 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
279 if (err) 280 if (err)
280 break; 281 break;
281 282
282 if (skb == segs && skb_shinfo(skb)->gso_type & SKB_GSO_UDP) { 283 if (skb == segs && gso_type & SKB_GSO_UDP) {
283 /* The initial flow key extracted by ovs_flow_extract() 284 /* The initial flow key extracted by ovs_flow_extract()
284 * in this case is for a first fragment, so we need to 285 * in this case is for a first fragment, so we need to
285 * properly mark later fragments. 286 * properly mark later fragments.