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

William Tu u9012063 at gmail.com
Thu May 31 17:47:08 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);
>
> 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

Do you intentionally want to keep this? Or we can just remove it.

>  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

Same above.

The rest looks good to me.
Thanks
William


More information about the dev mailing list