AC_MSG_RESULT([$kversion])
if test "$version" -ge 4; then
- if test "$version" = 4 && test "$patchlevel" -le 5; then
+ if test "$version" = 4 && test "$patchlevel" -le 6; then
: # Linux 4.x
else
- AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.5.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.6.x is not supported (please refer to the FAQ for advice)])
fi
elif test "$version" = 3 && test "$patchlevel" -ge 10; then
: # Linux 3.x
OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [eth_hw_addr_random])
OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [ether_addr_copy])
- OVS_GREP_IFELSE([$KSRC/nclude/linux/if_ether.h], [inner_eth_hdr])
OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_link.h], [IFLA_GENEVE_TOS])
OVS_GREP_IFELSE([$KSRC/include/uapi/linux/if_link.h], [rtnl_link_stats64])
[OVS_DEFINE([HAVE_UDP_FLOW_SRC_PORT])])])
OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_v4_check])
OVS_GREP_IFELSE([$KSRC/include/net/udp_tunnel.h], [udp_tunnel_gro_complete])
+ OVS_GREP_IFELSE([$KSRC/include/net/udp_tunnel.h], [sk_buff.*udp_tunnel_handle_offloads],
+ [OVS_DEFINE([HAVE_UDP_TUNNEL_HANDLE_OFFLOAD_RET_SKB])])
OVS_FIND_FIELD_IFELSE([$KSRC/include/net/udp_tunnel.h], [udp_tunnel_sock_cfg],
[gro_receive])
if (unlikely(err))
goto free_rt;
- err = udp_tunnel_handle_offloads(skb, udp_sum, false);
+ err = udp_tunnel_handle_offloads(skb, udp_sum);
if (err)
goto free_rt;
if (unlikely(err))
goto free_dst;
- err = udp_tunnel_handle_offloads(skb, udp_sum, false);
+ err = udp_tunnel_handle_offloads(skb, udp_sum);
if (err)
goto free_dst;
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#endif
-#ifndef HAVE_INNER_ETH_HDR
+#define inner_eth_hdr rpl_inner_eth_hdr
static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb)
{
return (struct ethhdr *)skb_inner_mac_header(skb);
}
#endif
-#endif
#include <net/ip6_fib.h>
#endif
-#ifndef USE_UPSTREAM_TUNNEL
+#ifdef USE_UPSTREAM_TUNNEL
+#include_next <net/dst_cache.h>
+
+#else
struct dst_cache {
struct dst_cache_pcpu __percpu *cache;
unsigned long reset_ts;
}
#define skb_tunnel_info ovs_skb_tunnel_info
-#endif
static inline void ovs_tun_rx_dst(struct metadata_dst *md_dst, int optslen)
{
info->key.label = ip6_flowlabel(ip6h);
}
+#endif /* USE_UPSTREAM_TUNNEL */
+
void ovs_ip_tunnel_rcv(struct net_device *dev, struct sk_buff *skb,
struct metadata_dst *tun_dst);
#endif /* __NET_DST_METADATA_WRAPPER_H */
#undef TUNNEL_OPTIONS_PRESENT
#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)
-#define skb_is_encapsulated ovs_skb_is_encapsulated
-bool ovs_skb_is_encapsulated(struct sk_buff *skb);
-
/* Used to memset ip_tunnel padding. */
#define IP_TUNNEL_KEY_SIZE offsetofend(struct ip_tunnel_key, tp_dst)
return 0;
}
#endif /* USE_UPSTREAM_TUNNEL */
+
+#define skb_is_encapsulated ovs_skb_is_encapsulated
+bool ovs_skb_is_encapsulated(struct sk_buff *skb);
+
#endif /* __NET_IP_TUNNELS_H */
#ifdef USE_UPSTREAM_TUNNEL
#include_next <net/udp_tunnel.h>
-/* this is to handle the return type change in handle-offload
- * functions.
- */
-static inline int
-rpl_udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum,
- bool is_vxlan)
-{
- if (skb_is_gso(skb) && skb_is_encapsulated(skb)) {
- return -ENOSYS;
- }
- return udp_tunnel_handle_offloads(skb, udp_csum);
-}
-
#else
#include <net/addrconf.h>
void ovs_udp_csum_gso(struct sk_buff *skb);
static inline int rpl_udp_tunnel_handle_offloads(struct sk_buff *skb,
- bool udp_csum,
- bool is_vxlan)
+ bool udp_csum)
{
int type = 0;
fix_segment = ovs_udp_gso;
else
fix_segment = ovs_udp_csum_gso;
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
- if (!is_vxlan)
- type = 0;
+ /* This functuin is not used by vxlan lan tunnel. On older
+ * udp offload only supports vxlan, therefore fallback to software
+ * segmentation.
+ */
+ type = 0;
#endif
return ovs_iptunnel_handle_offloads(skb, udp_csum, type, fix_segment);
}
-#endif /* USE_UPSTREAM_TUNNEL */
#define udp_tunnel_handle_offloads rpl_udp_tunnel_handle_offloads
static inline void ovs_udp_tun_rx_dst(struct metadata_dst *md_dst,
if (udp_hdr(skb)->check)
info->key.tun_flags |= TUNNEL_CSUM;
}
+#endif /* USE_UPSTREAM_TUNNEL */
#endif
return ip_route_output_key(net, fl);
}
+/* this is to handle the return type change in handle-offload
+ * functions.
+ */
+#if !defined(HAVE_UDP_TUNNEL_HANDLE_OFFLOAD_RET_SKB) || !defined(USE_UPSTREAM_TUNNEL)
+static struct sk_buff *
+__udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
+{
+ int err;
+
+ err = udp_tunnel_handle_offloads(skb, udp_csum);
+ if (err) {
+ kfree_skb(skb);
+ return NULL;
+ }
+ return skb;
+}
+#else
+#define __udp_tunnel_handle_offloads udp_tunnel_handle_offloads
+#endif
+
netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
skb_reset_mac_header(skb);
skb->vlan_tci = 0;
- err = udp_tunnel_handle_offloads(skb, false, false);
- if (err)
+ if (skb_is_gso(skb) && skb_is_encapsulated(skb))
goto err_free_rt;
+ skb = __udp_tunnel_handle_offloads(skb, false);
+ if (!skb)
+ return NETDEV_TX_OK;
+
src_port = htons(get_src_port(net, skb));
dst_port = lisp_dev->dst_port;