Upstream Commit:
    commit 7f290c94352e59b1d720055fce760a69a63bd0a1
    Author: Jiri Benc <jb...@redhat.com>

    iptunnel: scrub packet in iptunnel_pull_header

    Part of skb_scrub_packet was open coded in iptunnel_pull_header. Let it call
    skb_scrub_packet directly instead.

    Signed-off-by: Jiri Benc <jb...@redhat.com>
    Signed-off-by: David S. Miller <da...@davemloft.net>

Signed-off-by: Pravin B Shelar <pshe...@ovn.org>
Acked-by: Jesse Gross <je...@kernel.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(-)

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 0540494..8d25f7a 100644
--- a/datapath/linux/compat/geneve.c
+++ b/datapath/linux/compat/geneve.c
@@ -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);
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 ae3e5f3..c726012 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..4374a3a 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -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);
 
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to