In certain cases we need to ensure we save off skb->cb before
calling __skb_gso_segment() since in kernels >= 3.9 skb->cb is
used by this routine.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
Signed-off-by: Kyle Mestery <kmest...@cisco.com>
---
Changes in v3:
* Save skb->cb in gso.c:tnl_skb_gso_segment().
* Add FAQ and NEWS entries for Linux kernel 3.9 support.
Changes in v2:
* Save skb->cb in tunnel.c:handle_offloads().
* No longer save skb->sb in vport_netdev.c:netdev_send().
---
 FAQ                         | 2 +-
 NEWS                        | 1 +
 datapath/datapath.c         | 4 ++--
 datapath/linux/compat/gso.c | 6 ++++++
 datapath/tunnel.c           | 7 +++++++
 5 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/FAQ b/FAQ
index 6b5d8da..810803e 100644
--- a/FAQ
+++ b/FAQ
@@ -148,7 +148,7 @@ A: The following table lists the Linux kernel versions 
against which the
        1.9.x      2.6.18 to 3.8
        1.10.x     2.6.18 to 3.8
        1.11.x     2.6.18 to 3.8
-       1.12.x     2.6.18 to 3.8
+       1.12.x     2.6.18 to 3.9
 
    Open vSwitch userspace should also work with the Linux kernel module
    built into Linux 3.3 and later.
diff --git a/NEWS b/NEWS
index 3bf4421..c0a3ecb 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ v1.12.0 - xx xxx xxxx
       through database paths (e.g. Private key option with the database name
       should look like "--private-key=db:Open_vSwitch,SSL,private_key").
     - Added ovs-dev.py, a utility script helpful for Open vSwitch developers.
+    - Support for Linux kernels up to 3.9
 
 
 v1.11.0 - xx xxx xxxx
diff --git a/datapath/datapath.c b/datapath/datapath.c
index 4330ce3..e5e0616 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -63,8 +63,8 @@
 #include "vport-netdev.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \
-    LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
-#error Kernels before 2.6.18 or after 3.8 are not supported by this version of 
Open vSwitch.
+    LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#error Kernels before 2.6.18 or after 3.9 are not supported by this version of 
Open vSwitch.
 #endif
 
 #define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
diff --git a/datapath/linux/compat/gso.c b/datapath/linux/compat/gso.c
index 43418d3..30332a2 100644
--- a/datapath/linux/compat/gso.c
+++ b/datapath/linux/compat/gso.c
@@ -65,6 +65,7 @@ static struct sk_buff *tnl_skb_gso_segment(struct sk_buff 
*skb,
        struct sk_buff *skb1 = skb;
        struct sk_buff *segs;
        __be16 proto = skb->protocol;
+       char cb[sizeof(skb->cb)];
 
        /* setup whole inner packet to get protocol. */
        __skb_pull(skb, mac_offset);
@@ -76,6 +77,10 @@ static struct sk_buff *tnl_skb_gso_segment(struct sk_buff 
*skb,
        skb_reset_network_header(skb);
        skb_reset_transport_header(skb);
 
+       /* From 3.9 kernel skb->cb is used by skb gso. Therefore
+        * make copy of it to restore it back. */
+       memcpy(cb, skb->cb, sizeof(cb));
+
        segs = __skb_gso_segment(skb, 0, tx_path);
        if (!segs || IS_ERR(segs))
                goto free;
@@ -89,6 +94,7 @@ static struct sk_buff *tnl_skb_gso_segment(struct sk_buff 
*skb,
                skb->mac_len = 0;
 
                memcpy(ip_hdr(skb), iph, pkt_hlen);
+               memcpy(skb->cb, cb, sizeof(cb));
                if (OVS_GSO_CB(skb)->fix_segment)
                        OVS_GSO_CB(skb)->fix_segment(skb);
 
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index ef46a69..bd63da5 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -144,6 +144,9 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb)
 
        if (skb_is_gso(skb)) {
                struct sk_buff *nskb;
+               char cb[sizeof(skb->cb)];
+
+               memcpy(cb, skb->cb, sizeof(cb));
 
                nskb = __skb_gso_segment(skb, 0, false);
                if (IS_ERR(nskb)) {
@@ -153,6 +156,10 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb)
 
                consume_skb(skb);
                skb = nskb;
+               while (nskb) {
+                       memcpy(nskb->cb, cb, sizeof(cb));
+                       nskb = nskb->next;
+               }
        } else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
                /* Pages aren't locked and could change at any time.
                 * If this happens after we compute the checksum, the
-- 
1.8.3.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to