@@ -380,30 +380,22 @@ vti6_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
380
380
* vti6_xmit - send a packet
381
381
* @skb: the outgoing socket buffer
382
382
* @dev: the outgoing tunnel device
383
+ * @fl: the flow informations for the xfrm_lookup
383
384
**/
384
- static int vti6_xmit (struct sk_buff * skb , struct net_device * dev )
385
+ static int
386
+ vti6_xmit (struct sk_buff * skb , struct net_device * dev , struct flowi * fl )
385
387
{
386
388
struct ip6_tnl * t = netdev_priv (dev );
387
389
struct net_device_stats * stats = & t -> dev -> stats ;
388
390
struct dst_entry * dst = skb_dst (skb );
389
- struct flowi fl ;
390
- struct ipv6hdr * ipv6h = ipv6_hdr (skb );
391
391
struct net_device * tdev ;
392
392
int err = -1 ;
393
393
394
- if ((t -> parms .proto != IPPROTO_IPV6 && t -> parms .proto != 0 ) ||
395
- !ip6_tnl_xmit_ctl (t ) || vti6_addr_conflict (t , ipv6h ))
396
- return err ;
397
-
398
- memset (& fl , 0 , sizeof (fl ));
399
- skb -> mark = be32_to_cpu (t -> parms .o_key );
400
- xfrm_decode_session (skb , & fl , AF_INET6 );
401
-
402
394
if (!dst )
403
395
goto tx_err_link_failure ;
404
396
405
397
dst_hold (dst );
406
- dst = xfrm_lookup (t -> net , dst , & fl , NULL , 0 );
398
+ dst = xfrm_lookup (t -> net , dst , fl , NULL , 0 );
407
399
if (IS_ERR (dst )) {
408
400
err = PTR_ERR (dst );
409
401
dst = NULL ;
@@ -422,12 +414,22 @@ static int vti6_xmit(struct sk_buff *skb, struct net_device *dev)
422
414
goto tx_err_dst_release ;
423
415
}
424
416
425
- memset (IP6CB (skb ), 0 , sizeof (* IP6CB (skb )));
426
417
skb_scrub_packet (skb , !net_eq (t -> net , dev_net (dev )));
427
418
skb_dst_set (skb , dst );
428
419
skb -> dev = skb_dst (skb )-> dev ;
429
420
430
- ip6tunnel_xmit (skb , dev );
421
+ err = dst_output (skb );
422
+ if (net_xmit_eval (err ) == 0 ) {
423
+ struct pcpu_sw_netstats * tstats = this_cpu_ptr (dev -> tstats );
424
+
425
+ u64_stats_update_begin (& tstats -> syncp );
426
+ tstats -> tx_bytes += skb -> len ;
427
+ tstats -> tx_packets ++ ;
428
+ u64_stats_update_end (& tstats -> syncp );
429
+ } else {
430
+ stats -> tx_errors ++ ;
431
+ stats -> tx_aborted_errors ++ ;
432
+ }
431
433
432
434
return 0 ;
433
435
tx_err_link_failure :
@@ -443,16 +445,33 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
443
445
{
444
446
struct ip6_tnl * t = netdev_priv (dev );
445
447
struct net_device_stats * stats = & t -> dev -> stats ;
448
+ struct ipv6hdr * ipv6h ;
449
+ struct flowi fl ;
446
450
int ret ;
447
451
452
+ memset (& fl , 0 , sizeof (fl ));
453
+ skb -> mark = be32_to_cpu (t -> parms .o_key );
454
+
448
455
switch (skb -> protocol ) {
449
456
case htons (ETH_P_IPV6 ):
450
- ret = vti6_xmit (skb , dev );
457
+ ipv6h = ipv6_hdr (skb );
458
+
459
+ if ((t -> parms .proto != IPPROTO_IPV6 && t -> parms .proto != 0 ) ||
460
+ !ip6_tnl_xmit_ctl (t ) || vti6_addr_conflict (t , ipv6h ))
461
+ goto tx_err ;
462
+
463
+ xfrm_decode_session (skb , & fl , AF_INET6 );
464
+ memset (IP6CB (skb ), 0 , sizeof (* IP6CB (skb )));
465
+ break ;
466
+ case htons (ETH_P_IP ):
467
+ xfrm_decode_session (skb , & fl , AF_INET );
468
+ memset (IPCB (skb ), 0 , sizeof (* IPCB (skb )));
451
469
break ;
452
470
default :
453
471
goto tx_err ;
454
472
}
455
473
474
+ ret = vti6_xmit (skb , dev , & fl );
456
475
if (ret < 0 )
457
476
goto tx_err ;
458
477
0 commit comments