On Fri, Feb 20, 2015 at 2:15 PM, Pravin Shelar <pshe...@nicira.com> wrote: > On Fri, Feb 20, 2015 at 10:50 AM, Jesse Gross <je...@nicira.com> wrote: >> This series backports much of the UDP tunnel infrastructure, ultimately >> in support of syncing Geneve with upstream and providing outer UDP >> checksum support. >> >> During the backporting process, I realized that there are several >> other lurking bugs that were fixed through a more complete UDP >> tunnel layer. The ones that I am aware of are: >> * VXLAN TSO fails in some cases because the OVS handle_offload() >> function is used with the upstream GSO handler. >> * Hardware VXLAN offload was disabled on kernels that is otherwise >> supported on since version checks were incremented by the GBP changes. >> * LISP attempts to use hardware offload with NICs that only support >> VXLAN >> * LISP accesses unset inner headers when getting the source port for >> egress info. >> >> v3: Patches 1-5 were pushed to master and have been removed from this >> series. >> > I just noticed series does not compile on 3.10 and 3.18 kernel.
OK, here's what I ended up with as a diff. It has both the iptunnel_xmit() simplification and a couple minor fixes for those kernels that were broken: diff --git a/acinclude.m4 b/acinclude.m4 index 25110c0..d8b415e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -365,8 +365,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [netlink_has_listeners(net-> [OVS_DEFINE([HAVE_GENL_HAS_LISTENERS_TAKES_NET])]) OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_cisco_register]) - OVS_GREP_IFELSE([$KSRC/include/net/ip_tunnels.h], [iptunnel_xmit.*net], - [OVS_DEFINE([HAVE_IPTUNNEL_XMIT_NET])]) OVS_GREP_IFELSE([$KSRC/include/net/ipv6.h], [IP6_FH_F_SKIP_RH]) OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_get_be16]) OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_put_be16]) diff --git a/datapath/linux/compat/gso.c b/datapath/linux/compat/gso.c index 79adae1..cad9b18 100644 --- a/datapath/linux/compat/gso.c +++ b/datapath/linux/compat/gso.c @@ -242,11 +242,29 @@ free: return segs; } +static int output_ip(struct sk_buff *skb) +{ + int ret = NETDEV_TX_OK; + int err; + + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); + +#undef ip_local_out + err = ip_local_out(skb); + if (unlikely(net_xmit_eval(err))) + ret = err; + + return ret; +} + int rpl_ip_local_out(struct sk_buff *skb) { int ret = NETDEV_TX_OK; int id = -1; + if (!OVS_GSO_CB(skb)->fix_segment) + return output_ip(skb); + if (skb_is_gso(skb)) { struct iphdr *iph; @@ -266,7 +284,6 @@ int rpl_ip_local_out(struct sk_buff *skb) while (skb) { struct sk_buff *next_skb = skb->next; struct iphdr *iph; - int err; skb->next = NULL; @@ -274,13 +291,7 @@ int rpl_ip_local_out(struct sk_buff *skb) if (id >= 0) iph->id = htons(id++); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - -#undef ip_local_out - err = ip_local_out(skb); - if (unlikely(net_xmit_eval(err))) - ret = err; - + ret = output_ip(skb); skb = next_skb; } return ret; diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/com index 017acf0..bb96ec3 100644 --- a/datapath/linux/compat/include/net/ip_tunnels.h +++ b/datapath/linux/compat/include/net/ip_tunnels.h @@ -47,7 +47,6 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __b #define TUNNEL_REC __cpu_to_be16(0x20) #define TUNNEL_VERSION __cpu_to_be16(0x40) #define TUNNEL_NO_KEY __cpu_to_be16(0x80) -#define TUNNEL_DONT_FRAGMENT __cpu_to_be16(0x0100) struct tnl_ptk_info { __be16 flags; @@ -60,6 +59,10 @@ struct tnl_ptk_info { #define PACKET_REJECT 1 #endif +#ifndef TUNNEL_DONT_FRAGMENT +#define TUNNEL_DONT_FRAGMENT __cpu_to_be16(0x0100) +#endif + #ifndef TUNNEL_OAM #define TUNNEL_OAM __cpu_to_be16(0x0200) #define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400) diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_ index c37db14..5e38603 100644 --- a/datapath/linux/compat/ip_tunnels_core.c +++ b/datapath/linux/compat/ip_tunnels_core.c @@ -36,10 +36,9 @@ #include "gso.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) -static int ovs_iptunnel_xmit(struct sock *sk, struct rtable *rt, - struct sk_buff *skb, __be32 src, __be32 dst, - __u8 proto, __u8 tos, __u8 ttl, __be16 df, - bool xnet) +int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, + __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl, + __be16 df, bool xnet) { int pkt_len = skb->len; struct iphdr *iph; @@ -82,30 +81,6 @@ static int ovs_iptunnel_xmit(struct sock *sk, struct rtable * return pkt_len; } -int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, - __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl, - __be16 df, bool xnet) -{ - if (OVS_GSO_CB(skb)->fix_segment) - return ovs_iptunnel_xmit(sk, rt, skb, src, dst, proto, tos, - ttl, df, xnet); - -#undef iptunnel_xmit - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) - return ovs_iptunnel_xmit(sk, rt, skb, src, dst, proto, tos, ttl, - df, xnet); -#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) -#ifdef HAVE_IPTUNNEL_XMIT_NET - return iptunnel_xmit(NULL, rt, skb, src, dst, proto, tos, ttl, df); -#else - return iptunnel_xmit(rt, skb, src, dst, proto, tos, ttl, df, xnet); -#endif -#else - return iptunnel_xmit(sk, rt, skb, src, dst, proto, tos, ttl, df, xnet); -#endif -} - struct sk_buff *ovs_iptunnel_handle_offloads(struct sk_buff *skb, bool csum_help, int gso_type_mask, void (*fix_segment)(struct sk_buff diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index 7556dc5..960ddba 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -61,13 +61,12 @@ #include "vlan.h" #ifndef USE_UPSTREAM_VXLAN -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) + /* VXLAN protocol header */ struct vxlanhdr { __be32 vx_flags; __be32 vx_vni; }; -#endif /* Callback from net/ipv4/udp.c to receive packets */ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev