diff options
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index fc998a3..2399099 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1756,17 +1756,15 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, struct sk_buff *skb, int oif, u8 tos, __be32 daddr, __be32 *saddr, struct dst_cache *dst_cache, - struct ip_tunnel_info *info) + const struct ip_tunnel_info *info) { + bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct rtable *rt = NULL; - bool use_cache = false; struct flowi4 fl4; - /* when the ip_tunnel_info is availble, the tos used for lookup is - * packet independent, so we can use the cache - */ - if (!skb->mark && (!tos || info)) { - use_cache = true; + if (tos && !info) + use_cache = false; + if (use_cache) { rt = dst_cache_get_ip4(dst_cache, saddr); if (rt) return rt; @@ -1791,16 +1789,20 @@ static struct rtable *vxlan_get_route(struct vxlan_dev *vxlan, #if IS_ENABLED(CONFIG_IPV6) static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, - struct sk_buff *skb, int oif, + struct sk_buff *skb, int oif, u8 tos, const struct in6_addr *daddr, struct in6_addr *saddr, - struct dst_cache *dst_cache) + struct dst_cache *dst_cache, + const struct ip_tunnel_info *info) { + bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct dst_entry *ndst; struct flowi6 fl6; int err; - if (!skb->mark) { + if (tos && !info) + use_cache = false; + if (use_cache) { ndst = dst_cache_get_ip6(dst_cache, saddr); if (ndst) return ndst; @@ -1808,6 +1810,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_oif = oif; + fl6.flowi6_tos = RT_TOS(tos); fl6.daddr = *daddr; fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr; fl6.flowi6_mark = skb->mark; @@ -1820,7 +1823,7 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan, return ERR_PTR(err); *saddr = fl6.saddr; - if (!skb->mark) + if (use_cache) dst_cache_set_ip6(dst_cache, ndst, saddr); return ndst; } @@ -2016,9 +2019,9 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, sk = vxlan->vn6_sock->sock->sk; ndst = vxlan6_get_route(vxlan, skb, - rdst ? rdst->remote_ifindex : 0, + rdst ? rdst->remote_ifindex : 0, tos, &dst->sin6.sin6_addr, &saddr, - dst_cache); + dst_cache, info); if (IS_ERR(ndst)) { netdev_dbg(dev, "no route to %pI6\n", &dst->sin6.sin6_addr); @@ -2053,6 +2056,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, if (!info) udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX); + tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip6_dst_hoplimit(ndst); skb_scrub_packet(skb, xnet); err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr), @@ -2062,8 +2066,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, return; } udp_tunnel6_xmit_skb(ndst, sk, skb, dev, - &saddr, &dst->sin6.sin6_addr, - 0, ttl, src_port, dst_port, !udp_sum); + &saddr, &dst->sin6.sin6_addr, tos, ttl, + src_port, dst_port, !udp_sum); #endif } @@ -2385,9 +2389,9 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) if (!vxlan->vn6_sock) return -EINVAL; - ndst = vxlan6_get_route(vxlan, skb, 0, + ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos, &info->key.u.ipv6.dst, - &info->key.u.ipv6.src, NULL); + &info->key.u.ipv6.src, NULL, info); if (IS_ERR(ndst)) return PTR_ERR(ndst); dst_release(ndst); |