ip_tunnel: Move stats update to iptunnel_xmit()
authorPravin B Shelar <pshelar@nicira.com>
Thu, 24 Dec 2015 22:34:54 +0000 (14:34 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 26 Dec 2015 04:32:23 +0000 (23:32 -0500)
By moving stats update into iptunnel_xmit(), we can simplify
iptunnel_xmit() usage. With this change there is no need to
call another function (iptunnel_xmit_stats()) to update stats
in tunnel xmit code path.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
12 files changed:
drivers/net/geneve.c
drivers/net/vxlan.c
include/net/ip6_tunnel.h
include/net/ip_tunnels.h
include/net/udp_tunnel.h
net/ipv4/ip_gre.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ip_vti.c
net/ipv4/udp_tunnel.c
net/ipv6/sit.c
net/tipc/udp_media.c

index e6e00924f8efcdae25c3282db8ba5eb494d9ba95..20dd66423ec8852462eff0ec373f1b45c77c59ab 100644 (file)
@@ -918,12 +918,11 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
                df = 0;
        }
-       err = udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr,
-                                 tos, ttl, df, sport, geneve->dst_port,
-                                 !net_eq(geneve->net, dev_net(geneve->dev)),
-                                 !(flags & GENEVE_F_UDP_CSUM));
+       udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr,
+                           tos, ttl, df, sport, geneve->dst_port,
+                           !net_eq(geneve->net, dev_net(geneve->dev)),
+                           !(flags & GENEVE_F_UDP_CSUM));
 
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
        return NETDEV_TX_OK;
 
 tx_error:
@@ -1005,10 +1004,10 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                        ttl = 1;
                ttl = ttl ? : ip6_dst_hoplimit(dst);
        }
-       err = udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
-                                  &fl6.saddr, &fl6.daddr, prio, ttl,
-                                  sport, geneve->dst_port,
-                                  !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
+       udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev,
+                            &fl6.saddr, &fl6.daddr, prio, ttl,
+                            sport, geneve->dst_port,
+                            !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX));
        return NETDEV_TX_OK;
 
 tx_error:
index ba363cedef80820feb11b5ce6f5f347f8a575d12..fecf7b6c732e96a76d2dd0b1ff7433a76ab2e37d 100644 (file)
@@ -1841,9 +1841,10 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
 
        skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
-                                  ttl, df, src_port, dst_port, xnet,
-                                  !(vxflags & VXLAN_F_UDP_CSUM));
+       udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos, ttl, df,
+                           src_port, dst_port, xnet,
+                           !(vxflags & VXLAN_F_UDP_CSUM));
+       return 0;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
@@ -2056,8 +2057,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        skb = NULL;
                        goto rt_tx_error;
                }
-
-               iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 #if IS_ENABLED(CONFIG_IPV6)
        } else {
                struct dst_entry *ndst;
index ff788b665277d59d8039fd4588f3e0256639833c..ae07e94778d80c82c3d5f7a4ed07752ab2dfa773 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_tunnel.h>
 #include <linux/ip6_tunnel.h>
+#include <net/ip_tunnels.h>
 
 #define IP6TUNNEL_ERR_TIMEO (30*HZ)
 
@@ -83,22 +84,12 @@ int ip6_tnl_get_iflink(const struct net_device *dev);
 static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
                                  struct net_device *dev)
 {
-       struct net_device_stats *stats = &dev->stats;
        int pkt_len, err;
 
        pkt_len = skb->len - skb_inner_network_offset(skb);
        err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
-
-       if (net_xmit_eval(err) == 0) {
-               struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);
-               u64_stats_update_begin(&tstats->syncp);
-               tstats->tx_bytes += pkt_len;
-               tstats->tx_packets++;
-               u64_stats_update_end(&tstats->syncp);
-               put_cpu_ptr(tstats);
-       } else {
-               stats->tx_errors++;
-               stats->tx_aborted_errors++;
-       }
+       if (unlikely(net_xmit_eval(err)))
+               pkt_len = -1;
+       iptunnel_xmit_stats(dev, pkt_len);
 }
 #endif
index 62a750a6a8f8cb32c9eb5d8d160aa94a20898473..6db96ea0144f0445c4e52c51cddcc3d25d60ccdd 100644 (file)
@@ -273,32 +273,34 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
 }
 
 int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
-int 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);
+void 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);
 struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
                                             gfp_t flags);
 
 struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum,
                                         int gso_type_mask);
 
-static inline void iptunnel_xmit_stats(int err,
-                                      struct net_device_stats *err_stats,
-                                      struct pcpu_sw_netstats __percpu *stats)
+static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)
 {
-       if (err > 0) {
-               struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats);
+       if (pkt_len > 0) {
+               struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);
 
                u64_stats_update_begin(&tstats->syncp);
-               tstats->tx_bytes += err;
+               tstats->tx_bytes += pkt_len;
                tstats->tx_packets++;
                u64_stats_update_end(&tstats->syncp);
                put_cpu_ptr(tstats);
-       } else if (err < 0) {
-               err_stats->tx_errors++;
-               err_stats->tx_aborted_errors++;
        } else {
-               err_stats->tx_dropped++;
+               struct net_device_stats *err_stats = &dev->stats;
+
+               if (pkt_len < 0) {
+                       err_stats->tx_errors++;
+                       err_stats->tx_aborted_errors++;
+               } else {
+                       err_stats->tx_dropped++;
+               }
        }
 }
 
index cb2f89f20f5c95d4566745cf02aa97d064fd1099..cca2ad3082c37aaa9250f7f79ac105e1dcf1f754 100644 (file)
@@ -78,10 +78,10 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
                           struct udp_tunnel_sock_cfg *sock_cfg);
 
 /* Transmit the skb using UDP encapsulation. */
