Kernel 4.3 is not released yet, but we need this to support netdev based vport in out of tree ovs module.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- FAQ.md | 2 +- acinclude.m4 | 11 ++++++- datapath/linux/compat/geneve.c | 3 +- datapath/linux/compat/gre.c | 2 +- datapath/linux/compat/gso.c | 5 ++- datapath/linux/compat/gso.h | 32 +++++++++++++++-------- datapath/linux/compat/include/linux/netdevice.h | 18 +++++------- datapath/linux/compat/include/net/geneve.h | 3 +- datapath/linux/compat/include/net/gre.h | 10 +++++-- datapath/linux/compat/include/net/ip_tunnels.h | 3 +- datapath/linux/compat/include/net/udp_tunnel.h | 4 ++- datapath/linux/compat/include/net/vxlan.h | 4 ++- datapath/linux/compat/ip_tunnels_core.c | 8 ++++- datapath/linux/compat/udp_tunnel.c | 11 +++----- 14 files changed, 72 insertions(+), 44 deletions(-) diff --git a/FAQ.md b/FAQ.md index d11c493..038c28a 100644 --- a/FAQ.md +++ b/FAQ.md @@ -156,7 +156,7 @@ A: The following table lists the Linux kernel versions against which the | 2.1.x | 2.6.32 to 3.11 | 2.3.x | 2.6.32 to 3.14 | 2.4.x | 2.6.32 to 4.0 -| 2.5.x | 2.6.32 to 4.2 +| 2.5.x | 2.6.32 to 4.3 Open vSwitch userspace should also work with the Linux kernel module built into Linux 3.3 and later. diff --git a/acinclude.m4 b/acinclude.m4 index b246dc7..c5848bc 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ AC_MSG_RESULT([$kversion]) if test "$version" -ge 4; then - if test "$version" = 4 && test "$patchlevel" -le 2; then + if test "$version" = 4 && test "$patchlevel" -le 3; then : # Linux 4.x else - AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.2.x is not supported (please refer to the FAQ for advice)]) + AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.3.x is not supported (please refer to the FAQ for advice)]) fi elif test "$version" = 3; then : # Linux 3.x @@ -327,6 +327,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/linux/in.h], [proto_ports_offset]) OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [__ip_select_ident.*dst_entry], [OVS_DEFINE([HAVE_IP_SELECT_IDENT_USING_DST_ENTRY])]) + OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [__ip_select_ident.*net], + [OVS_DEFINE([HAVE_IP_SELECT_IDENT_USING_NET])]) + OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [inet_get_local_port_range.*net], [OVS_DEFINE([HAVE_INET_GET_LOCAL_PORT_RANGE_USING_NET])]) OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [ip_is_fragment]) @@ -344,6 +347,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [net_device_extended]) OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [rx_handler_func_t.*pskb], [OVS_DEFINE([HAVE_RX_HANDLER_PSKB])]) + OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netif_needs_gso.*net_device], + [OVS_DEFINE([HAVE_NETIF_NEEDS_GSO_NETDEV])]) + OVS_GREP_IFELSE([$KSRC/include/linux/netfilter.h], [nf_hookfn.*nf_hook_ops], [OVS_DEFINE([HAVE_NF_HOOKFN_ARG_OPS])]) @@ -420,6 +426,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/geneve.h], [geneve_hdr]) OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_cisco_register]) + OVS_GREP_IFELSE([$KSRC/include/net/gre.h], [gre_handle_offloads]) 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/geneve.c b/datapath/linux/compat/geneve.c index 85cf95f..8475419 100644 --- a/datapath/linux/compat/geneve.c +++ b/datapath/linux/compat/geneve.c @@ -12,7 +12,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/version.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) && \ + defined(HAVE_GRE_HANDLE_OFFLOADS) #include <linux/kernel.h> #include <linux/types.h> diff --git a/datapath/linux/compat/gre.c b/datapath/linux/compat/gre.c index fe81380..de1dbaf 100644 --- a/datapath/linux/compat/gre.c +++ b/datapath/linux/compat/gre.c @@ -40,7 +40,7 @@ #if IS_ENABLED(CONFIG_NET_IPGRE_DEMUX) -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) +#ifndef HAVE_GRE_HANDLE_OFFLOADS #ifndef HAVE_GRE_CISCO_REGISTER diff --git a/datapath/linux/compat/gso.c b/datapath/linux/compat/gso.c index 2c19b58..d11c62e 100644 --- a/datapath/linux/compat/gso.c +++ b/datapath/linux/compat/gso.c @@ -130,7 +130,7 @@ int rpl_dev_queue_xmit(struct sk_buff *skb) if (mpls) features &= NETIF_F_SG; - if (netif_needs_gso(skb->dev, skb, features)) { + if (netif_needs_gso(skb, features)) { struct sk_buff *nskb; nskb = skb_gso_segment(skb, features); @@ -170,7 +170,8 @@ drop: EXPORT_SYMBOL_GPL(rpl_dev_queue_xmit); #endif /* OVS_USE_COMPAT_GSO_SEGMENTATION */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) static __be16 __skb_network_protocol(struct sk_buff *skb) { __be16 type = skb->protocol; diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h index 6fcaff8..bf409cf 100644 --- a/datapath/linux/compat/gso.h +++ b/datapath/linux/compat/gso.h @@ -2,7 +2,8 @@ #define __LINUX_GSO_WRAPPER_H #include <linux/version.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) #include <linux/netdevice.h> #include <linux/skbuff.h> @@ -14,13 +15,10 @@ typedef void (*gso_fix_segment_t)(struct sk_buff *); struct ovs_gso_cb { struct ovs_skb_cb dp_cb; gso_fix_segment_t fix_segment; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) __be16 inner_protocol; -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) unsigned int inner_mac_header; -#endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) unsigned int inner_network_header; #endif }; @@ -37,12 +35,15 @@ static inline void skb_clear_ovs_gso_cb(struct sk_buff *skb) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) +#define skb_inner_mac_header rpl_skb_inner_mac_header static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb) { return skb->head + OVS_GSO_CB(skb)->inner_mac_header; } +#define skb_set_inner_mac_header rpl_skb_set_inner_mac_header static inline void skb_set_inner_mac_header(const struct sk_buff *skb, int offset) { @@ -50,12 +51,15 @@ static inline void skb_set_inner_mac_header(const struct sk_buff *skb, } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) +#define skb_inner_network_header rpl_skb_inner_network_header static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb) { return skb->head + OVS_GSO_CB(skb)->inner_network_header; } +#define skb_inner_network_offset rpl_skb_inner_network_offset static inline int skb_inner_network_offset(const struct sk_buff *skb) { return skb_inner_network_header(skb) - skb->data; @@ -70,6 +74,7 @@ static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb) return 0; } +#define skb_set_inner_network_header rpl_skb_set_inner_network_header static inline void skb_set_inner_network_header(const struct sk_buff *skb, int offset) { @@ -77,6 +82,7 @@ static inline void skb_set_inner_network_header(const struct sk_buff *skb, + offset; } +#define skb_set_inner_transport_header rpl_skb_set_inner_transport_header static inline void skb_set_inner_transport_header(const struct sk_buff *skb, int offset) { } @@ -90,7 +96,8 @@ static inline int ovs_skb_inner_transport_offset(const struct sk_buff *skb) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) { OVS_GSO_CB(skb)->inner_protocol = htons(0); } @@ -114,7 +121,8 @@ static inline void ovs_skb_init_inner_protocol(struct sk_buff *skb) { */ } -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) static inline void ovs_skb_set_inner_protocol(struct sk_buff *skb, __be16 ethertype) { @@ -134,10 +142,12 @@ static inline __be16 ovs_skb_get_inner_protocol(struct sk_buff *skb) } #endif /* 3.11 */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) ||\ + !defined(HAVE_GRE_HANDLE_OFFLOADS) #define ip_local_out rpl_ip_local_out int rpl_ip_local_out(struct sk_buff *skb); +#define skb_inner_mac_offset rpl_skb_inner_mac_offset static inline int skb_inner_mac_offset(const struct sk_buff *skb) { return skb_inner_mac_header(skb) - skb->data; diff --git a/datapath/linux/compat/include/linux/netdevice.h b/datapath/linux/compat/include/linux/netdevice.h index 0fb2144..a2f7eb9 100644 --- a/datapath/linux/compat/include/linux/netdevice.h +++ b/datapath/linux/compat/include/linux/netdevice.h @@ -88,7 +88,8 @@ static inline struct net_device *dev_get_by_index_rcu(struct net *net, int ifind typedef u32 netdev_features_t; #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) #define OVS_USE_COMPAT_GSO_SEGMENTATION #endif @@ -112,18 +113,15 @@ struct sk_buff *rpl_skb_gso_segment(struct sk_buff *skb, netdev_features_t featu netdev_features_t rpl_netif_skb_features(struct sk_buff *skb); #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) -static inline int rpl_netif_needs_gso(struct net_device *dev, - struct sk_buff *skb, int features) +#ifdef HAVE_NETIF_NEEDS_GSO_NETDEV +#define netif_needs_gso rpl_netif_needs_gso +static inline bool netif_needs_gso(struct sk_buff *skb, + netdev_features_t features) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) return skb_is_gso(skb) && (!skb_gso_ok(skb, features) || - unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); -#else - return netif_needs_gso(skb, features); -#endif + unlikely((skb->ip_summed != CHECKSUM_PARTIAL) && + (skb->ip_summed != CHECKSUM_UNNECESSARY))); } -#define netif_needs_gso rpl_netif_needs_gso #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) diff --git a/datapath/linux/compat/include/net/geneve.h b/datapath/linux/compat/include/net/geneve.h index 4f250c2..116ebc7 100644 --- a/datapath/linux/compat/include/net/geneve.h +++ b/datapath/linux/compat/include/net/geneve.h @@ -3,7 +3,8 @@ #include <linux/version.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) && \ + defined(HAVE_GRE_HANDLE_OFFLOADS) #include_next <net/geneve.h> #else diff --git a/datapath/linux/compat/include/net/gre.h b/datapath/linux/compat/include/net/gre.h index 6e0df0f..040fd11 100644 --- a/datapath/linux/compat/include/net/gre.h +++ b/datapath/linux/compat/include/net/gre.h @@ -28,13 +28,17 @@ int rpl_gre_cisco_register(struct gre_cisco_protocol *proto); #define gre_cisco_unregister rpl_gre_cisco_unregister int rpl_gre_cisco_unregister(struct gre_cisco_protocol *proto); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) +#ifndef HAVE_GRE_HANDLE_OFFLOADS +#ifndef GRE_HEADER_SECTION struct gre_base_hdr { __be16 flags; __be16 protocol; }; #define GRE_HEADER_SECTION 4 +#endif + +#define gre_flags_to_tnl_flags rpl_gre_flags_to_tnl_flags static inline __be16 gre_flags_to_tnl_flags(__be16 flags) { __be16 tflags = 0; @@ -57,6 +61,7 @@ static inline __be16 gre_flags_to_tnl_flags(__be16 flags) return tflags; } +#define tnl_flags_to_gre_flags rpl_tnl_flags_to_gre_flags static inline __be16 tnl_flags_to_gre_flags(__be16 tflags) { __be16 flags = 0; @@ -84,8 +89,7 @@ static inline __be16 tnl_flags_to_gre_flags(__be16 tflags) #define gre_handle_offloads rpl_gre_handle_offloads struct sk_buff *rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0) - +#ifndef HAVE_GRE_HANDLE_OFFLOADS #define gre_build_header rpl_gre_build_header void rpl_gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, int hdr_len); diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h index 3ed6f91..0ca086f 100644 --- a/datapath/linux/compat/include/net/ip_tunnels.h +++ b/datapath/linux/compat/include/net/ip_tunnels.h @@ -7,7 +7,8 @@ #include_next <net/ip_tunnels.h> #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) #include <linux/if_tunnel.h> #include <linux/netdevice.h> diff --git a/datapath/linux/compat/include/net/udp_tunnel.h b/datapath/linux/compat/include/net/udp_tunnel.h index d334746..21d05ff 100644 --- a/datapath/linux/compat/include/net/udp_tunnel.h +++ b/datapath/linux/compat/include/net/udp_tunnel.h @@ -4,7 +4,9 @@ #include <linux/version.h> #include <linux/kconfig.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) && \ + defined(HAVE_GRE_HANDLE_OFFLOADS) + #include_next <net/udp_tunnel.h> static inline struct sk_buff * diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h index cafff79..1a85a17 100644 --- a/datapath/linux/compat/include/net/vxlan.h +++ b/datapath/linux/compat/include/net/vxlan.h @@ -8,7 +8,9 @@ #include <linux/version.h> -#ifdef HAVE_VXLAN_METADATA +/* gre_handle_offload is not defined on kernel with netdev-vport support + * Use this as way to switch between compatibility implementations. */ +#if defined(HAVE_VXLAN_METADATA) && defined(HAVE_GRE_HANDLE_OFFLOADS) #define USE_UPSTREAM_VXLAN #include_next <net/vxlan.h> diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c index 8ff7cd7..05c8564 100644 --- a/datapath/linux/compat/ip_tunnels_core.c +++ b/datapath/linux/compat/ip_tunnels_core.c @@ -35,7 +35,8 @@ #include "compat.h" #include "gso.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) 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) @@ -71,6 +72,9 @@ int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, #ifdef HAVE_IP_SELECT_IDENT_USING_DST_ENTRY __ip_select_ident(iph, &rt_dst(rt), (skb_shinfo(skb)->gso_segs ?: 1) - 1); +#elif defined(HAVE_IP_SELECT_IDENT_USING_NET) + __ip_select_ident(dev_net(rt->dst.dev), iph, + skb_shinfo(skb)->gso_segs ?: 1); #else __ip_select_ident(iph, skb_shinfo(skb)->gso_segs ?: 1); #endif @@ -84,7 +88,7 @@ EXPORT_SYMBOL_GPL(rpl_iptunnel_xmit); struct sk_buff *ovs_iptunnel_handle_offloads(struct sk_buff *skb, bool csum_help, int gso_type_mask, - void (*fix_segment)(struct sk_buff *)) + void (*fix_segment)(struct sk_buff *)) { int err; diff --git a/datapath/linux/compat/udp_tunnel.c b/datapath/linux/compat/udp_tunnel.c index b6c5bad..11cb22a 100644 --- a/datapath/linux/compat/udp_tunnel.c +++ b/datapath/linux/compat/udp_tunnel.c @@ -1,6 +1,7 @@ #include <linux/version.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) || \ + !defined(HAVE_GRE_HANDLE_OFFLOADS) #include <linux/module.h> #include <linux/errno.h> @@ -23,12 +24,10 @@ int rpl_udp_sock_create(struct net *net, struct udp_port_cfg *cfg, if (cfg->family == AF_INET6) { struct sockaddr_in6 udp6_addr; - err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock); + err = ovs_sock_create_kern(net, AF_INET6, SOCK_DGRAM, 0, &sock); if (err < 0) goto error; - sk_change_net(sock->sk, net); - udp6_addr.sin6_family = AF_INET6; memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, sizeof(udp6_addr.sin6_addr)); @@ -54,12 +53,10 @@ int rpl_udp_sock_create(struct net *net, struct udp_port_cfg *cfg, if (cfg->family == AF_INET) { struct sockaddr_in udp_addr; - err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock); + err = ovs_sock_create_kern(net, AF_INET, SOCK_DGRAM, 0, &sock); if (err < 0) goto error; - sk_change_net(sock->sk, net); - udp_addr.sin_family = AF_INET; udp_addr.sin_addr = cfg->local_ip; udp_addr.sin_port = cfg->local_udp_port; -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev