forked from mirrors/linux
		
	ip_tunnel: Move stats update to iptunnel_xmit()
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>
This commit is contained in:
		
							parent
							
								
									d7d3e25f40
								
							
						
					
					
						commit
						039f50629b
					
				
					 12 changed files with 56 additions and 78 deletions
				
			
		|  | @ -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); | 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); | ||||||
| 		df = 0; | 		df = 0; | ||||||
| 	} | 	} | ||||||
| 	err = udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr, | 	udp_tunnel_xmit_skb(rt, gs4->sock->sk, skb, fl4.saddr, fl4.daddr, | ||||||
| 			    tos, ttl, df, sport, geneve->dst_port, | 			    tos, ttl, df, sport, geneve->dst_port, | ||||||
| 			    !net_eq(geneve->net, dev_net(geneve->dev)), | 			    !net_eq(geneve->net, dev_net(geneve->dev)), | ||||||
| 			    !(flags & GENEVE_F_UDP_CSUM)); | 			    !(flags & GENEVE_F_UDP_CSUM)); | ||||||
| 
 | 
 | ||||||
| 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |  | ||||||
| 	return NETDEV_TX_OK; | 	return NETDEV_TX_OK; | ||||||
| 
 | 
 | ||||||
| tx_error: | tx_error: | ||||||
|  | @ -1005,7 +1004,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, | ||||||
| 			ttl = 1; | 			ttl = 1; | ||||||
| 		ttl = ttl ? : ip6_dst_hoplimit(dst); | 		ttl = ttl ? : ip6_dst_hoplimit(dst); | ||||||
| 	} | 	} | ||||||
| 	err = udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev, | 	udp_tunnel6_xmit_skb(dst, gs6->sock->sk, skb, dev, | ||||||
| 			     &fl6.saddr, &fl6.daddr, prio, ttl, | 			     &fl6.saddr, &fl6.daddr, prio, ttl, | ||||||
| 			     sport, geneve->dst_port, | 			     sport, geneve->dst_port, | ||||||
| 			     !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX)); | 			     !!(flags & GENEVE_F_UDP_ZERO_CSUM6_TX)); | ||||||
|  |  | ||||||
|  | @ -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)); | 	skb_set_inner_protocol(skb, htons(ETH_P_TEB)); | ||||||
| 
 | 
 | ||||||
| 	return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos, | 	udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos, ttl, df, | ||||||
| 				   ttl, df, src_port, dst_port, xnet, | 			    src_port, dst_port, xnet, | ||||||
| 			    !(vxflags & VXLAN_F_UDP_CSUM)); | 			    !(vxflags & VXLAN_F_UDP_CSUM)); | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if IS_ENABLED(CONFIG_IPV6) | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  | @ -2056,8 +2057,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | ||||||
| 			skb = NULL; | 			skb = NULL; | ||||||
| 			goto rt_tx_error; | 			goto rt_tx_error; | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |  | ||||||
| #if IS_ENABLED(CONFIG_IPV6) | #if IS_ENABLED(CONFIG_IPV6) | ||||||
| 	} else { | 	} else { | ||||||
| 		struct dst_entry *ndst; | 		struct dst_entry *ndst; | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <linux/netdevice.h> | #include <linux/netdevice.h> | ||||||
| #include <linux/if_tunnel.h> | #include <linux/if_tunnel.h> | ||||||
| #include <linux/ip6_tunnel.h> | #include <linux/ip6_tunnel.h> | ||||||
|  | #include <net/ip_tunnels.h> | ||||||
| 
 | 
 | ||||||
| #define IP6TUNNEL_ERR_TIMEO (30*HZ) | #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, | static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, | ||||||
| 				  struct net_device *dev) | 				  struct net_device *dev) | ||||||
| { | { | ||||||
| 	struct net_device_stats *stats = &dev->stats; |  | ||||||
| 	int pkt_len, err; | 	int pkt_len, err; | ||||||
| 
 | 
 | ||||||
| 	pkt_len = skb->len - skb_inner_network_offset(skb); | 	pkt_len = skb->len - skb_inner_network_offset(skb); | ||||||
| 	err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb); | 	err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb); | ||||||
| 
 | 	if (unlikely(net_xmit_eval(err))) | ||||||
| 	if (net_xmit_eval(err) == 0) { | 		pkt_len = -1; | ||||||
| 		struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); | 	iptunnel_xmit_stats(dev, pkt_len); | ||||||
| 		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++; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -273,7 +273,7 @@ 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_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, | void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, | ||||||
| 		   __be32 src, __be32 dst, u8 proto, | 		   __be32 src, __be32 dst, u8 proto, | ||||||
| 		   u8 tos, u8 ttl, __be16 df, bool xnet); | 		   u8 tos, u8 ttl, __be16 df, bool xnet); | ||||||
| struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, | struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, | ||||||
|  | @ -282,25 +282,27 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, | ||||||
| struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum, | struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum, | ||||||
| 					 int gso_type_mask); | 					 int gso_type_mask); | ||||||
| 
 | 
 | ||||||