-int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
-                       __be32 src, __be32 dst, __u8 tos, __u8 ttl,
-                       __be16 df, __be16 src_port, __be16 dst_port,
-                       bool xnet, bool nocheck);
+void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
+                        __be32 src, __be32 dst, __u8 tos, __u8 ttl,
+                        __be16 df, __be16 src_port, __be16 dst_port,
+                        bool xnet, bool nocheck);
 
 #if IS_ENABLED(CONFIG_IPV6)
 int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
index 04a48c0159cca559d1f894d2d7400157a3a93dfe..7c51c4e1661f9aafc63829cf58b3b5ec28ed859e 100644 (file)
@@ -561,10 +561,9 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
                     tunnel_id_to_key(tun_info->key.tun_id), 0);
 
        df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
-       err = iptunnel_xmit(skb->sk, rt, skb, fl.saddr,
-                           key->u.ipv4.dst, IPPROTO_GRE,
-                           key->tos, key->ttl, df, false);
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
+
+       iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE,
+                     key->tos, key->ttl, df, false);
        return;
 
 err_free_rt:
index 0f6e9ee031c4b7a1b4013bd735b4200d888fc5fd..c7bd72e9b544848d10a490b010e0a30c4d5e4c21 100644 (file)
@@ -656,7 +656,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
        struct rtable *rt;              /* Route to the other host */
        unsigned int max_headroom;      /* The extra header space needed */
        __be32 dst;
-       int err;
        bool connected;
 
        inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
@@ -794,10 +793,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
                return;
        }
 
-       err = iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol,
-                           tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
-
+       iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
+                     df, !net_eq(tunnel->net, dev_net(dev)));
        return;
 
 #if IS_ENABLED(CONFIG_IPV6)
index 1db8418aa62e67d6c58aa76bab8f23526f2324f7..eb52ce950c27b7f4ed06f349f1655a2e38968d72 100644 (file)
 #include <net/rtnetlink.h>
 #include <net/dst_metadata.h>
 
-int 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)
+void 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)
 {
        int pkt_len = skb->len - skb_inner_network_offset(skb);
        struct net *net = dev_net(rt->dst.dev);
+       struct net_device *dev = skb->dev;
        struct iphdr *iph;
        int err;
 
@@ -81,7 +82,7 @@ int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
        err = ip_local_out(net, sk, skb);
        if (unlikely(net_xmit_eval(err)))
                pkt_len = 0;
-       return pkt_len;
+       iptunnel_xmit_stats(dev, pkt_len);
 }
 EXPORT_SYMBOL_GPL(iptunnel_xmit);
 
index 02d9c21e2953b86179ea4a0ddcd9a3fb95bc9c63..5cf10b777b7e4bb8b1037201a2c8bfeeb031c7cc 100644 (file)
@@ -199,7 +199,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
        err = dst_output(tunnel->net, skb->sk, skb);
        if (net_xmit_eval(err) == 0)
                err = skb->len;
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
+       iptunnel_xmit_stats(dev, err);
        return NETDEV_TX_OK;
 
 tx_error_icmp:
index aba428626b5290ddf68c8b350b8b2879119d136b..0ec08814f37d9e904b5f85bbd86cd2fa607c4307 100644 (file)
@@ -74,10 +74,10 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
 }
 EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock);
 
-int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
-                       __be32 src, __be32 dst, __u8 tos, __u8 ttl,
-                       __be16 df, __be16 src_port, __be16 dst_port,
-                       bool xnet, bool nocheck)
+void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
+                        __be32 src, __be32 dst, __u8 tos, __u8 ttl,
+                        __be16 df, __be16 src_port, __be16 dst_port,
+                        bool xnet, bool nocheck)
 {
        struct udphdr *uh;
 
@@ -91,8 +91,7 @@ int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
 
        udp_set_csum(nocheck, skb, src, dst, skb->len);
 
-       return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP,
-                            tos, ttl, df, xnet);
+       iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, xnet);
 }
 EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
 
index dcccae86190f2a29c5ea8199320bbf399c7350b1..e794ef66a40135f33b5731a1059a6f45d0fc90b7 100644 (file)
@@ -820,7 +820,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
        const struct in6_addr *addr6;
        int addr_type;
        u8 ttl;
-       int err;
        u8 protocol = IPPROTO_IPV6;
        int t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
@@ -983,10 +982,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 
        skb_set_inner_ipproto(skb, IPPROTO_IPV6);
 
-       err = iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr,
-                           protocol, tos, ttl, df,
-                           !net_eq(tunnel->net, dev_net(dev)));
-       iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
+       iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl,
+                     df, !net_eq(tunnel->net, dev_net(dev)));
        return NETDEV_TX_OK;
 
 tx_error_icmp:
index 6af78c6276b4b185be00d62370932bb1d816bfd4..d63a911e7fe29b2f4ef9c1795e47cf5feb006be0 100644 (file)
@@ -182,15 +182,9 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
                        goto tx_error;
                }
                ttl = ip4_dst_hoplimit(&rt->dst);
-               err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb,
-                                         src->ipv4.s_addr,
-                                         dst->ipv4.s_addr, 0, ttl, 0,
-                                         src->udp_port, dst->udp_port,
-                                         false, true);
-               if (err < 0) {
-                       ip_rt_put(rt);
-                       goto tx_error;
-               }
+               udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
+                                   dst->ipv4.s_addr, 0, ttl, 0, src->udp_port,
+                                   dst->udp_port, false, true);
 #if IS_ENABLED(CONFIG_IPV6)
        } else {
                struct dst_entry *ndst;