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); | ||||
| 		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: | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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++; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -47,12 +47,13 @@ | |||
| #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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Pravin B Shelar
						Pravin B Shelar