diff options
Diffstat (limited to 'datapath')
-rw-r--r-- | datapath/linux/compat/geneve.c | 15 | ||||
-rw-r--r-- | datapath/linux/compat/gre.c | 149 | ||||
-rw-r--r-- | datapath/linux/compat/include/linux/compiler-gcc.h | 5 | ||||
-rw-r--r-- | datapath/linux/compat/include/net/dst_metadata.h | 2 | ||||
-rw-r--r-- | datapath/linux/compat/include/net/erspan.h | 2 | ||||
-rw-r--r-- | datapath/linux/compat/include/net/gre.h | 28 | ||||
-rw-r--r-- | datapath/linux/compat/include/net/ip_tunnels.h | 18 | ||||
-rw-r--r-- | datapath/linux/compat/ip6_gre.c | 46 | ||||
-rw-r--r-- | datapath/linux/compat/ip6_tunnel.c | 19 | ||||
-rw-r--r-- | datapath/linux/compat/ip_gre.c | 118 | ||||
-rw-r--r-- | datapath/linux/compat/ip_tunnel.c | 2 | ||||
-rw-r--r-- | datapath/linux/compat/ip_tunnels_core.c | 25 | ||||
-rw-r--r-- | datapath/linux/compat/vxlan.c | 18 |
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; |