datapath: Add support for 4.1 kernel.
authorJoe Stringer <joestringer@nicira.com>
Wed, 9 Sep 2015 21:34:48 +0000 (14:34 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Fri, 18 Sep 2015 20:27:24 +0000 (13:27 -0700)
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
15 files changed:
.travis.yml
FAQ.md
acinclude.m4
datapath/datapath.c
datapath/datapath.h
datapath/flow.c
datapath/linux/compat/geneve.c
datapath/linux/compat/include/net/net_namespace.h
datapath/linux/compat/include/net/udp_tunnel.h
datapath/linux/compat/include/net/vxlan.h
datapath/linux/compat/stt.c
datapath/linux/compat/udp_tunnel.c
datapath/linux/compat/vxlan.c
datapath/vport-lisp.c
datapath/vport-vxlan.c

index d14f786..f4b9188 100644 (file)
@@ -12,7 +12,8 @@ env:
   - TESTSUITE=1 KERNEL=3.18.1
   - TESTSUITE=1 OPTS="--enable-shared"
   - BUILD_ENV="-m32" OPTS="--disable-ssl"
   - TESTSUITE=1 KERNEL=3.18.1
   - TESTSUITE=1 OPTS="--enable-shared"
   - BUILD_ENV="-m32" OPTS="--disable-ssl"
-  - KERNEL=4.0.2
+  - KERNEL=4.1.6
+  - KERNEL=4.0.9
   - KERNEL=3.17.7 DPDK=1
   - KERNEL=3.17.7 DPDK=1 OPTS="--enable-shared"
   - KERNEL=3.17.7
   - KERNEL=3.17.7 DPDK=1
   - KERNEL=3.17.7 DPDK=1 OPTS="--enable-shared"
   - KERNEL=3.17.7
diff --git a/FAQ.md b/FAQ.md
index b9ba18b..7ade627 100644 (file)
--- a/FAQ.md
+++ b/FAQ.md
@@ -156,6 +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.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.1
 
    Open vSwitch userspace should also work with the Linux kernel module
    built into Linux 3.3 and later.
 
    Open vSwitch userspace should also work with the Linux kernel module
    built into Linux 3.3 and later.
index 47d9318..beb320b 100644 (file)
@@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [
     AC_MSG_RESULT([$kversion])
 
     if test "$version" -ge 4; then
     AC_MSG_RESULT([$kversion])
 
     if test "$version" -ge 4; then
-       if test "$version" = 4 && test "$patchlevel" -le 0; then
+       if test "$version" = 4 && test "$patchlevel" -le 1; then
           : # Linux 4.x
        else
           : # Linux 4.x
        else
-          AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.0.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.1.x is not supported (please refer to the FAQ for advice)])
        fi
     elif test "$version" = 3; then
        : # Linux 3.x
        fi
     elif test "$version" = 3; then
        : # Linux 3.x
index 73c0b4a..1115649 100644 (file)
@@ -205,7 +205,6 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
 
        ovs_flow_tbl_destroy(&dp->table);
        free_percpu(dp->stats_percpu);
 
        ovs_flow_tbl_destroy(&dp->table);
        free_percpu(dp->stats_percpu);
-       release_net(ovs_dp_get_net(dp));
        kfree(dp->ports);
        kfree(dp);
 }
        kfree(dp->ports);
        kfree(dp);
 }
@@ -1527,7 +1526,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
        if (dp == NULL)
                goto err_free_reply;
 
        if (dp == NULL)
                goto err_free_reply;
 
-       ovs_dp_set_net(dp, hold_net(sock_net(skb->sk)));
+       ovs_dp_set_net(dp, sock_net(skb->sk));
 
        /* Allocate table. */
        err = ovs_flow_tbl_init(&dp->table);
 
        /* Allocate table. */
        err = ovs_flow_tbl_init(&dp->table);
@@ -1601,7 +1600,6 @@ err_destroy_percpu:
 err_destroy_table:
        ovs_flow_tbl_destroy(&dp->table);
 err_free_dp:
 err_destroy_table:
        ovs_flow_tbl_destroy(&dp->table);
 err_free_dp:
-       release_net(ovs_dp_get_net(dp));
        kfree(dp);
 err_free_reply:
        kfree_skb(reply);
        kfree(dp);
 err_free_reply:
        kfree_skb(reply);
