@@ -675,39 +675,37 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
675
675
return vh ;
676
676
}
677
677
678
- static struct sk_buff * vxlan_gro_receive (struct sock * sk ,
679
- struct list_head * head ,
680
- struct sk_buff * skb )
678
+ static struct vxlanhdr * vxlan_gro_prepare_receive (struct sock * sk ,
679
+ struct list_head * head ,
680
+ struct sk_buff * skb ,
681
+ struct gro_remcsum * grc )
681
682
{
682
- struct sk_buff * pp = NULL ;
683
683
struct sk_buff * p ;
684
684
struct vxlanhdr * vh , * vh2 ;
685
685
unsigned int hlen , off_vx ;
686
- int flush = 1 ;
687
686
struct vxlan_sock * vs = rcu_dereference_sk_user_data (sk );
688
687
__be32 flags ;
689
- struct gro_remcsum grc ;
690
688
691
- skb_gro_remcsum_init (& grc );
689
+ skb_gro_remcsum_init (grc );
692
690
693
691
off_vx = skb_gro_offset (skb );
694
692
hlen = off_vx + sizeof (* vh );
695
693
vh = skb_gro_header (skb , hlen , off_vx );
696
694
if (unlikely (!vh ))
697
- goto out ;
695
+ return NULL ;
698
696
699
697
skb_gro_postpull_rcsum (skb , vh , sizeof (struct vxlanhdr ));
700
698
701
699
flags = vh -> vx_flags ;
702
700
703
701
if ((flags & VXLAN_HF_RCO ) && (vs -> flags & VXLAN_F_REMCSUM_RX )) {
704
702
vh = vxlan_gro_remcsum (skb , off_vx , vh , sizeof (struct vxlanhdr ),
705
- vh -> vx_vni , & grc ,
703
+ vh -> vx_vni , grc ,
706
704
!!(vs -> flags &
707
705
VXLAN_F_REMCSUM_NOPARTIAL ));
708
706
709
707
if (!vh )
710
- goto out ;
708
+ return NULL ;
711
709
}
712
710
713
711
skb_gro_pull (skb , sizeof (struct vxlanhdr )); /* pull vxlan header */
@@ -724,12 +722,48 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk,
724
722
}
725
723
}
726
724
727
- pp = call_gro_receive (eth_gro_receive , head , skb );
728
- flush = 0 ;
725
+ return vh ;
726
+ }
727
+
728
+ static struct sk_buff * vxlan_gro_receive (struct sock * sk ,
729
+ struct list_head * head ,
730
+ struct sk_buff * skb )
731
+ {
732
+ struct sk_buff * pp = NULL ;
733
+ struct gro_remcsum grc ;
734
+ int flush = 1 ;
729
735
730
- out :
736
+ if (vxlan_gro_prepare_receive (sk , head , skb , & grc )) {
737
+ pp = call_gro_receive (eth_gro_receive , head , skb );
738
+ flush = 0 ;
739
+ }
731
740
skb_gro_flush_final_remcsum (skb , pp , flush , & grc );
741
+ return pp ;
742
+ }
732
743
744
+ static struct sk_buff * vxlan_gpe_gro_receive (struct sock * sk ,
745
+ struct list_head * head ,
746
+ struct sk_buff * skb )
747
+ {
748
+ const struct packet_offload * ptype ;
749
+ struct sk_buff * pp = NULL ;
750
+ struct gro_remcsum grc ;
751
+ struct vxlanhdr * vh ;
752
+ __be16 protocol ;
753
+ int flush = 1 ;
754
+
755
+ vh = vxlan_gro_prepare_receive (sk , head , skb , & grc );
756
+ if (vh ) {
757
+ if (!vxlan_parse_gpe_proto (vh , & protocol ))
758
+ goto out ;
759
+ ptype = gro_find_receive_by_type (protocol );
760
+ if (!ptype )
761
+ goto out ;
762
+ pp = call_gro_receive (ptype -> callbacks .gro_receive , head , skb );
763
+ flush = 0 ;
764
+ }
765
+ out :
766
+ skb_gro_flush_final_remcsum (skb , pp , flush , & grc );
733
767
return pp ;
734
768
}
735
769
@@ -741,6 +775,21 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
741
775
return eth_gro_complete (skb , nhoff + sizeof (struct vxlanhdr ));
742
776
}
743
777
778
+ static int vxlan_gpe_gro_complete (struct sock * sk , struct sk_buff * skb , int nhoff )
779
+ {
780
+ struct vxlanhdr * vh = (struct vxlanhdr * )(skb -> data + nhoff );
781
+ const struct packet_offload * ptype ;
782
+ int err = - ENOSYS ;
783
+ __be16 protocol ;
784
+
785
+ if (!vxlan_parse_gpe_proto (vh , & protocol ))
786
+ return err ;
787
+ ptype = gro_find_complete_by_type (protocol );
788
+ if (ptype )
789
+ err = ptype -> callbacks .gro_complete (skb , nhoff + sizeof (struct vxlanhdr ));
790
+ return err ;
791
+ }
792
+
744
793
static struct vxlan_fdb * vxlan_fdb_alloc (struct vxlan_dev * vxlan , const u8 * mac ,
745
794
__u16 state , __be32 src_vni ,
746
795
__u16 ndm_flags )
@@ -3376,8 +3425,13 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
3376
3425
tunnel_cfg .encap_rcv = vxlan_rcv ;
3377
3426
tunnel_cfg .encap_err_lookup = vxlan_err_lookup ;
3378
3427
tunnel_cfg .encap_destroy = NULL ;
3379
- tunnel_cfg .gro_receive = vxlan_gro_receive ;
3380
- tunnel_cfg .gro_complete = vxlan_gro_complete ;
3428
+ if (vs -> flags & VXLAN_F_GPE ) {
3429
+ tunnel_cfg .gro_receive = vxlan_gpe_gro_receive ;
3430
+ tunnel_cfg .gro_complete = vxlan_gpe_gro_complete ;
3431
+ } else {
3432
+ tunnel_cfg .gro_receive = vxlan_gro_receive ;
3433
+ tunnel_cfg .gro_complete = vxlan_gro_complete ;
3434
+ }
3381
3435
3382
3436
setup_udp_tunnel_sock (net , sock , & tunnel_cfg );
3383
3437
0 commit comments