| static inline void iptunnel_xmit_stats(int err, | static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len) | ||||||
| 				       struct net_device_stats *err_stats, |  | ||||||
| 				       struct pcpu_sw_netstats __percpu *stats) |  | ||||||
| { | { | ||||||
| 	if (err > 0) { | 	if (pkt_len > 0) { | ||||||
| 		struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats); | 		struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); | ||||||
| 
 | 
 | ||||||
| 		u64_stats_update_begin(&tstats->syncp); | 		u64_stats_update_begin(&tstats->syncp); | ||||||
| 		tstats->tx_bytes += err; | 		tstats->tx_bytes += pkt_len; | ||||||
| 		tstats->tx_packets++; | 		tstats->tx_packets++; | ||||||
| 		u64_stats_update_end(&tstats->syncp); | 		u64_stats_update_end(&tstats->syncp); | ||||||
| 		put_cpu_ptr(tstats); | 		put_cpu_ptr(tstats); | ||||||
| 	} else if (err < 0) { | 	} else { | ||||||
|  | 		struct net_device_stats *err_stats = &dev->stats; | ||||||
|  | 
 | ||||||
|  | 		if (pkt_len < 0) { | ||||||
| 			err_stats->tx_errors++; | 			err_stats->tx_errors++; | ||||||
| 			err_stats->tx_aborted_errors++; | 			err_stats->tx_aborted_errors++; | ||||||
| 		} else { | 		} else { | ||||||
| 			err_stats->tx_dropped++; | 			err_stats->tx_dropped++; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info) | static inline void *ip_tunnel_info_opts(struct ip_tunnel_info *info) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -78,7 +78,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock, | ||||||
| 			   struct udp_tunnel_sock_cfg *sock_cfg); | 			   struct udp_tunnel_sock_cfg *sock_cfg); | ||||||
| 
 | 
 | ||||||
| /* Transmit the skb using UDP encapsulation. */ | /* Transmit the skb using UDP encapsulation. */ | ||||||
| int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, | void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, | ||||||
| 			 __be32 src, __be32 dst, __u8 tos, __u8 ttl, | 			 __be32 src, __be32 dst, __u8 tos, __u8 ttl, | ||||||
| 			 __be16 df, __be16 src_port, __be16 dst_port, | 			 __be16 df, __be16 src_port, __be16 dst_port, | ||||||
| 			 bool xnet, bool nocheck); | 			 bool xnet, bool nocheck); | ||||||
|  |  | ||||||
|  | @ -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); | 		     tunnel_id_to_key(tun_info->key.tun_id), 0); | ||||||
| 
 | 
 | ||||||
| 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 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, | 	iptunnel_xmit(skb->sk, rt, skb, fl.saddr, key->u.ipv4.dst, IPPROTO_GRE, | ||||||
| 		      key->tos, key->ttl, df, false); | 		      key->tos, key->ttl, df, false); | ||||||
| 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |  | ||||||
| 	return; | 	return; | ||||||
| 
 | 
 | ||||||
| err_free_rt: | err_free_rt: | ||||||
|  |  | ||||||
|  | @ -656,7 +656,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | ||||||
| 	struct rtable *rt;		/* Route to the other host */ | 	struct rtable *rt;		/* Route to the other host */ | ||||||
| 	unsigned int max_headroom;	/* The extra header space needed */ | 	unsigned int max_headroom;	/* The extra header space needed */ | ||||||
| 	__be32 dst; | 	__be32 dst; | ||||||
| 	int err; |  | ||||||
| 	bool connected; | 	bool connected; | ||||||
| 
 | 
 | ||||||
| 	inner_iph = (const struct iphdr *)skb_inner_network_header(skb); | 	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; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, | 	iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, | ||||||
| 			    tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 		      df, !net_eq(tunnel->net, dev_net(dev))); | ||||||
| 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |  | ||||||
| 
 |  | ||||||
| 	return; | 	return; | ||||||
| 
 | 
 | ||||||
| #if IS_ENABLED(CONFIG_IPV6) | #if IS_ENABLED(CONFIG_IPV6) | ||||||
|  |  | ||||||
|  | @ -47,12 +47,13 @@ | ||||||
| #include <net/rtnetlink.h> | #include <net/rtnetlink.h> | ||||||
| #include <net/dst_metadata.h> | #include <net/dst_metadata.h> | ||||||
| 
 | 
 | ||||||