index 526ddad..aca9407 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/u64_stats_sync.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/u64_stats_sync.h>
+#include <net/net_namespace.h>
 
 #include "compat.h"
 #include "flow.h"
 
 #include "compat.h"
 #include "flow.h"
@@ -86,10 +87,8 @@ struct datapath {
        /* Stats. */
        struct dp_stats_percpu __percpu *stats_percpu;
 
        /* Stats. */
        struct dp_stats_percpu __percpu *stats_percpu;
 
-#ifdef CONFIG_NET_NS
        /* Network namespace ref. */
        /* Network namespace ref. */
-       struct net *net;
-#endif
+       possible_net_t net;
 
        u32 user_features;
 };
 
        u32 user_features;
 };
@@ -156,12 +155,12 @@ int lockdep_ovsl_is_held(void);
 
 static inline struct net *ovs_dp_get_net(const struct datapath *dp)
 {
 
 static inline struct net *ovs_dp_get_net(const struct datapath *dp)
 {
-       return read_pnet(&dp->net);
+       return rpl_read_pnet(&dp->net);
 }
 
 static inline void ovs_dp_set_net(struct datapath *dp, struct net *net)
 {
 }
 
 static inline void ovs_dp_set_net(struct datapath *dp, struct net *net)
 {
-       write_pnet(&dp->net, net);
+       rpl_write_pnet(&dp->net, net);
 }
 
 struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no);
 }
 
 struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no);
index a7a2063..8ef60d1 100644 (file)
@@ -101,7 +101,9 @@ void ovs_flow_stats_update(struct sw_flow *flow, __be16 tcp_flags,
 
                                new_stats =
                                        kmem_cache_alloc_node(flow_stats_cache,
 
                                new_stats =
                                        kmem_cache_alloc_node(flow_stats_cache,
-                                                             GFP_THISNODE |
+                                                              GFP_NOWAIT |
+                                                              __GFP_THISNODE |
+                                                              __GFP_NOWARN |
                                                              __GFP_NOMEMALLOC,
                                                              node);
                                if (likely(new_stats)) {
                                                              __GFP_NOMEMALLOC,
                                                              node);
                                if (likely(new_stats)) {
index 78d3395..8e80180 100644 (file)
@@ -117,7 +117,7 @@ int rpl_geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
 
        ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
 
        ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, skb, src, dst,
+       return udp_tunnel_xmit_skb(rt, gs->sock->sk, skb, src, dst,
                                   tos, ttl, df, src_port, dst_port, xnet,
                                   !csum);
 }
                                   tos, ttl, df, src_port, dst_port, xnet,
                                   !csum);
 }
index b7dbfe3..edfa131 100644 (file)
@@ -51,4 +51,31 @@ static void rpl_unregister_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_p
 #define DEFINE_COMPAT_PNET_REG_FUNC(TYPE)
 #endif /* 2.6.33 */
 
 #define DEFINE_COMPAT_PNET_REG_FUNC(TYPE)
 #endif /* 2.6.33 */
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+typedef struct {
+#ifdef CONFIG_NET_NS
+       struct net *net;
+#endif
+} possible_net_t;
+
+static inline void rpl_write_pnet(possible_net_t *pnet, struct net *net)
+{
+#ifdef CONFIG_NET_NS
+       pnet->net = net;
+#endif
+}
+
+static inline struct net *rpl_read_pnet(const possible_net_t *pnet)
+{
+#ifdef CONFIG_NET_NS
+       return pnet->net;
+#else
+       return &init_net;
+#endif
+}
+#else /* Linux >= 4.1 */
+#define rpl_read_pnet read_pnet
+#define rpl_write_pnet write_pnet
+#endif /* Linux >= 4.1 */
+
 #endif /* net/net_namespace.h wrapper */
 #endif /* net/net_namespace.h wrapper */
index 81cb3df..d334746 100644 (file)
@@ -19,6 +19,18 @@ rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
 }
 #define udp_tunnel_handle_offloads rpl_udp_tunnel_handle_offloads
 
 }
 #define udp_tunnel_handle_offloads rpl_udp_tunnel_handle_offloads
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
+static inline int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
+                                         struct sock *sk, struct sk_buff *skb,
+                                         __be32 src, __be32 dst, __u8 tos, __u8 ttl,
+                                         __be16 df, __be16 src_port, __be16 dst_port,
+                                         bool xnet, bool nocheck)
+{
+       return udp_tunnel_xmit_skb(rt, skb, src, dst, tos, ttl, df, src_port,
+                                  dst_port, xnet, nocheck);
+}
+#define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
+#endif
 #else
 
 #include <net/ip_tunnels.h>
 #else
 
 #include <net/ip_tunnels.h>
