Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / ipv4 / ip_vti.c
index 1831092f999fb32880f2d5e721c242236b000228..f4a825d3bd7ffea56b08022fb8c528055c8281ea 100644 (file)
@@ -66,20 +66,6 @@ static void vti_tunnel_setup(struct net_device *dev);
 static void vti_dev_free(struct net_device *dev);
 static int vti_tunnel_bind_dev(struct net_device *dev);
 
-/* Locking : hash tables are protected by RCU and RTNL */
-
-#define for_each_ip_tunnel_rcu(start) \
-       for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
-
-/* often modified stats are per cpu, other are shared (netdev->stats) */
-struct pcpu_tstats {
-       u64     rx_packets;
-       u64     rx_bytes;
-       u64     tx_packets;
-       u64     tx_bytes;
-       struct  u64_stats_sync  syncp;
-};
-
 #define VTI_XMIT(stats1, stats2) do {                          \
        int err;                                                \
        int pkt_len = skb->len;                                 \
@@ -142,19 +128,19 @@ static struct ip_tunnel *vti_tunnel_lookup(struct net *net,
        struct ip_tunnel *t;
        struct vti_net *ipn = net_generic(net, vti_net_id);
 
-       for_each_ip_tunnel_rcu(ipn->tunnels_r_l[h0 ^ h1])
+       for_each_ip_tunnel_rcu(t, ipn->tunnels_r_l[h0 ^ h1])
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
                        return t;
-       for_each_ip_tunnel_rcu(ipn->tunnels_r[h0])
+       for_each_ip_tunnel_rcu(t, ipn->tunnels_r[h0])
                if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
                        return t;
 
-       for_each_ip_tunnel_rcu(ipn->tunnels_l[h1])
+       for_each_ip_tunnel_rcu(t, ipn->tunnels_l[h1])
                if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP))
                        return t;
 
-       for_each_ip_tunnel_rcu(ipn->tunnels_wc[0])
+       for_each_ip_tunnel_rcu(t, ipn->tunnels_wc[0])
                if (t && (t->dev->flags&IFF_UP))
                        return t;
        return NULL;
@@ -338,12 +324,17 @@ static int vti_rcv(struct sk_buff *skb)
        if (tunnel != NULL) {
                struct pcpu_tstats *tstats;
 
+               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+                       return -1;
+
                tstats = this_cpu_ptr(tunnel->dev->tstats);
                u64_stats_update_begin(&tstats->syncp);
                tstats->rx_packets++;
                tstats->rx_bytes += skb->len;
                u64_stats_update_end(&tstats->syncp);
 
+               skb->mark = 0;
+               secpath_reset(skb);
                skb->dev = tunnel->dev;
                return 1;
        }