summaryrefslogtreecommitdiff
path: root/datapath
diff options
context:
space:
mode:
authorGreg Rose <gvrose8192@gmail.com>2018-05-31 14:10:10 -0700
committerBen Pfaff <blp@ovn.org>2018-05-31 18:58:30 -0700
commit436d36db628cd9cdb30e33e8718ab70f376bb9e4 (patch)
tree7b91a5d364cc2f20e244d1d5c7642af61a9a99f3 /datapath
parent6ba083c51e5f8d68f33d1b2c29c37c335465bc5c (diff)
downloadopenvswitch-436d36db628cd9cdb30e33e8718ab70f376bb9e4.tar.gz
compat: Fixups for newer kernels
A recent patch series added support for ERSPAN but left some problems remaining for kernel releases from 4.10 to 4.14. This patch addresses those problems. Of note is that the old cisco gre compat layer code is gone for good. Also, several compat defines in acinclude.m4 were looking for keys in .c source files - this does not work on distros without source code. A more reliable key was already defined so we use that instead. We have pared support for the Linux kernel releases in .travis.yml to reflect that 4.15 is no longer in the LTS list. With this patch the Out of Tree OVS datapath kernel modules can build on kernels up to 4.14.47. Support for kernels up to 4.16.x will be added later. Signed-off-by: Greg Rose <gvrose8192@gmail.com> Acked-by: William Tu <u9012063@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'datapath')
-rw-r--r--datapath/linux/compat/geneve.c15
-rw-r--r--datapath/linux/compat/gre.c149
-rw-r--r--datapath/linux/compat/include/linux/compiler-gcc.h5
-rw-r--r--datapath/linux/compat/include/net/dst_metadata.h2
-rw-r--r--datapath/linux/compat/include/net/erspan.h2
-rw-r--r--datapath/linux/compat/include/net/gre.h28
-rw-r--r--datapath/linux/compat/include/net/ip_tunnels.h18
-rw-r--r--datapath/linux/compat/ip6_gre.c46
-rw-r--r--datapath/linux/compat/ip6_tunnel.c19
-rw-r--r--datapath/linux/compat/ip_gre.c118
-rw-r--r--datapath/linux/compat/ip_tunnel.c2
-rw-r--r--datapath/linux/compat/ip_tunnels_core.c25
-rw-r--r--datapath/linux/compat/vxlan.c18
13 files changed, 161 insertions, 286 deletions
diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
index 0fcc6e51d..435a23fb7 100644
--- a/datapath/linux/compat/geneve.c
+++ b/datapath/linux/compat/geneve.c
@@ -1336,7 +1336,11 @@ static void geneve_setup(struct net_device *dev)
dev->netdev_ops = &geneve_netdev_ops;
dev->ethtool_ops = &geneve_ethtool_ops;
+#ifndef HAVE_NEEDS_FREE_NETDEV
dev->destructor = free_netdev;
+#else
+ dev->needs_free_netdev = true;
+#endif
SET_NETDEV_DEVTYPE(dev, &geneve_type);
@@ -1370,7 +1374,12 @@ static const struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
[IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
};
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int geneve_validate(struct nlattr *tb[], struct nlattr *data[])
+#endif
{
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -1489,8 +1498,14 @@ static int geneve_configure(struct net *net, struct net_device *dev,
return 0;
}
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int geneve_newlink(struct net *net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int geneve_newlink(struct net *net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
+#endif
{
__be16 dst_port = htons(GENEVE_UDP_PORT);
__u8 ttl = 0, tos = 0;
diff --git a/datapath/linux/compat/gre.c b/datapath/linux/compat/gre.c
index b45f8b459..7f2b54556 100644
--- a/datapath/linux/compat/gre.c
+++ b/datapath/linux/compat/gre.c
@@ -154,155 +154,6 @@ static int rpl_ip_gre_calc_hlen(__be16 o_flags)
return addend;
}
-#ifndef HAVE_GRE_HANDLE_OFFLOADS
-#ifndef HAVE_GRE_CISCO_REGISTER
-
-#ifdef HAVE_DEMUX_PARSE_GRE_HEADER
-static __sum16 check_checksum(struct sk_buff *skb)
-{
- __sum16 csum = 0;
-
- switch (skb->ip_summed) {
- case CHECKSUM_COMPLETE:
- csum = csum_fold(skb->csum);
-
- if (!csum)
- break;
- /* Fall through. */
-
- case CHECKSUM_NONE:
- skb->csum = 0;
- csum = __skb_checksum_complete(skb);
- skb->ip_summed = CHECKSUM_COMPLETE;
- break;
- }
-
- return csum;
-}
-
-static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
- bool *csum_err)
-{
- unsigned int ip_hlen = ip_hdrlen(skb);
- struct gre_base_hdr *greh;
- __be32 *options;
- int hdr_len;
-
- if (unlikely(!pskb_may_pull(skb, sizeof(struct gre_base_hdr))))
- return -EINVAL;
-
- greh = (struct gre_base_hdr *)(skb_network_header(skb) + ip_hlen);
- if (unlikely(greh->flags & (GRE_VERSION | GRE_ROUTING)))
- return -EINVAL;
-
- tpi->flags = gre_flags_to_tnl_flags(greh->flags);
- hdr_len = ip_gre_calc_hlen(tpi->flags);
- tpi->hdr_len = hdr_len;
- tpi->proto = greh->protocol;
-
- if (!pskb_may_pull(skb, hdr_len))
- return -EINVAL;
-
- options = (__be32 *)(greh + 1);
- if (greh->flags & GRE_CSUM) {
- if (check_checksum(skb)) {
- *csum_err = true;
- return -EINVAL;
- }
- options++;
- }
-
- if (greh->flags & GRE_KEY) {
- tpi->key = *options;
- options++;
- } else
- tpi->key = 0;
-
- if (unlikely(greh->flags & GRE_SEQ)) {
- tpi->seq = *options;
- options++;
- } else
- tpi->seq = 0;
-
- /* WCCP version 1 and 2 protocol decoding.
- * - Change protocol to IP
- * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
- */
- if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
- tpi->proto = htons(ETH_P_IP);
- if ((*(u8 *)options & 0xF0) != 0x40) {
- hdr_len += 4;
- if (!pskb_may_pull(skb, hdr_len))
- return -EINVAL;
- }
- }
-
- return iptunnel_pull_header(skb, hdr_len, tpi->proto, false);
-}
-
-static struct gre_cisco_protocol __rcu *gre_cisco_proto;
-static int gre_cisco_rcv(struct sk_buff *skb)
-{
- struct gre_cisco_protocol *proto;
- struct tnl_ptk_info tpi;
- bool csum_err = false;
-
- rcu_read_lock();
- proto = rcu_dereference(gre_cisco_proto);
- if (!proto)
- goto drop;
-
- if (parse_gre_header(skb, &tpi, &csum_err) < 0)
- goto drop;
- proto->handler(skb, &tpi);
- rcu_read_unlock();
- return 0;
-
-drop:
- rcu_read_unlock();
- kfree_skb(skb);
- return 0;
-}
-
-static const struct gre_protocol ipgre_protocol = {
- .handler = gre_cisco_rcv,
-};
-
-int rpl_gre_cisco_register(struct gre_cisco_protocol *newp)
-{
- int err;
-
- err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
- if (err) {
- pr_warn("%s: cannot register gre_cisco protocol handler\n", __func__);
- return err;
- }
-
-
- return (cmpxchg((struct gre_cisco_protocol **)&gre_cisco_proto, NULL, newp) == NULL) ?
- 0 : -EBUSY;
-}
-EXPORT_SYMBOL_GPL(rpl_gre_cisco_register);
-
-int rpl_gre_cisco_unregister(struct gre_cisco_protocol *proto)
-{
- int ret;
- ret = (cmpxchg((struct gre_cisco_protocol **)&gre_cisco_proto, proto, NULL) == proto) ?
- 0 : -EINVAL;
-
- if (ret)
- return ret;
-
- synchronize_net();
- ret = gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
- return ret;
-}
-EXPORT_SYMBOL_GPL(rpl_gre_cisco_unregister);
-
-#endif /* HAVE_DEMUX_PARSE_GRE_HEADER */
-#endif /* !HAVE_GRE_CISCO_REGISTER */
-#endif
-
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/linux/compiler-gcc.h b/datapath/linux/compat/include/linux/compiler-gcc.h
index bfcd5312a..39d2e0198 100644
--- a/datapath/linux/compat/include/linux/compiler-gcc.h
+++ b/datapath/linux/compat/include/linux/compiler-gcc.h
@@ -1,8 +1,13 @@
#ifndef __LINUX_COMPILER_H
+#if 0
+/* Disable this check - it no longer makes sense with so many backports
+ * due to spectre mitigation
+ */
#ifndef HAVE_LINUX_COMPILER_TYPES_H
#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
#endif
#endif
+#endif
#include_next <linux/compiler-gcc.h>
diff --git a/datapath/linux/compat/include/net/dst_metadata.h b/datapath/linux/compat/include/net/dst_metadata.h
index 93ea95439..e53a29ed2 100644
--- a/datapath/linux/compat/include/net/dst_metadata.h
+++ b/datapath/linux/compat/include/net/dst_metadata.h
@@ -116,13 +116,11 @@ static inline void ovs_ipv6_tun_rx_dst(struct metadata_dst *md_dst,
void ovs_ip_tunnel_rcv(struct net_device *dev, struct sk_buff *skb,
struct metadata_dst *tun_dst);
-#ifndef HAVE_METADATA_DST_ALLOC_WITH_METADATA_TYPE
static inline struct metadata_dst *
rpl_metadata_dst_alloc(u8 optslen, enum metadata_type type, gfp_t flags)
{
return metadata_dst_alloc(optslen, flags);
}
#define metadata_dst_alloc rpl_metadata_dst_alloc
-#endif
#endif /* __NET_DST_METADATA_WRAPPER_H */
diff --git a/datapath/linux/compat/include/net/erspan.h b/datapath/linux/compat/include/net/erspan.h
index 8adc89fca..9fdae97b5 100644
--- a/datapath/linux/compat/include/net/erspan.h
+++ b/datapath/linux/compat/include/net/erspan.h
@@ -1,4 +1,4 @@
-#ifndef HAVE_LINUX_ERSPAN_H
+#ifndef USE_UPSTREAM_TUNNEL
#ifndef __LINUX_ERSPAN_H
#define __LINUX_ERSPAN_H
diff --git a/datapath/linux/compat/include/net/gre.h b/datapath/linux/compat/include/net/gre.h
index 141ed2d9c..58fa97a8d 100644
--- a/datapath/linux/compat/include/net/gre.h
+++ b/datapath/linux/compat/include/net/gre.h
@@ -124,34 +124,6 @@ static inline __be16 rpl_gre_tnl_flags_to_gre_flags(__be16 tflags)
return flags;
}
-#ifndef HAVE_GRE_CISCO_REGISTER
-
-/* GRE demux not available, implement our own demux. */
-#define MAX_GRE_PROTO_PRIORITY 255
-
-struct gre_cisco_protocol {
- int (*handler)(struct sk_buff *skb, const struct tnl_ptk_info *tpi);
- int (*err_handler)(struct sk_buff *skb, u32 info,
- const struct tnl_ptk_info *tpi);
- u8 priority;
-};
-
-#define gre_cisco_register rpl_gre_cisco_register
-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);
-
-#ifndef GRE_HEADER_SECTION
-struct gre_base_hdr {
- __be16 flags;
- __be16 protocol;
-};
-#define GRE_HEADER_SECTION 4
-#endif
-
-#endif /* HAVE_GRE_CISCO_REGISTER */
-
#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 9b2621e0b..b1c383dc8 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -60,9 +60,15 @@ int ovs_iptunnel_handle_offloads(struct sk_buff *skb,
* rpl prefix is to make OVS build happy.
*/
#define iptunnel_handle_offloads rpl_iptunnel_handle_offloads
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
struct sk_buff *rpl_iptunnel_handle_offloads(struct sk_buff *skb,
bool csum_help,
int gso_type_mask);
+#else
+int rpl_iptunnel_handle_offloads(struct sk_buff *skb,
+ bool csum_help,
+ int gso_type_mask);
+#endif
#define iptunnel_xmit rpl_iptunnel_xmit
void rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
@@ -231,7 +237,6 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
#define ip_tunnel_collect_metadata() true
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
#undef TUNNEL_NOCACHE
#define TUNNEL_NOCACHE 0
@@ -248,7 +253,6 @@ ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
return true;
}
-#endif
#define ip_tunnel_dst rpl_ip_tunnel_dst
struct rpl_ip_tunnel_dst {
@@ -359,14 +363,14 @@ static inline int ovs_ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,
return ret;
}
-#ifndef HAVE_PCPU_SW_NETSTATS
#define ip_tunnel_get_stats64 rpl_ip_tunnel_get_stats64
-#else
-#define rpl_ip_tunnel_get_stats64 ip_tunnel_get_stats64
-#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
struct rtnl_link_stats64 *rpl_ip_tunnel_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *tot);
-
+#else
+void rpl_ip_tunnel_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *tot);
+#endif
#define ip_tunnel_get_dsfield rpl_ip_tunnel_get_dsfield
static inline u8 rpl_ip_tunnel_get_dsfield(const struct iphdr *iph,
const struct sk_buff *skb)
diff --git a/datapath/linux/compat/ip6_gre.c b/datapath/linux/compat/ip6_gre.c
index 94a031c9e..dd22240fc 100644
--- a/datapath/linux/compat/ip6_gre.c
+++ b/datapath/linux/compat/ip6_gre.c
@@ -785,9 +785,9 @@ static int rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
#else
static int gre_handle_offloads(struct sk_buff *skb, bool csum)
{
- return iptunnel_handle_offloads(skb,
+ return iptunnel_handle_offloads(skb, csum,
csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
-
+}
#endif
static void prepare_ip6gre_xmit_ipv4(struct sk_buff *skb,
@@ -1526,7 +1526,7 @@ static const struct net_device_ops ip6gre_netdev_ops = {
.ndo_start_xmit = ip6gre_tunnel_xmit,
.ndo_do_ioctl = ip6gre_tunnel_ioctl,
.ndo_change_mtu = ip6_tnl_change_mtu,
- .ndo_get_stats64 = rpl_ip_tunnel_get_stats64,
+ .ndo_get_stats64 = ip_tunnel_get_stats64,
#ifdef HAVE_NDO_GET_IFLINK
.ndo_get_iflink = ip6_tnl_get_iflink,
#endif
@@ -1787,7 +1787,7 @@ static struct pernet_operations ip6gre_net_ops = {
.id = &ip6gre_net_id,
.size = sizeof(struct ip6gre_net),
};
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6gre_tunnel_validate(struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -1813,7 +1813,7 @@ static int rpl_ip6gre_tunnel_validate(struct nlattr *tb[],
}
#define ip6gre_tunnel_validate rpl_ip6gre_tunnel_validate
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6gre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
#else
@@ -1839,7 +1839,7 @@ static int rpl_ip6gre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
}
out:
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
return ip6gre_tunnel_validate(tb, data, extack);
#else
return ip6gre_tunnel_validate(tb, data);
@@ -1847,7 +1847,7 @@ out:
}
#define ip6gre_tap_validate rpl_ip6gre_tap_validate
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6erspan_tap_validate(struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -1862,7 +1862,7 @@ static int rpl_ip6erspan_tap_validate(struct nlattr *tb[],
if (!data)
return 0;
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
ret = ip6gre_tap_validate(tb, data, extack);
#else
ret = ip6gre_tap_validate(tb, data);
@@ -2011,7 +2011,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = ip6_tnl_change_mtu,
- .ndo_get_stats64 = rpl_ip_tunnel_get_stats64,
+ .ndo_get_stats64 = ip_tunnel_get_stats64,
#ifdef HAVE_NDO_GET_IFLINK
.ndo_get_iflink = ip6_tnl_get_iflink,
#endif
@@ -2134,7 +2134,7 @@ static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
return ret;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -2176,7 +2176,7 @@ out:
}
#define ip6gre_newlink_common rpl_ip6gre_newlink_common
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6gre_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -2201,7 +2201,7 @@ static int rpl_ip6gre_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
err = ip6gre_newlink_common(src_net, dev, tb, data, extack);
#else
err = ip6gre_newlink_common(src_net, dev, tb, data);
@@ -2216,7 +2216,7 @@ static int rpl_ip6gre_newlink(struct net *src_net, struct net_device *dev,
#define ip6gre_newlink rpl_ip6gre_newlink
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static struct ip6_tnl *
rpl_ip6gre_changelink_common(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[], struct __ip6_tnl_parm *p_p,
@@ -2257,7 +2257,7 @@ rpl_ip6gre_changelink_common(struct net_device *dev, struct nlattr *tb[],
}
#define ip6gre_changelink_common rpl_ip6gre_changelink_common
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -2270,7 +2270,7 @@ static int rpl_ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
struct __ip6_tnl_parm p;
struct ip6_tnl *t;
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
t = ip6gre_changelink_common(dev, tb, data, &p, extack);
#else
t = ip6gre_changelink_common(dev, tb, data, &p);
@@ -2436,7 +2436,7 @@ static void ip6erspan_tap_setup(struct net_device *dev)
netif_keep_dst(dev);
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6erspan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -2461,7 +2461,7 @@ static int rpl_ip6erspan_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
err = ip6gre_newlink_common(src_net, dev, tb, data, extack);
#else
err = ip6gre_newlink_common(src_net, dev, tb, data);
@@ -2489,7 +2489,7 @@ static int ip6erspan_tnl_change(struct ip6_tnl *t,
return 0;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -2501,7 +2501,7 @@ static int rpl_ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
struct ip6gre_net *ign = net_generic(dev_net(dev), ip6gre_net_id);
struct __ip6_tnl_parm p;
struct ip6_tnl *t;
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
t = ip6gre_changelink_common(dev, tb, data, &p, extack);
#else
t = ip6gre_changelink_common(dev, tb, data, &p);
@@ -2588,7 +2588,11 @@ struct net_device *ip6erspan_fb_dev_create(struct net *net, const char *name,
t = netdev_priv(dev);
t->parms.collect_md = true;
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ err = ip6erspan_newlink(net, dev, tb, NULL, NULL);
+#else
err = ip6erspan_newlink(net, dev, tb, NULL);
+#endif
if (err < 0) {
free_netdev(dev);
return ERR_PTR(err);
@@ -2685,7 +2689,11 @@ struct net_device *ip6gre_fb_dev_create(struct net *net, const char *name,
t = netdev_priv(dev);
t->parms.collect_md = true;
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ err = ip6gre_newlink(net, dev, tb, NULL, NULL);
+#else
err = ip6gre_newlink(net, dev, tb, NULL);
+#endif
if (err < 0) {
free_netdev(dev);
return ERR_PTR(err);
diff --git a/datapath/linux/compat/ip6_tunnel.c b/datapath/linux/compat/ip6_tunnel.c
index f9720a37b..f6ac069b5 100644
--- a/datapath/linux/compat/ip6_tunnel.c
+++ b/datapath/linux/compat/ip6_tunnel.c
@@ -73,9 +73,11 @@ enum {
IFLA_IPTUN_ENCAP_SPORT,
IFLA_IPTUN_ENCAP_DPORT,
#endif
-#ifndef HAVE_IFLA_IPTUN_COLLECT_METADTA
+#ifndef HAVE_IFLA_IPTUN_COLLECT_METADATA
IFLA_IPTUN_COLLECT_METADATA = IFLA_IPTUN_ENCAP_DPORT + 1,
- IFLA_IPTUN_FWMARK,
+#endif
+#ifndef HAVE_IFLA_IPTUN_FWMARK
+ IFLA_IPTUN_FWMARK = IFLA_IPTUN_COLLECT_METADATA + 1,
#endif
RPL__IFLA_IPTUN_MAX = IFLA_IPTUN_FWMARK + 1,
};
@@ -104,7 +106,8 @@ static void gre_csum_fix(struct sk_buff *skb)
}
#define iptunnel_handle_offloads rpl__iptunnel_handle_offloads
-static int rpl__iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum)
+static int rpl__iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum,
+ int __always_unused ignored)
{
int type = gre_csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE;
gso_fix_segment_t fix_segment;
@@ -1116,7 +1119,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
// FIX ME
// fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
+ if (iptunnel_handle_offloads(skb, true, SKB_GSO_IPXIP6))
return -1;
dsfield = INET_ECN_encapsulate(dsfield, ipv4_get_dsfield(iph));
@@ -1208,7 +1211,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
// FIX ME
// fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
- if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
+ if (iptunnel_handle_offloads(skb, true, SKB_GSO_IPXIP6))
return -1;
dsfield = INET_ECN_encapsulate(dsfield, ipv6_get_dsfield(ipv6h));
@@ -1746,7 +1749,7 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
return 0;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
#else
@@ -1840,7 +1843,7 @@ static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[],
return ret;
}
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
@@ -1882,7 +1885,7 @@ static int rpl_ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
}
#define ip6_tnl_newlink rpl_ip6_tnl_newlink
-#ifdef HAVE_IP6GRE_EXTACK
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
static int rpl_ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
diff --git a/datapath/linux/compat/ip_gre.c b/datapath/linux/compat/ip_gre.c
index 5911c6cc1..d35614ee9 100644
--- a/datapath/linux/compat/ip_gre.c
+++ b/datapath/linux/compat/ip_gre.c
@@ -19,7 +19,7 @@
#include <linux/kernel.h>
#include <linux/kconfig.h>
#include <linux/slab.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/netdev_features.h>
@@ -96,14 +96,6 @@ static __be32 tunnel_id_to_key(__be64 x)
#endif
}
-#ifdef HAVE_DEMUX_PARSE_GRE_HEADER
-/* Called with rcu_read_lock and BH disabled. */
-static int gre_err(struct sk_buff *skb, u32 info,
- const struct tnl_ptk_info *tpi)
-{
- return PACKET_REJECT;
-}
-#endif
static struct dst_ops md_dst_ops = {
.family = AF_UNSPEC,
};
@@ -354,7 +346,6 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
}
-#ifndef HAVE_DEMUX_PARSE_GRE_HEADER
static int gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *unused_tpi)
{
struct tnl_ptk_info tpi;
@@ -379,28 +370,9 @@ drop:
kfree_skb(skb);
return 0;
}
-#else
-static int gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *__tpi)
-{
- struct tnl_ptk_info tpi = *__tpi;
-
- if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) ||
- tpi.proto == htons(ETH_P_ERSPAN2))) {
- if (erspan_rcv(skb, &tpi, 0) == PACKET_RCVD)
- return 0;
- goto drop;
- }
-
- if (ipgre_rcv(skb, &tpi, 0) == PACKET_RCVD)
- return 0;
-drop:
-
- kfree_skb(skb);
- return 0;
-}
-#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+#include "gso.h"
/* gre_handle_offloads() has different return type on older kernsl. */
static void gre_nop_fix(struct sk_buff *skb) { }
@@ -418,11 +390,6 @@ static void gre_csum_fix(struct sk_buff *skb)
skb->len - gre_offset, 0));
}
-static bool is_gre_gso(struct sk_buff *skb)
-{
- return skb_is_gso(skb);
-}
-
#define gre_handle_offloads rpl_gre_handle_offloads
static int rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
{
@@ -437,6 +404,12 @@ static int rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
return ovs_iptunnel_handle_offloads(skb, type, fix_segment);
}
#else
+static int gre_handle_offloads(struct sk_buff *skb, bool csum)
+{
+ return iptunnel_handle_offloads(skb, csum,
+ csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
+}
+#endif
static bool is_gre_gso(struct sk_buff *skb)
{
@@ -444,16 +417,6 @@ static bool is_gre_gso(struct sk_buff *skb)
(SKB_GSO_GRE | SKB_GSO_GRE_CSUM);
}
-static int rpl_gre_handle_offloads(struct sk_buff *skb, bool gre_csum)
-{
- if (skb_is_gso(skb) && skb_is_encapsulated(skb))
- return -ENOSYS;
-
-#undef gre_handle_offloads
- return gre_handle_offloads(skb, gre_csum);
-}
-#endif
-
static void build_header(struct sk_buff *skb, int hdr_len, __be16 flags,
__be16 proto, __be32 key, __be32 seq)
{
@@ -589,14 +552,14 @@ netdev_tx_t rpl_gre_fb_xmit(struct sk_buff *skb)
goto err_free_rt;
}
- skb = vlan_hwaccel_push_inside(skb);
+ skb = __vlan_hwaccel_push_inside(skb);
if (unlikely(!skb)) {
err = -ENOMEM;
goto err_free_rt;
}
/* Push Tunnel header. */
- err = rpl_gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM));
+ err = gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM));
if (err)
goto err_free_rt;
@@ -747,14 +710,6 @@ static void __gre_tunnel_init(struct net_device *dev)
}
}
-#ifdef HAVE_DEMUX_PARSE_GRE_HEADER
-static struct gre_cisco_protocol ipgre_cisco_protocol = {
- .handler = gre_rcv,
- .err_handler = gre_err,
- .priority = 1,
-};
-#endif
-
static int __gre_rcv(struct sk_buff *skb)
{
return gre_rcv(skb, NULL);
@@ -789,7 +744,12 @@ static struct pernet_operations ipgre_net_ops = {
.size = sizeof(struct ip_tunnel_net),
};
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
+#endif
{
__be16 flags;
@@ -807,7 +767,12 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
return 0;
}
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
+#endif
{
__be32 daddr;
@@ -828,7 +793,11 @@ static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
}
out:
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ return ipgre_tunnel_validate(tb, data, NULL);
+#else
return ipgre_tunnel_validate(tb, data);
+#endif
}
enum {
@@ -859,7 +828,12 @@ enum {
#define RPL_IFLA_GRE_MAX (IFLA_GRE_ERSPAN_HWID + 1)
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int erspan_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int erspan_validate(struct nlattr *tb[], struct nlattr *data[])
+#endif
{
__be16 flags = 0;
int ret;
@@ -867,7 +841,11 @@ static int erspan_validate(struct nlattr *tb[], struct nlattr *data[])
if (!data)
return 0;
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ ret = ipgre_tap_validate(tb, data, NULL);
+#else
ret = ipgre_tap_validate(tb, data);
+#endif
if (ret)
return ret;
@@ -1194,7 +1172,7 @@ static const struct net_device_ops gre_tap_netdev_ops = {
#else
.ndo_change_mtu = ip_tunnel_change_mtu,
#endif
- .ndo_get_stats64 = rpl_ip_tunnel_get_stats64,
+ .ndo_get_stats64 = ip_tunnel_get_stats64,
#ifdef HAVE_NDO_GET_IFLINK
.ndo_get_iflink = rpl_ip_tunnel_get_iflink,
#endif
@@ -1210,7 +1188,7 @@ static const struct net_device_ops erspan_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = ip_tunnel_change_mtu,
- .ndo_get_stats64 = rpl_ip_tunnel_get_stats64,
+ .ndo_get_stats64 = ip_tunnel_get_stats64,
#ifdef HAVE_NDO_GET_IFLINK
.ndo_get_iflink = rpl_ip_tunnel_get_iflink,
#endif
@@ -1247,8 +1225,14 @@ static void erspan_setup(struct net_device *dev)
ip_tunnel_setup(dev, erspan_net_id);
}
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int ipgre_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int ipgre_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
+#endif
{
struct ip_tunnel_parm p;
int err;
@@ -1424,7 +1408,11 @@ struct net_device *rpl_gretap_fb_dev_create(struct net *net, const char *name,
t = netdev_priv(dev);
t->collect_md = true;
/* Configure flow based GRE device. */
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ err = ipgre_newlink(net, dev, tb, NULL, NULL);
+#else
err = ipgre_newlink(net, dev, tb, NULL);
+#endif
if (err < 0) {
free_netdev(dev);
return ERR_PTR(err);
@@ -1504,7 +1492,11 @@ static struct net_device *erspan_fb_dev_create(struct net *net,
t = netdev_priv(dev);
t->collect_md = true;
/* Configure flow based GRE device. */
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+ err = ipgre_newlink(net, dev, tb, NULL, NULL);
+#else
err = ipgre_newlink(net, dev, tb, NULL);
+#endif
if (err < 0) {
free_netdev(dev);
return ERR_PTR(err);
@@ -1648,19 +1640,11 @@ int rpl_ipgre_init(void)
if (err < 0)
goto pnet_ipgre_failed;
-#ifdef HAVE_DEMUX_PARSE_GRE_HEADER
- err = gre_cisco_register(&ipgre_cisco_protocol);
- if (err < 0) {
- pr_info("%s: can't add protocol\n", __func__);
- goto add_proto_failed;
- }
-#else
err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO);
if (err < 0) {
pr_info("%s: can't add protocol\n", __func__);
goto add_proto_failed;
}
-#endif
pr_info("GRE over IPv4 tunneling driver\n");
@@ -1683,11 +1667,7 @@ void rpl_ipgre_fini(void)
{
ovs_vport_ops_unregister(&ovs_erspan_vport_ops);
ovs_vport_ops_unregister(&ovs_ipgre_vport_ops);
-#ifdef HAVE_DEMUX_PARSE_GRE_HEADER
- gre_cisco_unregister(&ipgre_cisco_protocol);
-#else
gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO);
-#endif
unregister_pernet_device(&ipgre_net_ops);
unregister_pernet_device(&erspan_net_ops);
unregister_pernet_device(&ipgre_tap_net_ops);
diff --git a/datapath/linux/compat/ip_tunnel.c b/datapath/linux/compat/ip_tunnel.c
index 58870bc2d..5ab6035ed 100644
--- a/datapath/linux/compat/ip_tunnel.c
+++ b/datapath/linux/compat/ip_tunnel.c
@@ -470,7 +470,9 @@ EXPORT_SYMBOL_GPL(rpl_ip_tunnel_xmit);
static void ip_tunnel_dev_free(struct net_device *dev)
{
free_percpu(dev->tstats);
+#ifndef HAVE_NEEDS_FREE_NETDEV
free_netdev(dev);
+#endif
}
void rpl_ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c
index 90e838a0f..fcb08905e 100644
--- a/datapath/linux/compat/ip_tunnels_core.c
+++ b/datapath/linux/compat/ip_tunnels_core.c
@@ -129,9 +129,16 @@ error:
}
EXPORT_SYMBOL_GPL(ovs_iptunnel_handle_offloads);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
struct sk_buff *rpl_iptunnel_handle_offloads(struct sk_buff *skb,
bool csum_help,
int gso_type_mask)
+#else
+int rpl_iptunnel_handle_offloads(struct sk_buff *skb,
+ bool csum_help,
+ int gso_type_mask)
+#endif
{
int err;
@@ -145,7 +152,7 @@ struct sk_buff *rpl_iptunnel_handle_offloads(struct sk_buff *skb,
if (unlikely(err))
goto error;
skb_shinfo(skb)->gso_type |= gso_type_mask;
- return skb;
+ goto out;
}
/* If packet is not gso and we are resolving any partial checksum,
@@ -163,10 +170,17 @@ struct sk_buff *rpl_iptunnel_handle_offloads(struct sk_buff *skb,
} else if (skb->ip_summed != CHECKSUM_PARTIAL)
skb->ip_summed = CHECKSUM_NONE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+out:
return skb;
error:
kfree_skb(skb);
return ERR_PTR(err);
+#else
+out:
+error:
+ return 0;
+#endif
}
EXPORT_SYMBOL_GPL(rpl_iptunnel_handle_offloads);
@@ -258,9 +272,15 @@ static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
dst[i] = src[i];
#endif
}
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
struct rtnl_link_stats64 *rpl_ip_tunnel_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *tot)
+#else
+void rpl_ip_tunnel_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *tot)
+#endif
{
int i;
@@ -286,9 +306,10 @@ struct rtnl_link_stats64 *rpl_ip_tunnel_get_stats64(struct net_device *dev,
tot->tx_bytes += tx_bytes;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
return tot;
-}
#endif
+}
void rpl_ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
struct net_device *dev)
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index fa4e7b11c..7f5d5ce64 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -844,7 +844,8 @@ static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
if (unlikely(err))
goto out_free;
- skb = vlan_hwaccel_push_inside(skb);
+ if (skb_vlan_tag_present(skb))
+ skb = __vlan_hwaccel_push_inside(skb);
if (WARN_ON(!skb))
return -ENOMEM;
@@ -1556,7 +1557,11 @@ static void vxlan_setup(struct net_device *dev)
eth_hw_addr_random(dev);
ether_setup(dev);
+#ifndef HAVE_NEEDS_FREE_NETDEV
dev->destructor = free_netdev;
+#else
+ dev->needs_free_netdev = true;
+#endif
SET_NETDEV_DEVTYPE(dev, &vxlan_type);
dev->features |= NETIF_F_LLTX;
@@ -1636,7 +1641,12 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
+#endif
{
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
@@ -1955,8 +1965,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
return 0;
}
+#ifdef HAVE_EXT_ACK_IN_RTNL_LINKOPS
+static int vxlan_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+#else
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
+#endif
{
pr_info("unsupported operation\n");
return -EINVAL;