diff options
author | wenxu <wenxu@ucloud.cn> | 2019-01-22 18:39:49 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-26 09:43:03 -0800 |
commit | f46fe4f8d787bd66005120460317939b8c6d7c70 (patch) | |
tree | 63aecb91fc579f48646977cd142d7f668627fa63 /net/ipv4/ip_tunnel.c | |
parent | 662a14d0c71e9e775383b0fd6796c9eb47d29ecc (diff) | |
download | linux-next-f46fe4f8d787bd66005120460317939b8c6d7c70.tar.gz |
ip_tunnel: Add ip tunnel dst_cache in ip_md_tunnel_xmit
Add ip tunnel dst cache in ip_md_tunnel_xmit to make more
efficient for the route lookup.
Signed-off-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_tunnel.c')
-rw-r--r-- | net/ipv4/ip_tunnel.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index c4f5602308ed..f98fc4c983a5 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -555,10 +555,11 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto) struct ip_tunnel_info *tun_info; const struct ip_tunnel_key *key; const struct iphdr *inner_iph; - struct rtable *rt; + struct rtable *rt = NULL; struct flowi4 fl4; __be16 df = 0; u8 tos, ttl; + bool use_cache; tun_info = skb_tunnel_info(skb); if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) || @@ -578,10 +579,19 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, u8 proto) RT_TOS(tos), tunnel->parms.link, tunnel->fwmark); if (tunnel->encap.type != TUNNEL_ENCAP_NONE) goto tx_error; - rt = ip_route_output_key(tunnel->net, &fl4); - if (IS_ERR(rt)) { - dev->stats.tx_carrier_errors++; - goto tx_error; + + use_cache = ip_tunnel_dst_cache_usable(skb, tun_info); + if (use_cache) + rt = dst_cache_get_ip4(&tun_info->dst_cache, &fl4.saddr); + if (!rt) { + rt = ip_route_output_key(tunnel->net, &fl4); + if (IS_ERR(rt)) { + dev->stats.tx_carrier_errors++; + goto tx_error; + } + if (use_cache) + dst_cache_set_ip4(&tun_info->dst_cache, &rt->dst, + fl4.saddr); } if (rt->dst.dev == dev) { ip_rt_put(rt); |