]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ipv6/ip6_tunnel.c
Merge branch 'noprefixroute'
[karo-tx-linux.git] / net / ipv6 / ip6_tunnel.c
index d6062325db08411207fd63b435ec1e5e4e0f2001..5db8d310f9c07adc656dff9e3e909f611dbc1b1b 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/if.h>
 #include <linux/in.h>
 #include <linux/ip.h>
-#include <linux/if_tunnel.h>
 #include <linux/net.h>
 #include <linux/in6.h>
 #include <linux/netdevice.h>
@@ -70,9 +69,6 @@ MODULE_ALIAS_NETDEV("ip6tnl0");
 #define IP6_TNL_TRACE(x...) do {;} while(0)
 #endif
 
-#define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK)
-#define IPV6_TCLASS_SHIFT 20
-
 #define HASH_SIZE_SHIFT  5
 #define HASH_SIZE (1 << HASH_SIZE_SHIFT)
 
@@ -103,16 +99,26 @@ struct ip6_tnl_net {
 
 static struct net_device_stats *ip6_get_stats(struct net_device *dev)
 {
-       struct pcpu_tstats sum = { 0 };
+       struct pcpu_sw_netstats tmp, sum = { 0 };
        int i;
 
        for_each_possible_cpu(i) {
-               const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
-
-               sum.rx_packets += tstats->rx_packets;
-               sum.rx_bytes   += tstats->rx_bytes;
-               sum.tx_packets += tstats->tx_packets;
-               sum.tx_bytes   += tstats->tx_bytes;
+               unsigned int start;
+               const struct pcpu_sw_netstats *tstats =
+                                                  per_cpu_ptr(dev->tstats, i);
+
+               do {
+                       start = u64_stats_fetch_begin_bh(&tstats->syncp);
+                       tmp.rx_packets = tstats->rx_packets;
+                       tmp.rx_bytes = tstats->rx_bytes;
+                       tmp.tx_packets = tstats->tx_packets;
+                       tmp.tx_bytes =  tstats->tx_bytes;
+               } while (u64_stats_fetch_retry_bh(&tstats->syncp, start));
+
+               sum.rx_packets += tmp.rx_packets;
+               sum.rx_bytes   += tmp.rx_bytes;
+               sum.tx_packets += tmp.tx_packets;
+               sum.tx_bytes   += tmp.tx_bytes;
        }
        dev->stats.rx_packets = sum.rx_packets;
        dev->stats.rx_bytes   = sum.rx_bytes;
@@ -785,7 +791,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
 
        if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr,
                                        &ipv6h->daddr)) != NULL) {
-               struct pcpu_tstats *tstats;
+               struct pcpu_sw_netstats *tstats;
 
                if (t->parms.proto != ipproto && t->parms.proto != 0) {
                        rcu_read_unlock();
@@ -824,8 +830,10 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
                }
 
                tstats = this_cpu_ptr(t->dev->tstats);
+               u64_stats_update_begin(&tstats->syncp);
                tstats->rx_packets++;
                tstats->rx_bytes += skb->len;
+               u64_stats_update_end(&tstats->syncp);
 
                netif_rx(skb);
 
@@ -1131,7 +1139,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
                fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
        if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
-               fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
+               fl6.flowlabel |= ip6_flowlabel(ipv6h);
        if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
                fl6.flowi6_mark = skb->mark;
 
@@ -1498,12 +1506,12 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
 
        t->dev = dev;
        t->net = dev_net(dev);
-       dev->tstats = alloc_percpu(struct pcpu_tstats);
+       dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
        if (!dev->tstats)
                return -ENOMEM;
 
        for_each_possible_cpu(i) {
-               struct pcpu_tstats *ip6_tnl_stats;
+               struct pcpu_sw_netstats *ip6_tnl_stats;
                ip6_tnl_stats = per_cpu_ptr(dev->tstats, i);
                u64_stats_init(&ip6_tnl_stats->syncp);
        }