| int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, | void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, | ||||||
| 		   __be32 src, __be32 dst, __u8 proto, | 		   __be32 src, __be32 dst, __u8 proto, | ||||||
| 		   __u8 tos, __u8 ttl, __be16 df, bool xnet) | 		   __u8 tos, __u8 ttl, __be16 df, bool xnet) | ||||||
| { | { | ||||||
| 	int pkt_len = skb->len - skb_inner_network_offset(skb); | 	int pkt_len = skb->len - skb_inner_network_offset(skb); | ||||||
| 	struct net *net = dev_net(rt->dst.dev); | 	struct net *net = dev_net(rt->dst.dev); | ||||||
|  | 	struct net_device *dev = skb->dev; | ||||||
| 	struct iphdr *iph; | 	struct iphdr *iph; | ||||||
| 	int err; | 	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); | 	err = ip_local_out(net, sk, skb); | ||||||
| 	if (unlikely(net_xmit_eval(err))) | 	if (unlikely(net_xmit_eval(err))) | ||||||
| 		pkt_len = 0; | 		pkt_len = 0; | ||||||
| 	return pkt_len; | 	iptunnel_xmit_stats(dev, pkt_len); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(iptunnel_xmit); | EXPORT_SYMBOL_GPL(iptunnel_xmit); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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); | 	err = dst_output(tunnel->net, skb->sk, skb); | ||||||
| 	if (net_xmit_eval(err) == 0) | 	if (net_xmit_eval(err) == 0) | ||||||
| 		err = skb->len; | 		err = skb->len; | ||||||
| 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 	iptunnel_xmit_stats(dev, err); | ||||||
| 	return NETDEV_TX_OK; | 	return NETDEV_TX_OK; | ||||||
| 
 | 
 | ||||||
| tx_error_icmp: | tx_error_icmp: | ||||||
|  |  | ||||||
|  | @ -74,7 +74,7 @@ void setup_udp_tunnel_sock(struct net *net, struct socket *sock, | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock); | EXPORT_SYMBOL_GPL(setup_udp_tunnel_sock); | ||||||
| 
 | 
 | ||||||
| int udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, | void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb, | ||||||
| 			 __be32 src, __be32 dst, __u8 tos, __u8 ttl, | 			 __be32 src, __be32 dst, __u8 tos, __u8 ttl, | ||||||
| 			 __be16 df, __be16 src_port, __be16 dst_port, | 			 __be16 df, __be16 src_port, __be16 dst_port, | ||||||
| 			 bool xnet, bool nocheck) | 			 bool xnet, bool nocheck) | ||||||
|  | @ -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); | 	udp_set_csum(nocheck, skb, src, dst, skb->len); | ||||||
| 
 | 
 | ||||||
| 	return iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, | 	iptunnel_xmit(sk, rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, xnet); | ||||||
| 			     tos, ttl, df, xnet); |  | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb); | EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -820,7 +820,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | ||||||
| 	const struct in6_addr *addr6; | 	const struct in6_addr *addr6; | ||||||
| 	int addr_type; | 	int addr_type; | ||||||
| 	u8 ttl; | 	u8 ttl; | ||||||
| 	int err; |  | ||||||
| 	u8 protocol = IPPROTO_IPV6; | 	u8 protocol = IPPROTO_IPV6; | ||||||
| 	int t_hlen = tunnel->hlen + sizeof(struct iphdr); | 	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); | 	skb_set_inner_ipproto(skb, IPPROTO_IPV6); | ||||||
| 
 | 
 | ||||||
| 	err = iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, | 	iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, | ||||||
| 			    protocol, tos, ttl, df, | 		      df, !net_eq(tunnel->net, dev_net(dev))); | ||||||
| 			    !net_eq(tunnel->net, dev_net(dev))); |  | ||||||
| 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |  | ||||||
| 	return NETDEV_TX_OK; | 	return NETDEV_TX_OK; | ||||||
| 
 | 
 | ||||||
| tx_error_icmp: | tx_error_icmp: | ||||||
|  |  | ||||||
|  | @ -182,15 +182,9 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, | ||||||
| 			goto tx_error; | 			goto tx_error; | ||||||
| 		} | 		} | ||||||
| 		ttl = ip4_dst_hoplimit(&rt->dst); | 		ttl = ip4_dst_hoplimit(&rt->dst); | ||||||
| 		err = udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, | 		udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr, | ||||||
| 					  src->ipv4.s_addr, | 				    dst->ipv4.s_addr, 0, ttl, 0, src->udp_port, | ||||||
| 					  dst->ipv4.s_addr, 0, ttl, 0, | 				    dst->udp_port, false, true); | ||||||
| 					  src->udp_port, dst->udp_port, |  | ||||||
| 					  false, true); |  | ||||||
| 		if (err < 0) { |  | ||||||
| 			ip_rt_put(rt); |  | ||||||
| 			goto tx_error; |  | ||||||
| 		} |  | ||||||
| #if IS_ENABLED(CONFIG_IPV6) | #if IS_ENABLED(CONFIG_IPV6) | ||||||
| 	} else { | 	} else { | ||||||
| 		struct dst_entry *ndst; | 		struct dst_entry *ndst; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Pravin B Shelar
						Pravin B Shelar