@@ -2215,57 +2215,6 @@ static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
22152215 return 0 ;
22162216}
22172217
2218- static struct rtable * vxlan_get_route (struct vxlan_dev * vxlan , struct net_device * dev ,
2219- struct vxlan_sock * sock4 ,
2220- struct sk_buff * skb , int oif , u8 tos ,
2221- __be32 daddr , __be32 * saddr , __be16 dport , __be16 sport ,
2222- __u8 flow_flags , struct dst_cache * dst_cache ,
2223- const struct ip_tunnel_info * info )
2224- {
2225- bool use_cache = ip_tunnel_dst_cache_usable (skb , info );
2226- struct rtable * rt = NULL ;
2227- struct flowi4 fl4 ;
2228-
2229- if (!sock4 )
2230- return ERR_PTR (- EIO );
2231-
2232- if (tos && !info )
2233- use_cache = false;
2234- if (use_cache ) {
2235- rt = dst_cache_get_ip4 (dst_cache , saddr );
2236- if (rt )
2237- return rt ;
2238- }
2239-
2240- memset (& fl4 , 0 , sizeof (fl4 ));
2241- fl4 .flowi4_oif = oif ;
2242- fl4 .flowi4_tos = RT_TOS (tos );
2243- fl4 .flowi4_mark = skb -> mark ;
2244- fl4 .flowi4_proto = IPPROTO_UDP ;
2245- fl4 .daddr = daddr ;
2246- fl4 .saddr = * saddr ;
2247- fl4 .fl4_dport = dport ;
2248- fl4 .fl4_sport = sport ;
2249- fl4 .flowi4_flags = flow_flags ;
2250-
2251- rt = ip_route_output_key (vxlan -> net , & fl4 );
2252- if (!IS_ERR (rt )) {
2253- if (rt -> dst .dev == dev ) {
2254- netdev_dbg (dev , "circular route to %pI4\n" , & daddr );
2255- ip_rt_put (rt );
2256- return ERR_PTR (- ELOOP );
2257- }
2258-
2259- * saddr = fl4 .saddr ;
2260- if (use_cache )
2261- dst_cache_set_ip4 (dst_cache , & rt -> dst , fl4 .saddr );
2262- } else {
2263- netdev_dbg (dev , "no route to %pI4\n" , & daddr );
2264- return ERR_PTR (- ENETUNREACH );
2265- }
2266- return rt ;
2267- }
2268-
22692218#if IS_ENABLED (CONFIG_IPV6 )
22702219static struct dst_entry * vxlan6_get_route (struct vxlan_dev * vxlan ,
22712220 struct net_device * dev ,
@@ -2418,30 +2367,38 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24182367{
24192368 struct dst_cache * dst_cache ;
24202369 struct ip_tunnel_info * info ;
2370+ struct ip_tunnel_key * pkey ;
2371+ struct ip_tunnel_key key ;
24212372 struct vxlan_dev * vxlan = netdev_priv (dev );
24222373 const struct iphdr * old_iph = ip_hdr (skb );
24232374 union vxlan_addr * dst ;
2424- union vxlan_addr remote_ip , local_ip ;
2375+ union vxlan_addr remote_ip ;
24252376 struct vxlan_metadata _md ;
24262377 struct vxlan_metadata * md = & _md ;
24272378 unsigned int pkt_len = skb -> len ;
24282379 __be16 src_port = 0 , dst_port ;
24292380 struct dst_entry * ndst = NULL ;
2430- __u8 tos , ttl , flow_flags = 0 ;
2381+ __u8 tos , ttl ;
24312382 int ifindex ;
24322383 int err ;
24332384 u32 flags = vxlan -> cfg .flags ;
2385+ bool use_cache ;
24342386 bool udp_sum = false;
24352387 bool xnet = !net_eq (vxlan -> net , dev_net (vxlan -> dev ));
24362388 __be32 vni = 0 ;
24372389#if IS_ENABLED (CONFIG_IPV6 )
2390+ union vxlan_addr local_ip ;
24382391 __be32 label ;
24392392#endif
24402393
24412394 info = skb_tunnel_info (skb );
2395+ use_cache = ip_tunnel_dst_cache_usable (skb , info );
24422396
24432397 if (rdst ) {
24442398 dst = & rdst -> remote_ip ;
2399+ memset (& key , 0 , sizeof (key ));
2400+ pkey = & key ;
2401+
24452402 if (vxlan_addr_any (dst )) {
24462403 if (did_rsc ) {
24472404 /* short-circuited back to local bridge */
@@ -2455,7 +2412,15 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24552412 dst_port = rdst -> remote_port ? rdst -> remote_port : vxlan -> cfg .dst_port ;
24562413 vni = (rdst -> remote_vni ) ? : default_vni ;
24572414 ifindex = rdst -> remote_ifindex ;
2458- local_ip = vxlan -> cfg .saddr ;
2415+
2416+ if (dst -> sa .sa_family == AF_INET ) {
2417+ key .u .ipv4 .src = vxlan -> cfg .saddr .sin .sin_addr .s_addr ;
2418+ key .u .ipv4 .dst = rdst -> remote_ip .sin .sin_addr .s_addr ;
2419+ } else {
2420+ key .u .ipv6 .src = vxlan -> cfg .saddr .sin6 .sin6_addr ;
2421+ key .u .ipv6 .dst = rdst -> remote_ip .sin6 .sin6_addr ;
2422+ }
2423+
24592424 dst_cache = & rdst -> dst_cache ;
24602425 md -> gbp = skb -> mark ;
24612426 if (flags & VXLAN_F_TTL_INHERIT ) {
@@ -2469,12 +2434,15 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24692434 tos = vxlan -> cfg .tos ;
24702435 if (tos == 1 )
24712436 tos = ip_tunnel_get_dsfield (old_iph , skb );
2437+ if (tos && !info )
2438+ use_cache = false;
24722439
24732440 if (dst -> sa .sa_family == AF_INET )
24742441 udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX );
24752442 else
24762443 udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX );
24772444#if IS_ENABLED (CONFIG_IPV6 )
2445+ local_ip = vxlan -> cfg .saddr ;
24782446 label = vxlan -> cfg .label ;
24792447#endif
24802448 } else {
@@ -2486,14 +2454,15 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24862454 remote_ip .sa .sa_family = ip_tunnel_info_af (info );
24872455 if (remote_ip .sa .sa_family == AF_INET ) {
24882456 remote_ip .sin .sin_addr .s_addr = info -> key .u .ipv4 .dst ;
2489- local_ip .sin .sin_addr .s_addr = info -> key .u .ipv4 .src ;
24902457 } else {
24912458 remote_ip .sin6 .sin6_addr = info -> key .u .ipv6 .dst ;
2459+ #if IS_ENABLED (CONFIG_IPV6 )
24922460 local_ip .sin6 .sin6_addr = info -> key .u .ipv6 .src ;
2461+ #endif
24932462 }
24942463 dst = & remote_ip ;
2464+ pkey = & info -> key ;
24952465 dst_port = info -> key .tp_dst ? : vxlan -> cfg .dst_port ;
2496- flow_flags = info -> key .flow_flags ;
24972466 vni = tunnel_id_to_key32 (info -> key .tun_id );
24982467 ifindex = 0 ;
24992468 dst_cache = & info -> dst_cache ;
@@ -2517,15 +2486,14 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25172486 struct vxlan_sock * sock4 = rcu_dereference (vxlan -> vn4_sock );
25182487 struct rtable * rt ;
25192488 __be16 df = 0 ;
2489+ __be32 saddr ;
25202490
25212491 if (!ifindex )
25222492 ifindex = sock4 -> sock -> sk -> sk_bound_dev_if ;
25232493
2524- rt = vxlan_get_route (vxlan , dev , sock4 , skb , ifindex , tos ,
2525- dst -> sin .sin_addr .s_addr ,
2526- & local_ip .sin .sin_addr .s_addr ,
2527- dst_port , src_port , flow_flags ,
2528- dst_cache , info );
2494+ rt = udp_tunnel_dst_lookup (skb , dev , vxlan -> net , ifindex ,
2495+ & saddr , pkey , src_port , dst_port ,
2496+ tos , use_cache ? dst_cache : NULL );
25292497 if (IS_ERR (rt )) {
25302498 err = PTR_ERR (rt );
25312499 goto tx_error ;
@@ -2561,16 +2529,13 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25612529 } else if (err ) {
25622530 if (info ) {
25632531 struct ip_tunnel_info * unclone ;
2564- struct in_addr src , dst ;
25652532
25662533 unclone = skb_tunnel_info_unclone (skb );
25672534 if (unlikely (!unclone ))
25682535 goto tx_error ;
25692536
2570- src = remote_ip .sin .sin_addr ;
2571- dst = local_ip .sin .sin_addr ;
2572- unclone -> key .u .ipv4 .src = src .s_addr ;
2573- unclone -> key .u .ipv4 .dst = dst .s_addr ;
2537+ unclone -> key .u .ipv4 .src = pkey -> u .ipv4 .dst ;
2538+ unclone -> key .u .ipv4 .dst = saddr ;
25742539 }
25752540 vxlan_encap_bypass (skb , vxlan , vxlan , vni , false);
25762541 dst_release (ndst );
@@ -2584,8 +2549,8 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25842549 if (err < 0 )
25852550 goto tx_error ;
25862551
2587- udp_tunnel_xmit_skb (rt , sock4 -> sock -> sk , skb , local_ip . sin . sin_addr . s_addr ,
2588- dst -> sin . sin_addr . s_addr , tos , ttl , df ,
2552+ udp_tunnel_xmit_skb (rt , sock4 -> sock -> sk , skb , saddr ,
2553+ pkey -> u . ipv4 . dst , tos , ttl , df ,
25892554 src_port , dst_port , xnet , !udp_sum );
25902555#if IS_ENABLED (CONFIG_IPV6 )
25912556 } else {
@@ -3286,11 +3251,14 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
32863251 struct vxlan_sock * sock4 = rcu_dereference (vxlan -> vn4_sock );
32873252 struct rtable * rt ;
32883253
3289- rt = vxlan_get_route (vxlan , dev , sock4 , skb , 0 , info -> key .tos ,
3290- info -> key .u .ipv4 .dst ,
3291- & info -> key .u .ipv4 .src , dport , sport ,
3292- info -> key .flow_flags , & info -> dst_cache ,
3293- info );
3254+ if (!sock4 )
3255+ return - EIO ;
3256+
3257+ rt = udp_tunnel_dst_lookup (skb , dev , vxlan -> net , 0 ,
3258+ & info -> key .u .ipv4 .src ,
3259+ & info -> key ,
3260+ sport , dport , info -> key .tos ,
3261+ & info -> dst_cache );
32943262 if (IS_ERR (rt ))
32953263 return PTR_ERR (rt );
32963264 ip_rt_put (rt );
0 commit comments