summaryrefslogtreecommitdiff
path: root/datapath
diff options
context:
space:
mode:
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;