@@ -71,7 +83,8 @@ void rpl_setup_udp_tunnel_sock(struct net *net, struct socket *sock,
 
 /* Transmit the skb using UDP encapsulation. */
 #define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
 
 /* Transmit the skb using UDP encapsulation. */
 #define udp_tunnel_xmit_skb rpl_udp_tunnel_xmit_skb
-int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sk_buff *skb,
+int rpl_udp_tunnel_xmit_skb(struct rtable *rt,
+                           struct sock *sk, struct sk_buff *skb,
                            __be32 src, __be32 dst, __u8 tos, __u8 ttl,
                            __be16 df, __be16 src_port, __be16 dst_port,
                            bool xnet, bool nocheck);
                            __be32 src, __be32 dst, __u8 tos, __u8 ttl,
                            __be16 df, __be16 src_port, __be16 dst_port,
                            bool xnet, bool nocheck);
index 0d60c18..cafff79 100644 (file)
@@ -88,10 +88,9 @@ struct vxlanhdr_gbp {
 #endif
 
 #ifdef USE_UPSTREAM_VXLAN
 #endif
 
 #ifdef USE_UPSTREAM_VXLAN
-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,
+static inline int rpl_vxlan_xmit_skb(struct rtable *rt, struct sock *sk,
+                  struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
+                  __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
                   struct vxlan_metadata *md, bool xnet, u32 vxflags)
 {
        if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
                   struct vxlan_metadata *md, bool xnet, u32 vxflags)
 {
        if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
@@ -99,7 +98,11 @@ static inline int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
                return -ENOSYS;
        }
 
                return -ENOSYS;
        }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)
        return vxlan_xmit_skb(rt, skb, src, dst, tos, ttl, df,
        return vxlan_xmit_skb(rt, skb, src, dst, tos, ttl, df,
+#else
+       return vxlan_xmit_skb(rt, sk, skb, src, dst, tos, ttl, df,
+#endif
                              src_port, dst_port, md, xnet, vxflags);
 }
 
                              src_port, dst_port, md, xnet, vxflags);
 }
 
@@ -138,8 +141,7 @@ struct vxlan_sock *rpl_vxlan_sock_add(struct net *net, __be16 port,
 void rpl_vxlan_sock_release(struct vxlan_sock *vs);
 
 #define vxlan_xmit_skb rpl_vxlan_xmit_skb
 void rpl_vxlan_sock_release(struct vxlan_sock *vs);
 
 #define vxlan_xmit_skb rpl_vxlan_xmit_skb
-int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
-                      struct rtable *rt, struct sk_buff *skb,
+int rpl_vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                       __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                       __be16 src_port, __be16 dst_port,
                       struct vxlan_metadata *md, bool xnet, u32 vxflags);
                       __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                       __be16 src_port, __be16 dst_port,
                       struct vxlan_metadata *md, bool xnet, u32 vxflags);
index dd21753..e27cedf 100644 (file)
@@ -1320,16 +1320,18 @@ static void clean_percpu(struct work_struct *work)
 }
 
 #ifdef HAVE_NF_HOOKFN_ARG_OPS
 }
 
 #ifdef HAVE_NF_HOOKFN_ARG_OPS
-#define FIRST_PARAM const struct nf_hook_ops *ops,
+#define FIRST_PARAM const struct nf_hook_ops *ops
 #else
 #else
-#define FIRST_PARAM unsigned int hooknum,
+#define FIRST_PARAM unsigned int hooknum
 #endif
 
 #endif
 
