diff mbox

[ovs-dev,v2,02/24] datapath: compat: update iptunnel_pull_header()

Message ID 1467274002-61390-2-git-send-email-pshelar@ovn.org
State Superseded
Headers show

Commit Message

Pravin Shelar June 30, 2016, 8:06 a.m. UTC
Introduce xnet parameter to iptunnel_pull_header().

Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
---
 acinclude.m4                                   |  1 +
 datapath/linux/compat/geneve.c                 |  2 +-
 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                  |  2 +-
 9 files changed, 41 insertions(+), 22 deletions(-)

Comments

Jesse Gross June 30, 2016, 3:16 p.m. UTC | #1
On Thu, Jun 30, 2016 at 1:06 AM, Pravin B Shelar <pshelar@ovn.org> wrote:
> Introduce xnet parameter to iptunnel_pull_header().
>
> Signed-off-by: Pravin B Shelar <pshelar@ovn.org>

I think this is essentially 7f290c94352e59b1d720055fce760a69a63bd0a1
("iptunnel: scrub packet in iptunnel_pull_header") but it is missing
some pieces, which means that we do odd things like scrub the packet
twice. Can you backport the whole thing in one go?
diff mbox

Patch

diff --git a/acinclude.m4 b/acinclude.m4
index 7f96be1..65d41f0 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -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])])
diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
index 884ea53..5983e6a 100644
--- a/datapath/linux/compat/geneve.c
+++ b/datapath/linux/compat/geneve.c
@@ -247,7 +247,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);
diff --git a/datapath/linux/compat/gre.c b/datapath/linux/compat/gre.c
index fa8d936..bb49c8c 100644
--- a/datapath/linux/compat/gre.c
+++ b/datapath/linux/compat/gre.c
@@ -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;
diff --git a/datapath/linux/compat/include/linux/skbuff.h b/datapath/linux/compat/include/linux/skbuff.h
index 376dfda..c0abe72 100644
--- a/datapath/linux/compat/include/linux/skbuff.h
+++ b/datapath/linux/compat/include/linux/skbuff.h
@@ -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
diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h
index 5eda8a2..bf67ac4 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -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,
diff --git a/datapath/linux/compat/ip_tunnels_core.c b/datapath/linux/compat/ip_tunnels_core.c
index 0858d02..c5fb2b7 100644
--- a/datapath/linux/compat/ip_tunnels_core.c
+++ b/datapath/linux/compat/ip_tunnels_core.c
@@ -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
 
diff --git a/datapath/linux/compat/lisp.c b/datapath/linux/compat/lisp.c
index 0a9a227..246a0fa 100644
--- a/datapath/linux/compat/lisp.c
+++ b/datapath/linux/compat/lisp.c
@@ -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);
diff --git a/datapath/linux/compat/stt.c b/datapath/linux/compat/stt.c
index 0bdd4db..423800b 100644
--- a/datapath/linux/compat/stt.c
+++ b/datapath/linux/compat/stt.c
@@ -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;
 
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index b92a902..a25db87 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -924,7 +924,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);