diff options
-rw-r--r-- | drivers/net/vxlan.c | 2 | ||||
-rw-r--r-- | include/linux/if_tunnel.h | 10 | ||||
-rw-r--r-- | include/net/ipip.h | 40 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 14 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 9 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 14 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 8 | ||||
-rw-r--r-- | net/ipv6/sit.c | 14 |
9 files changed, 35 insertions, 85 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 8aca888734da..9814d67237f1 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -769,7 +769,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) | |||
769 | 769 | ||
770 | vxlan_set_owner(dev, skb); | 770 | vxlan_set_owner(dev, skb); |
771 | 771 | ||
772 | /* See __IPTUNNEL_XMIT */ | 772 | /* See iptunnel_xmit() */ |
773 | skb->ip_summed = CHECKSUM_NONE; | 773 | skb->ip_summed = CHECKSUM_NONE; |
774 | ip_select_ident(iph, &rt->dst, NULL); | 774 | ip_select_ident(iph, &rt->dst, NULL); |
775 | 775 | ||
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 1cc595a67cc9..06d1d5badd36 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h | |||
@@ -4,5 +4,15 @@ | |||
4 | #include <linux/ip.h> | 4 | #include <linux/ip.h> |
5 | #include <linux/in6.h> | 5 | #include <linux/in6.h> |
6 | #include <uapi/linux/if_tunnel.h> | 6 | #include <uapi/linux/if_tunnel.h> |
7 | #include <linux/u64_stats_sync.h> | ||
8 | |||
9 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
10 | struct pcpu_tstats { | ||
11 | u64 rx_packets; | ||
12 | u64 rx_bytes; | ||
13 | u64 tx_packets; | ||
14 | u64 tx_bytes; | ||
15 | struct u64_stats_sync syncp; | ||
16 | }; | ||
7 | 17 | ||
8 | #endif /* _IF_TUNNEL_H_ */ | 18 | #endif /* _IF_TUNNEL_H_ */ |
diff --git a/include/net/ipip.h b/include/net/ipip.h index ddc077c51f32..21947cf4fa46 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h | |||
@@ -48,25 +48,27 @@ struct ip_tunnel_prl_entry { | |||
48 | struct rcu_head rcu_head; | 48 | struct rcu_head rcu_head; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #define __IPTUNNEL_XMIT(stats1, stats2) do { \ | 51 | static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
52 | int err; \ | 52 | { |
53 | int pkt_len = skb->len - skb_transport_offset(skb); \ | 53 | int err; |
54 | \ | 54 | struct iphdr *iph = ip_hdr(skb); |
55 | skb->ip_summed = CHECKSUM_NONE; \ | 55 | int pkt_len = skb->len - skb_transport_offset(skb); |
56 | ip_select_ident(iph, &rt->dst, NULL); \ | 56 | struct pcpu_tstats *tstats = this_cpu_ptr(dev->tstats); |
57 | \ | ||
58 | err = ip_local_out(skb); \ | ||
59 | if (likely(net_xmit_eval(err) == 0)) { \ | ||
60 | u64_stats_update_begin(&(stats1)->syncp); \ | ||
61 | (stats1)->tx_bytes += pkt_len; \ | ||
62 | (stats1)->tx_packets++; \ | ||
63 | u64_stats_update_end(&(stats1)->syncp); \ | ||
64 | } else { \ | ||
65 | (stats2)->tx_errors++; \ | ||
66 | (stats2)->tx_aborted_errors++; \ | ||
67 | } \ | ||
68 | } while (0) | ||
69 | 57 | ||
70 | #define IPTUNNEL_XMIT() __IPTUNNEL_XMIT(txq, stats) | 58 | nf_reset(skb); |
59 | skb->ip_summed = CHECKSUM_NONE; | ||
60 | ip_select_ident(iph, skb_dst(skb), NULL); | ||
61 | |||
62 | err = ip_local_out(skb); | ||
63 | if (likely(net_xmit_eval(err) == 0)) { | ||
64 | u64_stats_update_begin(&tstats->syncp); | ||
65 | tstats->tx_bytes += pkt_len; | ||
66 | tstats->tx_packets++; | ||
67 | u64_stats_update_end(&tstats->syncp); | ||
68 | } else { | ||
69 | dev->stats.tx_errors++; | ||
70 | dev->stats.tx_aborted_errors++; | ||
71 | } | ||
72 | } | ||
71 | 73 | ||
72 | #endif | 74 | #endif |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 7240f8e2dd45..37000ae24c55 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -171,15 +171,6 @@ struct ipgre_net { | |||
171 | #define for_each_ip_tunnel_rcu(start) \ | 171 | #define for_each_ip_tunnel_rcu(start) \ |
172 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 172 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
173 | 173 | ||
174 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
175 | struct pcpu_tstats { | ||
176 | u64 rx_packets; | ||
177 | u64 rx_bytes; | ||
178 | u64 tx_packets; | ||
179 | u64 tx_bytes; | ||
180 | struct u64_stats_sync syncp; | ||
181 | }; | ||
182 | |||
183 | static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev, | 174 | static struct rtnl_link_stats64 *ipgre_get_stats64(struct net_device *dev, |
184 | struct rtnl_link_stats64 *tot) | 175 | struct rtnl_link_stats64 *tot) |
185 | { | 176 | { |
@@ -753,7 +744,6 @@ drop: | |||
753 | static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | 744 | static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
754 | { | 745 | { |
755 | struct ip_tunnel *tunnel = netdev_priv(dev); | 746 | struct ip_tunnel *tunnel = netdev_priv(dev); |
756 | struct pcpu_tstats *tstats; | ||
757 | const struct iphdr *old_iph = ip_hdr(skb); | 747 | const struct iphdr *old_iph = ip_hdr(skb); |
758 | const struct iphdr *tiph; | 748 | const struct iphdr *tiph; |
759 | struct flowi4 fl4; | 749 | struct flowi4 fl4; |
@@ -977,9 +967,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
977 | } | 967 | } |
978 | } | 968 | } |
979 | 969 | ||
980 | nf_reset(skb); | 970 | iptunnel_xmit(skb, dev); |
981 | tstats = this_cpu_ptr(dev->tstats); | ||
982 | __IPTUNNEL_XMIT(tstats, &dev->stats); | ||
983 | return NETDEV_TX_OK; | 971 | return NETDEV_TX_OK; |
984 | 972 | ||
985 | #if IS_ENABLED(CONFIG_IPV6) | 973 | #if IS_ENABLED(CONFIG_IPV6) |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092f999f..e0f2c88f03c1 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -71,15 +71,6 @@ static int vti_tunnel_bind_dev(struct net_device *dev); | |||
71 | #define for_each_ip_tunnel_rcu(start) \ | 71 | #define for_each_ip_tunnel_rcu(start) \ |
72 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 72 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
73 | 73 | ||
74 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
75 | struct pcpu_tstats { | ||
76 | u64 rx_packets; | ||
77 | u64 rx_bytes; | ||
78 | u64 tx_packets; | ||
79 | u64 tx_bytes; | ||
80 | struct u64_stats_sync syncp; | ||
81 | }; | ||
82 | |||
83 | #define VTI_XMIT(stats1, stats2) do { \ | 74 | #define VTI_XMIT(stats1, stats2) do { \ |
84 | int err; \ | 75 | int err; \ |
85 | int pkt_len = skb->len; \ | 76 | int pkt_len = skb->len; \ |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 720855e41100..3a4ad7d82f67 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -147,15 +147,6 @@ static struct rtnl_link_ops ipip_link_ops __read_mostly; | |||
147 | #define for_each_ip_tunnel_rcu(start) \ | 147 | #define for_each_ip_tunnel_rcu(start) \ |
148 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 148 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
149 | 149 | ||
150 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
151 | struct pcpu_tstats { | ||
152 | u64 rx_packets; | ||
153 | u64 rx_bytes; | ||
154 | u64 tx_packets; | ||
155 | u64 tx_bytes; | ||
156 | struct u64_stats_sync syncp; | ||
157 | }; | ||
158 | |||
159 | static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev, | 150 | static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev, |
160 | struct rtnl_link_stats64 *tot) | 151 | struct rtnl_link_stats64 *tot) |
161 | { | 152 | { |
@@ -465,7 +456,6 @@ drop: | |||
465 | static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | 456 | static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
466 | { | 457 | { |
467 | struct ip_tunnel *tunnel = netdev_priv(dev); | 458 | struct ip_tunnel *tunnel = netdev_priv(dev); |
468 | struct pcpu_tstats *tstats; | ||
469 | const struct iphdr *tiph = &tunnel->parms.iph; | 459 | const struct iphdr *tiph = &tunnel->parms.iph; |
470 | u8 tos = tunnel->parms.iph.tos; | 460 | u8 tos = tunnel->parms.iph.tos; |
471 | __be16 df = tiph->frag_off; | 461 | __be16 df = tiph->frag_off; |
@@ -592,9 +582,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
592 | if ((iph->ttl = tiph->ttl) == 0) | 582 | if ((iph->ttl = tiph->ttl) == 0) |
593 | iph->ttl = old_iph->ttl; | 583 | iph->ttl = old_iph->ttl; |
594 | 584 | ||
595 | nf_reset(skb); | 585 | iptunnel_xmit(skb, dev); |
596 | tstats = this_cpu_ptr(dev->tstats); | ||
597 | __IPTUNNEL_XMIT(tstats, &dev->stats); | ||
598 | return NETDEV_TX_OK; | 586 | return NETDEV_TX_OK; |
599 | 587 | ||
600 | tx_error_icmp: | 588 | tx_error_icmp: |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 12aa473e9793..672101db71ee 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -116,15 +116,6 @@ static u32 HASH_ADDR(const struct in6_addr *addr) | |||
116 | #define for_each_ip_tunnel_rcu(start) \ | 116 | #define for_each_ip_tunnel_rcu(start) \ |
117 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 117 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
118 | 118 | ||
119 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
120 | struct pcpu_tstats { | ||
121 | u64 rx_packets; | ||
122 | u64 rx_bytes; | ||
123 | u64 tx_packets; | ||
124 | u64 tx_bytes; | ||
125 | struct u64_stats_sync syncp; | ||
126 | }; | ||
127 | |||
128 | static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, | 119 | static struct rtnl_link_stats64 *ip6gre_get_stats64(struct net_device *dev, |
129 | struct rtnl_link_stats64 *tot) | 120 | struct rtnl_link_stats64 *tot) |
130 | { | 121 | { |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 424ed45ef122..8db4d9b7ab14 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -95,14 +95,6 @@ struct ip6_tnl_net { | |||
95 | struct ip6_tnl __rcu **tnls[2]; | 95 | struct ip6_tnl __rcu **tnls[2]; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
99 | struct pcpu_tstats { | ||
100 | unsigned long rx_packets; | ||
101 | unsigned long rx_bytes; | ||
102 | unsigned long tx_packets; | ||
103 | unsigned long tx_bytes; | ||
104 | } __attribute__((aligned(4*sizeof(unsigned long)))); | ||
105 | |||
106 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) | 98 | static struct net_device_stats *ip6_get_stats(struct net_device *dev) |
107 | { | 99 | { |
108 | struct pcpu_tstats sum = { 0 }; | 100 | struct pcpu_tstats sum = { 0 }; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b543c56cad28..ffe83ef70cf7 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -88,15 +88,6 @@ struct sit_net { | |||
88 | #define for_each_ip_tunnel_rcu(start) \ | 88 | #define for_each_ip_tunnel_rcu(start) \ |
89 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) | 89 | for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) |
90 | 90 | ||
91 | /* often modified stats are per cpu, other are shared (netdev->stats) */ | ||
92 | struct pcpu_tstats { | ||
93 | u64 rx_packets; | ||
94 | u64 rx_bytes; | ||
95 | u64 tx_packets; | ||
96 | u64 tx_bytes; | ||
97 | struct u64_stats_sync syncp; | ||
98 | }; | ||
99 | |||
100 | static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev, | 91 | static struct rtnl_link_stats64 *ipip6_get_stats64(struct net_device *dev, |
101 | struct rtnl_link_stats64 *tot) | 92 | struct rtnl_link_stats64 *tot) |
102 | { | 93 | { |
@@ -685,7 +676,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
685 | struct net_device *dev) | 676 | struct net_device *dev) |
686 | { | 677 | { |
687 | struct ip_tunnel *tunnel = netdev_priv(dev); | 678 | struct ip_tunnel *tunnel = netdev_priv(dev); |
688 | struct pcpu_tstats *tstats; | ||
689 | const struct iphdr *tiph = &tunnel->parms.iph; | 679 | const struct iphdr *tiph = &tunnel->parms.iph; |
690 | const struct ipv6hdr *iph6 = ipv6_hdr(skb); | 680 | const struct ipv6hdr *iph6 = ipv6_hdr(skb); |
691 | u8 tos = tunnel->parms.iph.tos; | 681 | u8 tos = tunnel->parms.iph.tos; |
@@ -866,9 +856,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
866 | if ((iph->ttl = tiph->ttl) == 0) | 856 | if ((iph->ttl = tiph->ttl) == 0) |
867 | iph->ttl = iph6->hop_limit; | 857 | iph->ttl = iph6->hop_limit; |
868 | 858 | ||
869 | nf_reset(skb); | 859 | iptunnel_xmit(skb, dev); |
870 | tstats = this_cpu_ptr(dev->tstats); | ||
871 | __IPTUNNEL_XMIT(tstats, &dev->stats); | ||
872 | return NETDEV_TX_OK; | 860 | return NETDEV_TX_OK; |
873 | 861 | ||
874 | tx_error_icmp: | 862 | tx_error_icmp: |