From a2377e444a0e0a3f3c6db2502c63cc9545572281 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 17 Jun 2010 15:15:11 -0700 Subject: [PATCH] datapath: Call vswitch_skb_checksum_setup() before doing GSO. Since GSO computes checksums as it does segmentation, we need to setup the checksum pointers before calling skb_gso_segment(). Failing to do so can potentially result in warnings, incorrect checksums, crashes, or redundant checksum computation. In general we don't hit this case because the code path is run during the first packet in a flow, which is generally not a large GSO packet. This was found during the investigation of NIC-121 but has no impact on it because vswitch_skb_checksum_setup() is a no-op on 2.6.27-based XenServer kernels. --- datapath/datapath.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 39bc190b..5907e81f 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -743,13 +743,6 @@ queue_control_packets(struct sk_buff *skb, struct sk_buff_head *queue, nskb = skb->next; skb->next = NULL; - /* If a checksum-deferred packet is forwarded to the - * controller, correct the pointers and checksum. - */ - err = vswitch_skb_checksum_setup(skb); - if (err) - goto err_kfree_skbs; - if (skb->ip_summed == CHECKSUM_PARTIAL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) @@ -810,6 +803,10 @@ dp_output_control(struct datapath *dp, struct sk_buff *skb, int queue_no, forward_ip_summed(skb); + err = vswitch_skb_checksum_setup(skb); + if (err) + goto err_kfree_skb; + /* Break apart GSO packets into their component pieces. Otherwise * userspace may try to stuff a 64kB packet into a 1500-byte MTU. */ if (skb_is_gso(skb)) { -- 2.30.2