@@ -238,6 +238,7 @@ static void ip6_dev_free(struct net_device *dev)
238238{
239239 struct ip6_tnl * t = netdev_priv (dev );
240240
241+ gro_cells_destroy (& t -> gro_cells );
241242 dst_cache_destroy (& t -> dst_cache );
242243 free_percpu (dev -> tstats );
243244 free_netdev (dev );
@@ -753,97 +754,157 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
753754}
754755EXPORT_SYMBOL_GPL (ip6_tnl_rcv_ctl );
755756
756- /**
757- * ip6_tnl_rcv - decapsulate IPv6 packet and retransmit it locally
758- * @skb: received socket buffer
759- * @protocol: ethernet protocol ID
760- * @dscp_ecn_decapsulate: the function to decapsulate DSCP code and ECN
761- *
762- * Return: 0
763- **/
764-
765- static int ip6_tnl_rcv (struct sk_buff * skb , __u16 protocol ,
766- __u8 ipproto ,
767- int (* dscp_ecn_decapsulate )(const struct ip6_tnl * t ,
768- const struct ipv6hdr * ipv6h ,
769- struct sk_buff * skb ))
757+ static int __ip6_tnl_rcv (struct ip6_tnl * tunnel , struct sk_buff * skb ,
758+ const struct tnl_ptk_info * tpi ,
759+ struct metadata_dst * tun_dst ,
760+ int (* dscp_ecn_decapsulate )(const struct ip6_tnl * t ,
761+ const struct ipv6hdr * ipv6h ,
762+ struct sk_buff * skb ),
763+ bool log_ecn_err )
770764{
771- struct ip6_tnl * t ;
765+ struct pcpu_sw_netstats * tstats ;
772766 const struct ipv6hdr * ipv6h = ipv6_hdr (skb );
773- u8 tproto ;
774767 int err ;
775768
776- rcu_read_lock ();
777- t = ip6_tnl_lookup (dev_net (skb -> dev ), & ipv6h -> saddr , & ipv6h -> daddr );
778- if (t ) {
779- struct pcpu_sw_netstats * tstats ;
769+ if ((!(tpi -> flags & TUNNEL_CSUM ) &&
770+ (tunnel -> parms .i_flags & TUNNEL_CSUM )) ||
771+ ((tpi -> flags & TUNNEL_CSUM ) &&
772+ !(tunnel -> parms .i_flags & TUNNEL_CSUM ))) {
773+ tunnel -> dev -> stats .rx_crc_errors ++ ;
774+ tunnel -> dev -> stats .rx_errors ++ ;
775+ goto drop ;
776+ }
780777
781- tproto = ACCESS_ONCE (t -> parms .proto );
782- if (tproto != ipproto && tproto != 0 ) {
783- rcu_read_unlock ();
784- goto discard ;
778+ if (tunnel -> parms .i_flags & TUNNEL_SEQ ) {
779+ if (!(tpi -> flags & TUNNEL_SEQ ) ||
780+ (tunnel -> i_seqno &&
781+ (s32 )(ntohl (tpi -> seq ) - tunnel -> i_seqno ) < 0 )) {
782+ tunnel -> dev -> stats .rx_fifo_errors ++ ;
783+ tunnel -> dev -> stats .rx_errors ++ ;
784+ goto drop ;
785785 }
786+ tunnel -> i_seqno = ntohl (tpi -> seq ) + 1 ;
787+ }
786788
787- if (!xfrm6_policy_check (NULL , XFRM_POLICY_IN , skb )) {
788- rcu_read_unlock ();
789- goto discard ;
790- }
789+ skb -> protocol = tpi -> proto ;
791790
792- if (!ip6_tnl_rcv_ctl (t , & ipv6h -> daddr , & ipv6h -> saddr )) {
793- t -> dev -> stats .rx_dropped ++ ;
794- rcu_read_unlock ();
795- goto discard ;
791+ /* Warning: All skb pointers will be invalidated! */
792+ if (tunnel -> dev -> type == ARPHRD_ETHER ) {
793+ if (!pskb_may_pull (skb , ETH_HLEN )) {
794+ tunnel -> dev -> stats .rx_length_errors ++ ;
795+ tunnel -> dev -> stats .rx_errors ++ ;
796+ goto drop ;
796797 }
797- skb -> mac_header = skb -> network_header ;
798- skb_reset_network_header (skb );
799- skb -> protocol = htons (protocol );
800- memset (skb -> cb , 0 , sizeof (struct inet6_skb_parm ));
801-
802- __skb_tunnel_rx (skb , t -> dev , t -> net );
803-
804- err = dscp_ecn_decapsulate (t , ipv6h , skb );
805- if (unlikely (err )) {
806- if (log_ecn_error )
807- net_info_ratelimited ("non-ECT from %pI6 with dsfield=%#x\n" ,
808- & ipv6h -> saddr ,
809- ipv6_get_dsfield (ipv6h ));
810- if (err > 1 ) {
811- ++ t -> dev -> stats .rx_frame_errors ;
812- ++ t -> dev -> stats .rx_errors ;
813- rcu_read_unlock ();
814- goto discard ;
815- }
798+
799+ ipv6h = ipv6_hdr (skb );
800+ skb -> protocol = eth_type_trans (skb , tunnel -> dev );
801+ skb_postpull_rcsum (skb , eth_hdr (skb ), ETH_HLEN );
802+ } else {
803+ skb -> dev = tunnel -> dev ;
804+ }
805+
806+ skb_reset_network_header (skb );
807+ memset (skb -> cb , 0 , sizeof (struct inet6_skb_parm ));
808+
809+ __skb_tunnel_rx (skb , tunnel -> dev , tunnel -> net );
810+
811+ err = dscp_ecn_decapsulate (tunnel , ipv6h , skb );
812+ if (unlikely (err )) {
813+ if (log_ecn_err )
814+ net_info_ratelimited ("non-ECT from %pI6 with DS=%#x\n" ,
815+ & ipv6h -> saddr ,
816+ ipv6_get_dsfield (ipv6h ));
817+ if (err > 1 ) {
818+ ++ tunnel -> dev -> stats .rx_frame_errors ;
819+ ++ tunnel -> dev -> stats .rx_errors ;
820+ goto drop ;
816821 }
822+ }
817823
818- tstats = this_cpu_ptr (t -> dev -> tstats );
819- u64_stats_update_begin (& tstats -> syncp );
820- tstats -> rx_packets ++ ;
821- tstats -> rx_bytes += skb -> len ;
822- u64_stats_update_end (& tstats -> syncp );
824+ tstats = this_cpu_ptr (tunnel -> dev -> tstats );
825+ u64_stats_update_begin (& tstats -> syncp );
826+ tstats -> rx_packets ++ ;
827+ tstats -> rx_bytes += skb -> len ;
828+ u64_stats_update_end (& tstats -> syncp );
823829
824- netif_rx (skb );
830+ skb_scrub_packet (skb , ! net_eq ( tunnel -> net , dev_net ( tunnel -> dev )) );
825831
826- rcu_read_unlock ();
827- return 0 ;
832+ gro_cells_receive (& tunnel -> gro_cells , skb );
833+ return 0 ;
834+
835+ drop :
836+ kfree_skb (skb );
837+ return 0 ;
838+ }
839+
840+ int ip6_tnl_rcv (struct ip6_tnl * t , struct sk_buff * skb ,
841+ const struct tnl_ptk_info * tpi ,
842+ struct metadata_dst * tun_dst ,
843+ bool log_ecn_err )
844+ {
845+ return __ip6_tnl_rcv (t , skb , tpi , NULL , ip6ip6_dscp_ecn_decapsulate ,
846+ log_ecn_err );
847+ }
848+ EXPORT_SYMBOL (ip6_tnl_rcv );
849+
850+ static const struct tnl_ptk_info tpi_v6 = {
851+ /* no tunnel info required for ipxip6. */
852+ .proto = htons (ETH_P_IPV6 ),
853+ };
854+
855+ static const struct tnl_ptk_info tpi_v4 = {
856+ /* no tunnel info required for ipxip6. */
857+ .proto = htons (ETH_P_IP ),
858+ };
859+
860+ static int ipxip6_rcv (struct sk_buff * skb , u8 ipproto ,
861+ const struct tnl_ptk_info * tpi ,
862+ int (* dscp_ecn_decapsulate )(const struct ip6_tnl * t ,
863+ const struct ipv6hdr * ipv6h ,
864+ struct sk_buff * skb ))
865+ {
866+ struct ip6_tnl * t ;
867+ const struct ipv6hdr * ipv6h = ipv6_hdr (skb );
868+ int ret = -1 ;
869+
870+ rcu_read_lock ();
871+ t = ip6_tnl_lookup (dev_net (skb -> dev ), & ipv6h -> saddr , & ipv6h -> daddr );
872+
873+ if (t ) {
874+ u8 tproto = ACCESS_ONCE (t -> parms .proto );
875+
876+ if (tproto != ipproto && tproto != 0 )
877+ goto drop ;
878+ if (!xfrm6_policy_check (NULL , XFRM_POLICY_IN , skb ))
879+ goto drop ;
880+ if (!ip6_tnl_rcv_ctl (t , & ipv6h -> daddr , & ipv6h -> saddr ))
881+ goto drop ;
882+ if (iptunnel_pull_header (skb , 0 , tpi -> proto , false))
883+ goto drop ;
884+ ret = __ip6_tnl_rcv (t , skb , tpi , NULL , dscp_ecn_decapsulate ,
885+ log_ecn_error );
828886 }
887+
829888 rcu_read_unlock ();
830- return 1 ;
831889
832- discard :
890+ return ret ;
891+
892+ drop :
893+ rcu_read_unlock ();
833894 kfree_skb (skb );
834895 return 0 ;
835896}
836897
837898static int ip4ip6_rcv (struct sk_buff * skb )
838899{
839- return ip6_tnl_rcv (skb , ETH_P_IP , IPPROTO_IPIP ,
840- ip4ip6_dscp_ecn_decapsulate );
900+ return ipxip6_rcv (skb , IPPROTO_IP , & tpi_v4 ,
901+ ip4ip6_dscp_ecn_decapsulate );
841902}
842903
843904static int ip6ip6_rcv (struct sk_buff * skb )
844905{
845- return ip6_tnl_rcv (skb , ETH_P_IPV6 , IPPROTO_IPV6 ,
846- ip6ip6_dscp_ecn_decapsulate );
906+ return ipxip6_rcv (skb , IPPROTO_IPV6 , & tpi_v6 ,
907+ ip6ip6_dscp_ecn_decapsulate );
847908}
848909
849910struct ipv6_tel_txoption {
@@ -1370,6 +1431,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
13701431 struct net * net = t -> net ;
13711432 struct ip6_tnl_net * ip6n = net_generic (net , ip6_tnl_net_id );
13721433
1434+ memset (& p1 , 0 , sizeof (p1 ));
1435+
13731436 switch (cmd ) {
13741437 case SIOCGETTUNNEL :
13751438 if (dev == ip6n -> fb_tnl_dev ) {
@@ -1549,13 +1612,22 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
15491612 return - ENOMEM ;
15501613
15511614 ret = dst_cache_init (& t -> dst_cache , GFP_KERNEL );
1552- if (ret ) {
1553- free_percpu (dev -> tstats );
1554- dev -> tstats = NULL ;
1555- return ret ;
1556- }
1615+ if (ret )
1616+ goto free_stats ;
1617+
1618+ ret = gro_cells_init (& t -> gro_cells , dev );
1619+ if (ret )
1620+ goto destroy_dst ;
15571621
15581622 return 0 ;
1623+
1624+ destroy_dst :
1625+ dst_cache_destroy (& t -> dst_cache );
1626+ free_stats :
1627+ free_percpu (dev -> tstats );
1628+ dev -> tstats = NULL ;
1629+
1630+ return ret ;
15591631}
15601632
15611633/**
0 commit comments