@@ -541,6 +541,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_ensure_writable])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_vlan_pop])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_vlan_push])
+ OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_clear_hash_if_not_l4])
OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [bool],
[OVS_DEFINE([HAVE_BOOL_TYPE])])
@@ -175,7 +175,6 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
}
skb_reset_mac_header(skb);
- skb_scrub_packet(skb, !net_eq(geneve->net, dev_net(geneve->dev)));
skb->protocol = eth_type_trans(skb, geneve->dev);
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
@@ -247,7 +246,7 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
opts_len = geneveh->opt_len * 4;
if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
- htons(ETH_P_TEB)))
+ htons(ETH_P_TEB), false))
goto drop;
gs = rcu_dereference_sk_user_data(sk);
@@ -243,7 +243,7 @@ static int parse_gre_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
}
}
- return iptunnel_pull_header(skb, hdr_len, tpi->proto);
+ return iptunnel_pull_header(skb, hdr_len, tpi->proto, false);
}
static struct gre_cisco_protocol __rcu *gre_cisco_proto;
@@ -333,4 +333,12 @@ static inline void skb_pop_mac_header(struct sk_buff *skb)
{
skb->mac_header = skb->network_header;
}
+
+#ifndef HAVE_SKB_CLEAR_HASH_IF_NOT_L4
+static inline void skb_clear_hash_if_not_l4(struct sk_buff *skb)
+{
+ if (!skb->l4_rxhash)
+ skb_clear_hash(skb);
+}
+#endif
#endif
@@ -18,6 +18,19 @@
#include <net/ip.h>
#include <net/rtnetlink.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+#define __iptunnel_pull_header rpl___iptunnel_pull_header
+int rpl___iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool raw_proto, bool xnet);
+
+#define iptunnel_pull_header rpl_iptunnel_pull_header
+static inline int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool xnet)
+{
+ return rpl___iptunnel_pull_header(skb, hdr_len, inner_proto, false, xnet);
+}
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
struct sk_buff *ovs_iptunnel_handle_offloads(struct sk_buff *skb,
bool csum_help, int gso_type_mask,
@@ -28,18 +41,11 @@ int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl,
__be16 df, bool xnet);
-#define iptunnel_pull_header rpl_iptunnel_pull_header
-int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
-
#else
#define ovs_iptunnel_handle_offloads(skb, csum_help, gso_type_mask, fix_segment) \
iptunnel_handle_offloads(skb, csum_help, gso_type_mask)
-/* This macro is to make OVS build happy about declared functions name. */
-#define rpl_iptunnel_pull_header iptunnel_pull_header
-int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
-
#define rpl_iptunnel_xmit iptunnel_xmit
int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl,
@@ -139,23 +139,25 @@ error:
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(ovs_iptunnel_handle_offloads);
+#endif
-int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+int rpl___iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool raw_proto, bool xnet)
{
if (unlikely(!pskb_may_pull(skb, hdr_len)))
return -ENOMEM;
skb_pull_rcsum(skb, hdr_len);
- if (inner_proto == htons(ETH_P_TEB)) {
+ if (!raw_proto && inner_proto == htons(ETH_P_TEB)) {
struct ethhdr *eh;
if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
return -ENOMEM;
eh = (struct ethhdr *)skb->data;
-
- if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
+ if (likely(eth_proto_is_802_3(eh->h_proto)))
skb->protocol = eh->h_proto;
else
skb->protocol = htons(ETH_P_802_2);
@@ -164,16 +166,14 @@ int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_prot
skb->protocol = inner_proto;
}
- nf_reset(skb);
- secpath_reset(skb);
- skb_clear_hash(skb);
- skb_dst_drop(skb);
+ skb_clear_hash_if_not_l4(skb);
skb->vlan_tci = 0;
skb_set_queue_mapping(skb, 0);
- skb->pkt_type = PACKET_HOST;
+ skb_scrub_packet(skb, xnet);
+
return 0;
}
-EXPORT_SYMBOL_GPL(rpl_iptunnel_pull_header);
+EXPORT_SYMBOL_GPL(rpl___iptunnel_pull_header);
#endif
@@ -207,6 +207,7 @@ static void lisp_build_header(struct sk_buff *skb,
/* Called with rcu_read_lock and BH disabled. */
static int lisp_rcv(struct sock *sk, struct sk_buff *skb)
{
+ struct lisp_dev *lisp_dev;
struct net_device *dev;
struct lisphdr *lisph;
struct iphdr *inner_iph;
@@ -222,7 +223,9 @@ static int lisp_rcv(struct sock *sk, struct sk_buff *skb)
if (unlikely(!dev))
goto error;
- if (iptunnel_pull_header(skb, LISP_HLEN, 0))
+ lisp_dev = netdev_priv(dev);
+ if (iptunnel_pull_header(skb, LISP_HLEN, 0,
+ !net_eq(lisp_dev->net, dev_net(lisp_dev->dev))))
goto error;
lisph = lisp_hdr(skb);
@@ -1462,7 +1462,8 @@ static void stt_rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
err = iptunnel_pull_header(skb,
sizeof(struct stthdr) + STT_ETH_PAD,
- htons(ETH_P_TEB));
+ htons(ETH_P_TEB),
+ !net_eq(stt_dev->net, dev_net(stt_dev->dev)));
if (unlikely(err))
goto drop;
@@ -833,7 +833,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
goto drop;
skb_reset_mac_header(skb);
- skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
skb->protocol = eth_type_trans(skb, vxlan->dev);
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
@@ -924,7 +923,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto bad_flags;
}
- if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
+ if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB), false))
goto drop;
vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
Introduce xnet parameter to iptunnel_pull_header(). Signed-off-by: Pravin B Shelar <pshelar@ovn.org> --- acinclude.m4 | 1 + datapath/linux/compat/geneve.c | 3 +-- datapath/linux/compat/gre.c | 2 +- datapath/linux/compat/include/linux/skbuff.h | 8 ++++++++ datapath/linux/compat/include/net/ip_tunnels.h | 20 +++++++++++++------- datapath/linux/compat/ip_tunnels_core.c | 20 ++++++++++---------- datapath/linux/compat/lisp.c | 5 ++++- datapath/linux/compat/stt.c | 3 ++- datapath/linux/compat/vxlan.c | 3 +-- 9 files changed, 41 insertions(+), 24 deletions(-)