-static unsigned int nf_ip_hook(FIRST_PARAM
-                              struct sk_buff *skb,
-                              const struct net_device *in,
-                              const struct net_device *out,
-                              int (*okfn)(struct sk_buff *))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
+#define LAST_PARAM const struct nf_hook_state *state
+#else
+#define LAST_PARAM const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)
+#endif
+
+static unsigned int nf_ip_hook(FIRST_PARAM, struct sk_buff *skb, LAST_PARAM)
 {
        struct stt_sock *stt_sock;
        int ip_hdr_len;
 {
        struct stt_sock *stt_sock;
        int ip_hdr_len;
index c84113b..680fd83 100644 (file)
@@ -142,10 +142,10 @@ void ovs_udp_csum_gso(struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(ovs_udp_csum_gso);
 
 }
 EXPORT_SYMBOL_GPL(ovs_udp_csum_gso);
 
-int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sk_buff *skb,
-                           __be32 src, __be32 dst, __u8 tos, __u8 ttl,
-                           __be16 df, __be16 src_port, __be16 dst_port,
-                           bool xnet, bool nocheck)
+int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk,
+                           struct sk_buff *skb, __be32 src, __be32 dst,
+                           __u8 tos, __u8 ttl, __be16 df, __be16 src_port,
+                           __be16 dst_port, bool xnet, bool nocheck)
 {
        struct udphdr *uh;
 
 {
        struct udphdr *uh;
 
@@ -159,7 +159,7 @@ int rpl_udp_tunnel_xmit_skb(struct rtable *rt, struct sk_buff *skb,
 
        udp_set_csum(nocheck, skb, src, dst, skb->len);
 
 
        udp_set_csum(nocheck, skb, src, dst, skb->len);
 
-       return iptunnel_xmit(skb->sk, rt, skb, src, dst, IPPROTO_UDP,
+       return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
                             tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(rpl_udp_tunnel_xmit_skb);
                             tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(rpl_udp_tunnel_xmit_skb);
index 129f171..fd454ae 100644 (file)
@@ -180,8 +180,7 @@ static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, u32 vxflags,
        gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
 }
 
        gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
 }
 
-int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
-                      struct rtable *rt, struct sk_buff *skb,
+int rpl_vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
                       __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                       __be16 src_port, __be16 dst_port,
                       struct vxlan_metadata *md, bool xnet, u32 vxflags)
                       __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
                       __be16 src_port, __be16 dst_port,
                       struct vxlan_metadata *md, bool xnet, u32 vxflags)
@@ -217,11 +216,11 @@ int rpl_vxlan_xmit_skb(struct vxlan_sock *vs,
        if (vxflags & VXLAN_F_GBP)
                vxlan_build_gbp_hdr(vxh, vxflags, md);
 
        if (vxflags & VXLAN_F_GBP)
                vxlan_build_gbp_hdr(vxh, vxflags, md);
 
-       vxlan_set_owner(vs->sock->sk, skb);
+       vxlan_set_owner(sk, skb);
 
        ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
 
        ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, skb, src, dst, tos,
+       return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
                                   ttl, df, src_port, dst_port, xnet,
                                   !udp_sum);
 }
                                   ttl, df, src_port, dst_port, xnet,
                                   !udp_sum);
 }
index 0024eb4..104a21d 100644 (file)
@@ -455,7 +455,8 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb)
        ovs_skb_set_inner_protocol(skb, skb->protocol);
 
        df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
        ovs_skb_set_inner_protocol(skb, skb->protocol);
 
        df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
-       sent_len = udp_tunnel_xmit_skb(rt, skb, saddr, tun_key->ipv4_dst,
+       sent_len = udp_tunnel_xmit_skb(rt, lisp_port->lisp_rcv_socket->sk, skb,
+                                      saddr, tun_key->ipv4_dst,
                                       tun_key->ipv4_tos, tun_key->ipv4_ttl,
                                       df, src_port, dst_port, false, true);
 
                                       tun_key->ipv4_tos, tun_key->ipv4_ttl,
                                       df, src_port, dst_port, false, true);
 
index eff7ca2..fc9f350 100644 (file)
@@ -260,7 +260,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
        vxflags = vxlan_port->exts |
                      (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
 
        vxflags = vxlan_port->exts |
                      (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
 
-       err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
+       err = vxlan_xmit_skb(rt, vxlan_port->vs->sock->sk, skb,
                             saddr, tun_key->ipv4_dst,
                             tun_key->ipv4_tos,
                             tun_key->ipv4_ttl, df,
                             saddr, tun_key->ipv4_dst,
                             tun_key->ipv4_tos,
                             tun_key->ipv4_ttl, df,