Following patch enables all available tunnel GSO features for OVS
bridge device so that ovs can use hardware offloads available to
underling device.

Signed-off-by: Pravin B Shelar <pshe...@nicira.com>
---
 acinclude.m4                                       |  2 ++
 .../linux/compat/include/linux/netdev_features.h   | 36 ++++++++++++++++++++++
 datapath/linux/compat/include/net/gre.h            | 13 ++++++++
 datapath/linux/compat/include/net/vxlan.h          | 19 ++++++++++++
 datapath/vport-geneve.c                            |  5 +++
 datapath/vport-internal_dev.c                      |  8 ++++-
 datapath/vport-lisp.c                              |  5 +++
 7 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/acinclude.m4 b/acinclude.m4
index aa9ffcd..3d6d49b 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -281,6 +281,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [can_checksum_protocol])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netdev_features_t])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [pcpu_sw_netstats])
+  OVS_GREP_IFELSE([$KSRC/include/linux/netdev_features.h], [NETIF_F_GSO_GRE])
+  OVS_GREP_IFELSE([$KSRC/include/linux/netdev_features.h], 
[NETIF_F_GSO_UDP_TUNNEL])
 
   OVS_GREP_IFELSE([$KSRC/include/linux/random.h], [prandom_u32])
 
diff --git a/datapath/linux/compat/include/linux/netdev_features.h 
b/datapath/linux/compat/include/linux/netdev_features.h
index 0259413..3dfa49f 100644
--- a/datapath/linux/compat/include/linux/netdev_features.h
+++ b/datapath/linux/compat/include/linux/netdev_features.h
@@ -9,4 +9,40 @@
 #define NETIF_F_HW_VLAN_CTAG_TX NETIF_F_HW_VLAN_TX
 #endif
 
+#ifndef NETIF_F_GSO_GRE
+#define NETIF_F_GSO_GRE        0
+#endif
+
+#ifndef NETIF_F_GSO_GRE_CSUM
+#define NETIF_F_GSO_GRE_CSUM 0
+#endif
+
+#ifndef NETIF_F_GSO_IPIP
+#define NETIF_F_GSO_IPIP 0
+#endif
+
+#ifndef NETIF_F_GSO_SIT
+#define NETIF_F_GSO_SIT 0
+#endif
+
+#ifndef NETIF_F_GSO_UDP_TUNNEL
+#define NETIF_F_GSO_UDP_TUNNEL 0
+#endif
+
+#ifndef NETIF_F_GSO_UDP_TUNNEL_CSUM
+#define NETIF_F_GSO_UDP_TUNNEL_CSUM 0
+#endif
+
+#ifndef NETIF_F_GSO_MPLS
+#define NETIF_F_GSO_MPLS 0
+#endif
+
+#define NETIF_F_GSO_ENCAP_ALL  (NETIF_F_GSO_GRE |                      \
+                                NETIF_F_GSO_GRE_CSUM |                 \
+                                NETIF_F_GSO_IPIP |                     \
+                                NETIF_F_GSO_SIT |                      \
+                                NETIF_F_GSO_UDP_TUNNEL |               \
+                                NETIF_F_GSO_UDP_TUNNEL_CSUM |          \
+                                NETIF_F_GSO_MPLS)
+
 #endif
diff --git a/datapath/linux/compat/include/net/gre.h 
b/datapath/linux/compat/include/net/gre.h
index dc03535..051f523 100644
--- a/datapath/linux/compat/include/net/gre.h
+++ b/datapath/linux/compat/include/net/gre.h
@@ -105,4 +105,17 @@ static inline int ip_gre_calc_hlen(__be16 o_flags)
 }
 #endif
 
+#ifdef HAVE_NETIF_F_GSO_GRE
+static inline struct sk_buff *rpl_gre_handle_offloads(struct sk_buff *skb,
+                                                 bool gre_csum)
+{
+       if (skb->encapsulation && skb_is_gso(skb)) {
+               kfree_skb(skb);
+               return ERR_PTR(-ENOSYS);
+       }
+       return gre_handle_offloads(skb, gre_csum);
+}
+#define gre_handle_offloads rpl_gre_handle_offloads
+#endif
+
 #endif
diff --git a/datapath/linux/compat/include/net/vxlan.h 
b/datapath/linux/compat/include/net/vxlan.h
index 414a497..4b698d3 100644
--- a/datapath/linux/compat/include/net/vxlan.h
+++ b/datapath/linux/compat/include/net/vxlan.h
@@ -8,6 +8,25 @@
 #include <linux/version.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)
 #include_next <net/vxlan.h>
+
+#ifdef HAVE_NETIF_F_GSO_UDP_TUNNEL
+static inline int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
+                   struct rtable *rt, struct sk_buff *skb,
+                   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
+                   __be16 src_port, __be16 dst_port, __be32 vni)
+{
+       if (skb->encapsulation && skb_is_gso(skb)) {
+               kfree_skb(skb);
+               return -ENOSYS;
+       }
+
+       return vxlan_xmit_skb(vs, rt, skb, src, dst, tos, ttl, df,
+                             src_port, dst_port, vni);
+}
+
+#define vxlan_xmit_skb rpl_vxlan_xmit_skb
+#endif
+
 #else
 
 struct vxlan_sock;
diff --git a/datapath/vport-geneve.c b/datapath/vport-geneve.c
index 33047f2..99841d4 100644
--- a/datapath/vport-geneve.c
+++ b/datapath/vport-geneve.c
@@ -333,6 +333,11 @@ static int handle_offloads(struct sk_buff *skb)
 #else
 static int handle_offloads(struct sk_buff *skb)
 {
+       if (skb->encapsulation && skb_is_gso(skb)) {
+               kfree_skb(skb);
+               return -ENOSYS;
+       }
+
        if (skb_is_gso(skb)) {
                int err = skb_unclone(skb, GFP_ATOMIC);
                if (unlikely(err))
diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c
index 637d712..ae526a3 100644
--- a/datapath/vport-internal_dev.c
+++ b/datapath/vport-internal_dev.c
@@ -155,7 +155,8 @@ static void do_setup(struct net_device *netdev)
        netdev->tx_queue_len = 0;
 
        netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
-                          NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | 
NETIF_F_GSO_SOFTWARE;
+                          NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
+                          NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
 
        netdev->vlan_features = netdev->features;
        netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
@@ -163,6 +164,11 @@ static void do_setup(struct net_device *netdev)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
        netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
 #endif
+
+#ifdef HAVE_NETIF_F_GSO_GRE
+       netdev->hw_enc_features = netdev->features;
+#endif
+
        eth_hw_addr_random(netdev);
 }
 
diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c
index c41e09e..81ecf92 100644
--- a/datapath/vport-lisp.c
+++ b/datapath/vport-lisp.c
@@ -409,6 +409,11 @@ static int handle_offloads(struct sk_buff *skb)
 #else
 static int handle_offloads(struct sk_buff *skb)
 {
+       if (skb->encapsulation && skb_is_gso(skb)) {
+               kfree_skb(skb);
+               return -ENOSYS;
+       }
+
        if (skb_is_gso(skb)) {
                int err = skb_unclone(skb, GFP_ATOMIC);
                if (unlikely(err))
-- 
1.9.3

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

Reply via email to