[ovs-dev] [PATCH] compat: Fixups for newer kernels

Darrell Ball dlu998 at gmail.com
Thu May 31 16:06:34 UTC 2018


On Thu, May 31, 2018 at 8:32 AM, Greg Rose <gvrose8192 at gmail.com> wrote:

> 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.
>
> There are still clang warnings from Travis:
> lib/netdev-native-tnl.c:666:17: error: cast from 'struct erspan_base_hdr
> *' to 'ovs_be32 *' (aka 'unsigned int *') increases required alignment from
> 1 to 4 [-Werror,-Wcast-align]
>         index = (ovs_be32 *)(ersh + 1);
>


Hi Greg

The above code no longer exists in the repo.
I suspect whatever branch you used to push to your git repo is not up to
date.

Darrell




>
> I will post a follow on patch to fix that so we can have clean Travis
> builds again.
>
> Signed-off-by: Greg Rose <gvrose8192 at gmail.com>
> ---
>  .travis.yml                                        |  11 +-
>  acinclude.m4                                       |  15 +--
>  datapath/linux/compat/geneve.c                     |  15 +++
>  datapath/linux/compat/gre.c                        | 149
> ---------------------
>  datapath/linux/compat/include/linux/compiler-gcc.h |   5 +
>  datapath/linux/compat/include/net/dst_metadata.h   |   4 +-
>  datapath/linux/compat/include/net/erspan.h         |   2 +-
>  datapath/linux/compat/include/net/gre.h            |   2 +
>  datapath/linux/compat/include/net/ip_tunnels.h     |  20 ++-
>  datapath/linux/compat/ip6_gre.c                    |  46 ++++---
>  datapath/linux/compat/ip6_tunnel.c                 |  19 +--
>  datapath/linux/compat/ip_gre.c                     | 118 +++++++---------
>  datapath/linux/compat/ip_tunnel.c                  |   2 +
>  datapath/linux/compat/ip_tunnels_core.c            |  25 +++-
>  datapath/linux/compat/vxlan.c                      |  18 ++-
>  15 files changed, 176 insertions(+), 275 deletions(-)
>
> diff --git a/.travis.yml b/.travis.yml
> index cf37e8c..ff2fa2e 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -33,12 +33,11 @@ env:
>    - BUILD_ENV="-m32" OPTS="--disable-ssl"
>    - KERNEL=3.16.54 DPDK=1
>    - KERNEL=3.16.54 DPDK=1 OPTS="--enable-shared"
> -  - KERNEL=4.15.3
> -  - KERNEL=4.14.19
> -  - KERNEL=4.9.81
> -  - KERNEL=4.4.115
> -  - KERNEL=4.1.49
> -  - KERNEL=3.10.108
> +  - KERNEL=4.14.47
> +  - KERNEL=4.9.105
> +  - KERNEL=4.4.135
> +  - KERNEL=4.1.52
> +  - KERNEL=3.16.56
>    - TESTSUITE=1 LIBS=-ljemalloc
>
>  matrix:
> diff --git a/acinclude.m4 b/acinclude.m4
> index 2351792..7a653cb 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -151,10 +151,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [
>      AC_MSG_RESULT([$kversion])
>
>      if test "$version" -ge 4; then
> -       if test "$version" = 4 && test "$patchlevel" -le 15; then
> +       if test "$version" = 4 && test "$patchlevel" -le 14; then
>            : # Linux 4.x
>         else
> -          AC_ERROR([Linux kernel in $KBUILD is version $kversion, but
> version newer than 4.15.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.14.x is not supported (please refer to the FAQ for
> advice)])
>         fi
>      elif test "$version" = 3 && test "$patchlevel" -ge 10; then
>         : # Linux 3.x
> @@ -828,12 +828,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
>    OVS_FIND_FIELD_IFELSE([$KSRC/include/linux/netdevice.h], [net_device],
>                          [max_mtu],
>                          [OVS_DEFINE([HAVE_NET_DEVICE_MAX_MTU])])
> -  OVS_GREP_IFELSE([$KSRC/include/net/erspan.h],
> -                  [__LINUX_ERSPAN_H],
> -                  [OVS_DEFINE([HAVE_LINUX_ERSPAN_H])])
> -  OVS_FIND_PARAM_IFELSE([$KSRC/net/ipv6/ip6_gre.c],
> -                        [ip6gre_tunnel_validate], [extack],
> -                        [OVS_DEFINE([HAVE_IP6GRE_EXTACK])])
>    OVS_FIND_FIELD_IFELSE([$KSRC/include/net/ip6_tunnel.h],
> [__ip6_tnl_parm],
>                          [erspan_ver],
>                          [OVS_DEFINE([HAVE_IP6_TNL_PARM_ERSPAN_VER])])
> @@ -864,9 +858,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
>    OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_tunnel.h],
>                    [IFLA_IPTUN_COLLECT_METADATA],
>                    [OVS_DEFINE([HAVE_IFLA_IPTUN_COLLECT_METADATA])])
> -  OVS_GREP_IFELSE([$KSRC/net/ipv4/gre_demux.c],
> -                  [parse_gre_header],
> -                  [OVS_DEFINE([HAVE_DEMUX_PARSE_GRE_HEADER])])
>    OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_tunnel.h],
>                    [IFLA_GRE_ENCAP_DPORT])
>    OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_tunnel.h],
> @@ -879,6 +870,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
>                    [IFLA_GRE_ERSPAN_INDEX])
>    OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_tunnel.h],
>                    [IFLA_GRE_ERSPAN_HWID])
> +  OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_tunnel.h],
> +                  [IFLA_IPTUN_FWMARK])
>
>    if cmp -s datapath/linux/kcompat.h.new \
>              datapath/linux/kcompat.h >/dev/null 2>&1; then
> diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/
> geneve.c
> index 0fcc6e5..435a23f 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 b45f8b4..7f2b545 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 bfcd531..39d2e01 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 93ea954..02e717b 100644
> --- a/datapath/linux/compat/include/net/dst_metadata.h
> +++ b/datapath/linux/compat/include/net/dst_metadata.h
> @@ -116,13 +116,13 @@ 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
> +// #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
>
>  #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 8adc89f..9fdae97 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 141ed2d..a3121b1 100644
> --- a/datapath/linux/compat/include/net/gre.h
> +++ b/datapath/linux/compat/include/net/gre.h
> @@ -124,6 +124,7 @@ static inline __be16 rpl_gre_tnl_flags_to_gre_flags(__be16
> tflags)
>         return flags;
>  }
>
> +#if 0
>  #ifndef HAVE_GRE_CISCO_REGISTER
>
>  /* GRE demux not available, implement our own demux. */
> @@ -151,6 +152,7 @@ struct gre_base_hdr {
>  #endif
>
>  #endif /* HAVE_GRE_CISCO_REGISTER */
> +#endif
>
>  #define gre_build_header rpl_gre_build_header
>  void rpl_gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info
> *tpi,
> diff --git a/datapath/linux/compat/include/net/ip_tunnels.h
> b/datapath/linux/compat/include/net/ip_tunnels.h
> index 9b2621e..f9ae265 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,7 @@ 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)
> +// #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)
>  #undef TUNNEL_NOCACHE
>  #define TUNNEL_NOCACHE 0
>
> @@ -248,7 +254,7 @@ ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
>
>         return true;
>  }
> -#endif
> +// #endif
>
>  #define ip_tunnel_dst rpl_ip_tunnel_dst
>  struct rpl_ip_tunnel_dst {
> @@ -359,14 +365,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 94a031c..dd22240 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 f9720a3..f6ac069 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 5911c6c..d35614e 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 58870bc..5ab6035 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 90e838a..fcb0890 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 fa4e7b1..7f5d5ce 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;
> --
> 1.8.3.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>


More information about the dev mailing list