@@ -432,39 +432,33 @@ static struct rtable *gre_get_rt(struct sk_buff *skb,
432
432
return ip_route_output_key (net , fl );
433
433
}
434
434
435
- static void gre_fb_xmit (struct sk_buff * skb , struct net_device * dev ,
436
- __be16 proto )
435
+ static struct rtable * prepare_fb_xmit (struct sk_buff * skb ,
436
+ struct net_device * dev ,
437
+ struct flowi4 * fl ,
438
+ int tunnel_hlen )
437
439
{
438
440
struct ip_tunnel_info * tun_info ;
439
441
const struct ip_tunnel_key * key ;
440
442
struct rtable * rt = NULL ;
441
- struct flowi4 fl ;
442
443
int min_headroom ;
443
- int tunnel_hlen ;
444
- __be16 df , flags ;
445
444
bool use_cache ;
446
445
int err ;
447
446
448
447
tun_info = skb_tunnel_info (skb );
449
- if (unlikely (!tun_info || !(tun_info -> mode & IP_TUNNEL_INFO_TX ) ||
450
- ip_tunnel_info_af (tun_info ) != AF_INET ))
451
- goto err_free_skb ;
452
-
453
448
key = & tun_info -> key ;
454
449
use_cache = ip_tunnel_dst_cache_usable (skb , tun_info );
450
+
455
451
if (use_cache )
456
- rt = dst_cache_get_ip4 (& tun_info -> dst_cache , & fl . saddr );
452
+ rt = dst_cache_get_ip4 (& tun_info -> dst_cache , & fl -> saddr );
457
453
if (!rt ) {
458
- rt = gre_get_rt (skb , dev , & fl , key );
454
+ rt = gre_get_rt (skb , dev , fl , key );
459
455
if (IS_ERR (rt ))
460
- goto err_free_skb ;
456
+ goto err_free_skb ;
461
457
if (use_cache )
462
458
dst_cache_set_ip4 (& tun_info -> dst_cache , & rt -> dst ,
463
- fl . saddr );
459
+ fl -> saddr );
464
460
}
465
461
466
- tunnel_hlen = gre_calc_hlen (key -> tun_flags );
467
-
468
462
min_headroom = LL_RESERVED_SPACE (rt -> dst .dev ) + rt -> dst .header_len
469
463
+ tunnel_hlen + sizeof (struct iphdr );
470
464
if (skb_headroom (skb ) < min_headroom || skb_header_cloned (skb )) {
@@ -476,6 +470,37 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
476
470
if (unlikely (err ))
477
471
goto err_free_rt ;
478
472
}
473
+ return rt ;
474
+
475
+ err_free_rt :
476
+ ip_rt_put (rt );
477
+ err_free_skb :
478
+ kfree_skb (skb );
479
+ dev -> stats .tx_dropped ++ ;
480
+ return NULL ;
481
+ }
482
+
483
+ static void gre_fb_xmit (struct sk_buff * skb , struct net_device * dev ,
484
+ __be16 proto )
485
+ {
486
+ struct ip_tunnel_info * tun_info ;
487
+ const struct ip_tunnel_key * key ;
488
+ struct rtable * rt = NULL ;
489
+ struct flowi4 fl ;
490
+ int tunnel_hlen ;
491
+ __be16 df , flags ;
492
+
493
+ tun_info = skb_tunnel_info (skb );
494
+ if (unlikely (!tun_info || !(tun_info -> mode & IP_TUNNEL_INFO_TX ) ||
495
+ ip_tunnel_info_af (tun_info ) != AF_INET ))
496
+ goto err_free_skb ;
497
+
498
+ key = & tun_info -> key ;
499
+ tunnel_hlen = gre_calc_hlen (key -> tun_flags );
500
+
501
+ rt = prepare_fb_xmit (skb , dev , & fl , tunnel_hlen );
502
+ if (!rt )
503
+ return ;
479
504
480
505
/* Push Tunnel header. */
481
506
if (gre_handle_offloads (skb , !!(tun_info -> key .tun_flags & TUNNEL_CSUM )))
0 commit comments