@@ -488,199 +488,40 @@ struct ipv6_tel_txoption {
488
488
__u8 dst_opt [8 ];
489
489
};
490
490
491
- static void init_tel_txopt (struct ipv6_tel_txoption * opt , __u8 encap_limit )
491
+ static int gre_handle_offloads (struct sk_buff * skb , bool csum )
492
492
{
493
- memset (opt , 0 , sizeof (struct ipv6_tel_txoption ));
494
-
495
- opt -> dst_opt [2 ] = IPV6_TLV_TNL_ENCAP_LIMIT ;
496
- opt -> dst_opt [3 ] = 1 ;
497
- opt -> dst_opt [4 ] = encap_limit ;
498
- opt -> dst_opt [5 ] = IPV6_TLV_PADN ;
499
- opt -> dst_opt [6 ] = 1 ;
500
-
501
- opt -> ops .dst0opt = (struct ipv6_opt_hdr * ) opt -> dst_opt ;
502
- opt -> ops .opt_nflen = 8 ;
493
+ return iptunnel_handle_offloads (skb ,
494
+ csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE );
503
495
}
504
496
505
- static __sum16 gre6_checksum (struct sk_buff * skb )
506
- {
507
- __wsum csum ;
508
-
509
- if (skb -> ip_summed == CHECKSUM_PARTIAL )
510
- csum = lco_csum (skb );
511
- else
512
- csum = skb_checksum (skb , sizeof (struct ipv6hdr ),
513
- skb -> len - sizeof (struct ipv6hdr ), 0 );
514
- return csum_fold (csum );
515
- }
516
-
517
- static netdev_tx_t ip6gre_xmit2 (struct sk_buff * skb ,
518
- struct net_device * dev ,
519
- __u8 dsfield ,
520
- struct flowi6 * fl6 ,
521
- int encap_limit ,
522
- __u32 * pmtu )
497
+ static netdev_tx_t __gre6_xmit (struct sk_buff * skb ,
498
+ struct net_device * dev , __u8 dsfield ,
499
+ struct flowi6 * fl6 , int encap_limit ,
500
+ __u32 * pmtu , __be16 proto )
523
501
{
524
502
struct ip6_tnl * tunnel = netdev_priv (dev );
525
- struct net * net = tunnel -> net ;
526
- struct net_device * tdev ; /* Device to other host */
527
- struct ipv6hdr * ipv6h ; /* Our new IP header */
528
- unsigned int min_headroom = 0 ; /* The extra header space needed */
529
- int gre_hlen ;
530
- struct ipv6_tel_txoption opt ;
531
- int mtu ;
532
- struct dst_entry * dst = NULL , * ndst = NULL ;
533
- struct net_device_stats * stats = & tunnel -> dev -> stats ;
534
- int err = -1 ;
535
- u8 proto ;
536
- __be16 protocol ;
503
+ __be16 protocol = (dev -> type == ARPHRD_ETHER ) ?
504
+ htons (ETH_P_TEB ) : proto ;
537
505
538
506
if (dev -> type == ARPHRD_ETHER )
539
507
IPCB (skb )-> flags = 0 ;
540
508
541
- if (dev -> header_ops && dev -> type == ARPHRD_IP6GRE ) {
542
- gre_hlen = 0 ;
543
- ipv6h = (struct ipv6hdr * )skb -> data ;
544
- fl6 -> daddr = ipv6h -> daddr ;
545
- } else {
546
- gre_hlen = tunnel -> hlen ;
509
+ if (dev -> header_ops && dev -> type == ARPHRD_IP6GRE )
510
+ fl6 -> daddr = ((struct ipv6hdr * )skb -> data )-> daddr ;
511
+ else
547
512
fl6 -> daddr = tunnel -> parms .raddr ;
548
- }
549
-
550
- if (!fl6 -> flowi6_mark )
551
- dst = dst_cache_get (& tunnel -> dst_cache );
552
-
553
- if (!dst ) {
554
- dst = ip6_route_output (net , NULL , fl6 );
555
-
556
- if (dst -> error )
557
- goto tx_err_link_failure ;
558
- dst = xfrm_lookup (net , dst , flowi6_to_flowi (fl6 ), NULL , 0 );
559
- if (IS_ERR (dst )) {
560
- err = PTR_ERR (dst );
561
- dst = NULL ;
562
- goto tx_err_link_failure ;
563
- }
564
- ndst = dst ;
565
- }
566
-
567
- tdev = dst -> dev ;
568
-
569
- if (tdev == dev ) {
570
- stats -> collisions ++ ;
571
- net_warn_ratelimited ("%s: Local routing loop detected!\n" ,
572
- tunnel -> parms .name );
573
- goto tx_err_dst_release ;
574
- }
575
513
576
- mtu = dst_mtu (dst ) - sizeof (* ipv6h );
577
- if (encap_limit >= 0 ) {
578
- min_headroom += 8 ;
579
- mtu -= 8 ;
580
- }
581
- if (mtu < IPV6_MIN_MTU )
582
- mtu = IPV6_MIN_MTU ;
583
- if (skb_dst (skb ))
584
- skb_dst (skb )-> ops -> update_pmtu (skb_dst (skb ), NULL , skb , mtu );
585
- if (skb -> len > mtu && !skb_is_gso (skb )) {
586
- * pmtu = mtu ;
587
- err = - EMSGSIZE ;
588
- goto tx_err_dst_release ;
589
- }
514
+ if (tunnel -> parms .o_flags & TUNNEL_SEQ )
515
+ tunnel -> o_seqno ++ ;
590
516
591
- if (tunnel -> err_count > 0 ) {
592
- if (time_before (jiffies ,
593
- tunnel -> err_time + IP6TUNNEL_ERR_TIMEO )) {
594
- tunnel -> err_count -- ;
517
+ /* Push GRE header. */
518
+ gre_build_header (skb , tunnel -> tun_hlen , tunnel -> parms .o_flags ,
519
+ protocol , tunnel -> parms .o_key , htonl (tunnel -> o_seqno ));
595
520
596
- dst_link_failure (skb );
597
- } else
598
- tunnel -> err_count = 0 ;
599
- }
521
+ skb_set_inner_protocol (skb , proto );
600
522
601
- skb_scrub_packet (skb , !net_eq (tunnel -> net , dev_net (dev )));
602
-
603
- min_headroom += LL_RESERVED_SPACE (tdev ) + gre_hlen + dst -> header_len ;
604
-
605
- if (skb_headroom (skb ) < min_headroom || skb_header_cloned (skb )) {
606
- int head_delta = SKB_DATA_ALIGN (min_headroom -
607
- skb_headroom (skb ) +
608
- 16 );
609
-
610
- err = pskb_expand_head (skb , max_t (int , head_delta , 0 ),
611
- 0 , GFP_ATOMIC );
612
- if (min_headroom > dev -> needed_headroom )
613
- dev -> needed_headroom = min_headroom ;
614
- if (unlikely (err ))
615
- goto tx_err_dst_release ;
616
- }
617
-
618
- if (!fl6 -> flowi6_mark && ndst )
619
- dst_cache_set_ip6 (& tunnel -> dst_cache , ndst , & fl6 -> saddr );
620
- skb_dst_set (skb , dst );
621
-
622
- proto = NEXTHDR_GRE ;
623
- if (encap_limit >= 0 ) {
624
- init_tel_txopt (& opt , encap_limit );
625
- ipv6_push_nfrag_opts (skb , & opt .ops , & proto , NULL );
626
- }
627
-
628
- err = iptunnel_handle_offloads (skb ,
629
- (tunnel -> parms .o_flags & GRE_CSUM ) ?
630
- SKB_GSO_GRE_CSUM : SKB_GSO_GRE );
631
- if (err )
632
- goto tx_err_dst_release ;
633
-
634
- skb_push (skb , gre_hlen );
635
- skb_reset_network_header (skb );
636
- skb_set_transport_header (skb , sizeof (* ipv6h ));
637
-
638
- /*
639
- * Push down and install the IP header.
640
- */
641
- ipv6h = ipv6_hdr (skb );
642
- ip6_flow_hdr (ipv6h , INET_ECN_encapsulate (0 , dsfield ),
643
- ip6_make_flowlabel (net , skb , fl6 -> flowlabel , true, fl6 ));
644
- ipv6h -> hop_limit = tunnel -> parms .hop_limit ;
645
- ipv6h -> nexthdr = proto ;
646
- ipv6h -> saddr = fl6 -> saddr ;
647
- ipv6h -> daddr = fl6 -> daddr ;
648
-
649
- ((__be16 * )(ipv6h + 1 ))[0 ] = tunnel -> parms .o_flags ;
650
- protocol = (dev -> type == ARPHRD_ETHER ) ?
651
- htons (ETH_P_TEB ) : skb -> protocol ;
652
- ((__be16 * )(ipv6h + 1 ))[1 ] = protocol ;
653
-
654
- if (tunnel -> parms .o_flags & (GRE_KEY |GRE_CSUM |GRE_SEQ )) {
655
- __be32 * ptr = (__be32 * )(((u8 * )ipv6h ) + tunnel -> hlen - 4 );
656
-
657
- if (tunnel -> parms .o_flags & GRE_SEQ ) {
658
- ++ tunnel -> o_seqno ;
659
- * ptr = htonl (tunnel -> o_seqno );
660
- ptr -- ;
661
- }
662
- if (tunnel -> parms .o_flags & GRE_KEY ) {
663
- * ptr = tunnel -> parms .o_key ;
664
- ptr -- ;
665
- }
666
- if ((tunnel -> parms .o_flags & GRE_CSUM ) &&
667
- !(skb_shinfo (skb )-> gso_type &
668
- (SKB_GSO_GRE | SKB_GSO_GRE_CSUM ))) {
669
- * ptr = 0 ;
670
- * (__sum16 * )ptr = gre6_checksum (skb );
671
- }
672
- }
673
-
674
- skb_set_inner_protocol (skb , protocol );
675
-
676
- ip6tunnel_xmit (NULL , skb , dev );
677
- return 0 ;
678
- tx_err_link_failure :
679
- stats -> tx_carrier_errors ++ ;
680
- dst_link_failure (skb );
681
- tx_err_dst_release :
682
- dst_release (dst );
683
- return err ;
523
+ return ip6_tnl_xmit (skb , dev , dsfield , fl6 , encap_limit , pmtu ,
524
+ NEXTHDR_GRE );
684
525
}
685
526
686
527
static inline int ip6gre_xmit_ipv4 (struct sk_buff * skb , struct net_device * dev )
@@ -699,7 +540,6 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
699
540
encap_limit = t -> parms .encap_limit ;
700
541
701
542
memcpy (& fl6 , & t -> fl .u .ip6 , sizeof (fl6 ));
702
- fl6 .flowi6_proto = IPPROTO_GRE ;
703
543
704
544
dsfield = ipv4_get_dsfield (iph );
705
545
@@ -709,7 +549,12 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
709
549
if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
710
550
fl6 .flowi6_mark = skb -> mark ;
711
551
712
- err = ip6gre_xmit2 (skb , dev , dsfield , & fl6 , encap_limit , & mtu );
552
+ err = gre_handle_offloads (skb , !!(t -> parms .o_flags & TUNNEL_CSUM ));
553
+ if (err )
554
+ return -1 ;
555
+
556
+ err = __gre6_xmit (skb , dev , dsfield , & fl6 , encap_limit , & mtu ,
557
+ skb -> protocol );
713
558
if (err != 0 ) {
714
559
/* XXX: send ICMP error even if DF is not set. */
715
560
if (err == - EMSGSIZE )
@@ -749,7 +594,6 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
749
594
encap_limit = t -> parms .encap_limit ;
750
595
751
596
memcpy (& fl6 , & t -> fl .u .ip6 , sizeof (fl6 ));
752
- fl6 .flowi6_proto = IPPROTO_GRE ;
753
597
754
598
dsfield = ipv6_get_dsfield (ipv6h );
755
599
if (t -> parms .flags & IP6_TNL_F_USE_ORIG_TCLASS )
@@ -759,7 +603,11 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
759
603
if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
760
604
fl6 .flowi6_mark = skb -> mark ;
761
605
762
- err = ip6gre_xmit2 (skb , dev , dsfield , & fl6 , encap_limit , & mtu );
606
+ if (gre_handle_offloads (skb , !!(t -> parms .o_flags & TUNNEL_CSUM )))
607
+ return -1 ;
608
+
609
+ err = __gre6_xmit (skb , dev , dsfield , & fl6 , encap_limit ,
610
+ & mtu , skb -> protocol );
763
611
if (err != 0 ) {
764
612
if (err == - EMSGSIZE )
765
613
icmpv6_send (skb , ICMPV6_PKT_TOOBIG , 0 , mtu );
@@ -803,7 +651,11 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev)
803
651
memcpy (& fl6 , & t -> fl .u .ip6 , sizeof (fl6 ));
804
652
fl6 .flowi6_proto = skb -> protocol ;
805
653
806
- err = ip6gre_xmit2 (skb , dev , 0 , & fl6 , encap_limit , & mtu );
654
+ err = gre_handle_offloads (skb , !!(t -> parms .o_flags & TUNNEL_CSUM ));
655
+ if (err )
656
+ return err ;
657
+
658
+ err = __gre6_xmit (skb , dev , 0 , & fl6 , encap_limit , & mtu , skb -> protocol );
807
659
808
660
return err ;
809
661
}
@@ -1080,15 +932,6 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
1080
932
return err ;
1081
933
}
1082
934
1083
- static int ip6gre_tunnel_change_mtu (struct net_device * dev , int new_mtu )
1084
- {
1085
- if (new_mtu < 68 ||
1086
- new_mtu > 0xFFF8 - dev -> hard_header_len )
1087
- return - EINVAL ;
1088
- dev -> mtu = new_mtu ;
1089
- return 0 ;
1090
- }
1091
-
1092
935
static int ip6gre_header (struct sk_buff * skb , struct net_device * dev ,
1093
936
unsigned short type ,
1094
937
const void * daddr , const void * saddr , unsigned int len )
@@ -1132,7 +975,7 @@ static const struct net_device_ops ip6gre_netdev_ops = {
1132
975
.ndo_uninit = ip6gre_tunnel_uninit ,
1133
976
.ndo_start_xmit = ip6gre_tunnel_xmit ,
1134
977
.ndo_do_ioctl = ip6gre_tunnel_ioctl ,
1135
- .ndo_change_mtu = ip6gre_tunnel_change_mtu ,
978
+ .ndo_change_mtu = ip6_tnl_change_mtu ,
1136
979
.ndo_get_stats64 = ip_tunnel_get_stats64 ,
1137
980
.ndo_get_iflink = ip6_tnl_get_iflink ,
1138
981
};
@@ -1148,17 +991,11 @@ static void ip6gre_dev_free(struct net_device *dev)
1148
991
1149
992
static void ip6gre_tunnel_setup (struct net_device * dev )
1150
993
{
1151
- struct ip6_tnl * t ;
1152
-
1153
994
dev -> netdev_ops = & ip6gre_netdev_ops ;
1154
995
dev -> destructor = ip6gre_dev_free ;
1155
996
1156
997
dev -> type = ARPHRD_IP6GRE ;
1157
- dev -> hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr ) + 4 ;
1158
- dev -> mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr ) - 4 ;
1159
- t = netdev_priv (dev );
1160
- if (!(t -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
1161
- dev -> mtu -= 8 ;
998
+
1162
999
dev -> flags |= IFF_NOARP ;
1163
1000
dev -> addr_len = sizeof (struct in6_addr );
1164
1001
netif_keep_dst (dev );
@@ -1168,6 +1005,7 @@ static int ip6gre_tunnel_init_common(struct net_device *dev)
1168
1005
{
1169
1006
struct ip6_tnl * tunnel ;
1170
1007
int ret ;
1008
+ int t_hlen ;
1171
1009
1172
1010
tunnel = netdev_priv (dev );
1173
1011
@@ -1186,6 +1024,16 @@ static int ip6gre_tunnel_init_common(struct net_device *dev)
1186
1024
return ret ;
1187
1025
}
1188
1026
1027
+ tunnel -> tun_hlen = gre_calc_hlen (tunnel -> parms .o_flags );
1028
+
1029
+ t_hlen = tunnel -> hlen + sizeof (struct ipv6hdr );
1030
+
1031
+ dev -> needed_headroom = LL_MAX_HEADER + t_hlen + 4 ;
1032
+ dev -> mtu = ETH_DATA_LEN - t_hlen - 4 ;
1033
+
1034
+ if (!(tunnel -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
1035
+ dev -> mtu -= 8 ;
1036
+
1189
1037
return 0 ;
1190
1038
}
1191
1039
@@ -1420,7 +1268,7 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
1420
1268
.ndo_start_xmit = ip6gre_tunnel_xmit ,
1421
1269
.ndo_set_mac_address = eth_mac_addr ,
1422
1270
.ndo_validate_addr = eth_validate_addr ,
1423
- .ndo_change_mtu = ip6gre_tunnel_change_mtu ,
1271
+ .ndo_change_mtu = ip6_tnl_change_mtu ,
1424
1272
.ndo_get_stats64 = ip_tunnel_get_stats64 ,
1425
1273
.ndo_get_iflink = ip6_tnl_get_iflink ,
1426
1274
};
0 commit comments