summaryrefslogtreecommitdiff
path: root/datapath
diff options
context:
space:
mode:
authorPravin Shelar <pshelar@nicira.com>2014-02-07 10:46:53 -0800
committerPravin B Shelar <pshelar@nicira.com>2014-03-07 04:00:24 -0800
commit29c71cfa0c137abd49bfa346c1b871d2543071ae (patch)
tree99ec784a684f1426ee4aac9589e6b2d3c054af36 /datapath
parent72310b041cfa7d8e2ee5fb585348223ac7c22497 (diff)
downloadopenvswitch-29c71cfa0c137abd49bfa346c1b871d2543071ae.tar.gz
datapath: Add support for Linux 3.12
Bump kernel support for datapath module to include 3.12. Make use of native ip-tunnel API for Kernel >= 3.12. Based on patch from James Page. Signed-off-by: James Page <james.page@ubuntu.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Reviewed-by: Kyle Mestery <mestery@noironetworks.com>
Diffstat (limited to 'datapath')
-rw-r--r--datapath/flow_netlink.c1
-rw-r--r--datapath/linux/compat/gre.c5
-rw-r--r--datapath/linux/compat/gso.c4
-rw-r--r--datapath/linux/compat/gso.h5
-rw-r--r--datapath/linux/compat/include/net/gre.h4
-rw-r--r--datapath/linux/compat/include/net/ip_tunnels.h9
-rw-r--r--datapath/linux/compat/include/net/vxlan.h8
-rw-r--r--datapath/linux/compat/ip_tunnels_core.c7
-rw-r--r--datapath/linux/compat/vxlan.c9
-rw-r--r--datapath/vport-gre.c2
-rw-r--r--datapath/vport-lisp.c28
-rw-r--r--datapath/vport-vxlan.c2
12 files changed, 74 insertions, 10 deletions
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 40751cb54..4c68a68b9 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -43,6 +43,7 @@
#include <linux/icmpv6.h>
#include <linux/rculist.h>
#include <net/ip.h>
+#include <net/ip_tunnels.h>
#include <net/ipv6.h>
#include <net/ndisc.h>
diff --git a/datapath/linux/compat/gre.c b/datapath/linux/compat/gre.c
index 58b1e73e9..07b270a02 100644
--- a/datapath/linux/compat/gre.c
+++ b/datapath/linux/compat/gre.c
@@ -16,6 +16,9 @@
* 02110-1301, USA
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#include <linux/kconfig.h>
#if IS_ENABLED(CONFIG_NET_IPGRE_DEMUX)
@@ -340,3 +343,5 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
}
#endif /* CONFIG_NET_IPGRE_DEMUX */
+
+#endif /* 3.12 */
diff --git a/datapath/linux/compat/gso.c b/datapath/linux/compat/gso.c
index 32f906c82..9ded17c63 100644
--- a/datapath/linux/compat/gso.c
+++ b/datapath/linux/compat/gso.c
@@ -16,6 +16,9 @@
* 02110-1301, USA
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#include <linux/module.h>
#include <linux/if.h>
#include <linux/if_tunnel.h>
@@ -229,3 +232,4 @@ int rpl_ip_local_out(struct sk_buff *skb)
}
return ret;
}
+#endif /* 3.12 */
diff --git a/datapath/linux/compat/gso.h b/datapath/linux/compat/gso.h
index 44fd213f0..b83a4c3c8 100644
--- a/datapath/linux/compat/gso.h
+++ b/datapath/linux/compat/gso.h
@@ -1,6 +1,9 @@
#ifndef __LINUX_GSO_WRAPPER_H
#define __LINUX_GSO_WRAPPER_H
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#include <linux/skbuff.h>
#include <net/protocol.h>
@@ -69,4 +72,6 @@ static inline void skb_reset_inner_headers(struct sk_buff *skb)
#define ip_local_out rpl_ip_local_out
int ip_local_out(struct sk_buff *skb);
+
+#endif /* 3.12 */
#endif
diff --git a/datapath/linux/compat/include/net/gre.h b/datapath/linux/compat/include/net/gre.h
index a6f29c45c..6268655fc 100644
--- a/datapath/linux/compat/include/net/gre.h
+++ b/datapath/linux/compat/include/net/gre.h
@@ -4,6 +4,7 @@
#include <linux/skbuff.h>
#include <net/ip_tunnels.h>
+#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || \
defined(HAVE_GRE_CISCO_REGISTER)
#include_next <net/gre.h>
@@ -78,6 +79,8 @@ static inline __be16 tnl_flags_to_gre_flags(__be16 tflags)
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) */
#endif /* HAVE_GRE_CISCO_REGISTER */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#define gre_build_header rpl_gre_build_header
void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
int hdr_len);
@@ -98,5 +101,6 @@ static inline int ip_gre_calc_hlen(__be16 o_flags)
addend += 4;
return addend;
}
+#endif
#endif
diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h
index a786aa99d..e59f9f356 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -1,6 +1,11 @@
#ifndef __NET_IP_TUNNELS_WRAPPER_H
#define __NET_IP_TUNNELS_WRAPPER_H 1
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)
+#include_next <net/ip_tunnels.h>
+#else
+
#include <linux/if_tunnel.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
@@ -34,7 +39,9 @@ struct tnl_ptk_info {
int iptunnel_xmit(struct rtable *rt,
struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
- __u8 tos, __u8 ttl, __be16 df);
+ __u8 tos, __u8 ttl, __be16 df, bool xnet);
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
+
+#endif
#endif /* __NET_IP_TUNNELS_H */
diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h
index 3ac816b51..414a49703 100644
--- a/datapath/linux/compat/include/net/vxlan.h
+++ b/datapath/linux/compat/include/net/vxlan.h
@@ -5,6 +5,11 @@
#include <linux/netdevice.h>
#include <linux/udp.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)
+#include_next <net/vxlan.h>
+#else
+
struct vxlan_sock;
typedef void (vxlan_rcv_t)(struct vxlan_sock *vs, struct sk_buff *skb, __be32 key);
@@ -20,7 +25,7 @@ struct vxlan_sock {
struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
vxlan_rcv_t *rcv, void *data,
- bool no_share);
+ bool no_share, bool ipv6);
void vxlan_sock_release(struct vxlan_sock *vs);
@@ -31,4 +36,5 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb);
+#endif /* 3.12 */
#endif
diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c
index 66d5e0252..779075d1e 100644
--- a/datapath/linux/compat/ip_tunnels_core.c
+++ b/datapath/linux/compat/ip_tunnels_core.c
@@ -16,6 +16,9 @@
* 02110-1301, USA
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
@@ -37,7 +40,7 @@
int iptunnel_xmit(struct rtable *rt,
struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto,
- __u8 tos, __u8 ttl, __be16 df)
+ __u8 tos, __u8 ttl, __be16 df, bool xnet)
{
int pkt_len = skb->len;
struct iphdr *iph;
@@ -108,3 +111,5 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
skb->pkt_type = PACKET_HOST;
return 0;
}
+
+#endif /* 3.12 */
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index 64877e069..848a3952b 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -18,6 +18,9 @@
* This code is derived from kernel vxlan module.
*/
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
@@ -223,7 +226,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
if (err)
return err;
- return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df);
+ return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, false);
}
static void rcu_free_vs(struct rcu_head *rcu)
@@ -298,7 +301,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
vxlan_rcv_t *rcv, void *data,
- bool no_share)
+ bool no_share, bool ipv6)
{
return vxlan_socket_create(net, port, rcv, data);
}
@@ -310,3 +313,5 @@ void vxlan_sock_release(struct vxlan_sock *vs)
queue_work(system_wq, &vs->del_work);
}
+
+#endif /* 3.12 */
diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c
index 8737b63d7..86137565a 100644
--- a/datapath/vport-gre.c
+++ b/datapath/vport-gre.c
@@ -178,7 +178,7 @@ static int __send(struct vport *vport, struct sk_buff *skb,
return iptunnel_xmit(rt, skb, saddr,
OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE,
OVS_CB(skb)->tun_key->ipv4_tos,
- OVS_CB(skb)->tun_key->ipv4_ttl, df);
+ OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
err_free_rt:
ip_rt_put(rt);
error:
diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c
index c2698ae9d..e33cffea2 100644
--- a/datapath/vport-lisp.c
+++ b/datapath/vport-lisp.c
@@ -381,6 +381,8 @@ error:
return ERR_PTR(err);
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0)
+
static void lisp_fix_segment(struct sk_buff *skb)
{
struct udphdr *udph = udp_hdr(skb);
@@ -388,13 +390,30 @@ static void lisp_fix_segment(struct sk_buff *skb)
udph->len = htons(skb->len - skb_transport_offset(skb));
}
-static void handle_offloads(struct sk_buff *skb)
+static int handle_offloads(struct sk_buff *skb)
{
if (skb_is_gso(skb))
OVS_GSO_CB(skb)->fix_segment = lisp_fix_segment;
else if (skb->ip_summed != CHECKSUM_PARTIAL)
skb->ip_summed = CHECKSUM_NONE;
+ return 0;
}
+#else
+static int handle_offloads(struct sk_buff *skb)
+{
+ if (skb_is_gso(skb)) {
+ int err = skb_unclone(skb, GFP_ATOMIC);
+ if (unlikely(err))
+ return err;
+
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
+ } else if (skb->ip_summed != CHECKSUM_PARTIAL)
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb->encapsulation = 1;
+ return 0;
+}
+#endif
static int lisp_send(struct vport *vport, struct sk_buff *skb)
{
@@ -455,7 +474,10 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb)
lisp_build_header(vport, skb);
/* Offloading */
- handle_offloads(skb);
+ err = handle_offloads(skb);
+ if (err)
+ goto err_free_rt;
+
skb->local_df = 1;
df = OVS_CB(skb)->tun_key->tun_flags &
@@ -463,7 +485,7 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb)
sent_len = iptunnel_xmit(rt, skb,
saddr, OVS_CB(skb)->tun_key->ipv4_dst,
IPPROTO_UDP, OVS_CB(skb)->tun_key->ipv4_tos,
- OVS_CB(skb)->tun_key->ipv4_ttl, df);
+ OVS_CB(skb)->tun_key->ipv4_ttl, df, false);
return sent_len > 0 ? sent_len + network_offset : sent_len;
diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
index ab2b6f73f..d26478535 100644
--- a/datapath/vport-vxlan.c
+++ b/datapath/vport-vxlan.c
@@ -124,7 +124,7 @@ static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
vxlan_port = vxlan_vport(vport);
strncpy(vxlan_port->name, parms->name, IFNAMSIZ);
- vs = vxlan_sock_add(net, htons(dst_port), vxlan_rcv, vport, true);
+ vs = vxlan_sock_add(net, htons(dst_port), vxlan_rcv, vport, true, false);
if (IS_ERR(vs)) {
ovs_vport_free(vport);
return (void *)vs;