[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