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