@@ -657,6 +657,45 @@ static void xsk_drop_skb(struct sk_buff *skb)
657657 xsk_consume_skb (skb );
658658}
659659
660+ static int xsk_skb_metadata (struct sk_buff * skb , void * buffer ,
661+ struct xdp_desc * desc , struct xsk_buff_pool * pool ,
662+ u32 hr )
663+ {
664+ struct xsk_tx_metadata * meta = NULL ;
665+
666+ if (unlikely (pool -> tx_metadata_len == 0 ))
667+ return - EINVAL ;
668+
669+ meta = buffer - pool -> tx_metadata_len ;
670+ if (unlikely (!xsk_buff_valid_tx_metadata (meta )))
671+ return - EINVAL ;
672+
673+ if (meta -> flags & XDP_TXMD_FLAGS_CHECKSUM ) {
674+ if (unlikely (meta -> request .csum_start +
675+ meta -> request .csum_offset +
676+ sizeof (__sum16 ) > desc -> len ))
677+ return - EINVAL ;
678+
679+ skb -> csum_start = hr + meta -> request .csum_start ;
680+ skb -> csum_offset = meta -> request .csum_offset ;
681+ skb -> ip_summed = CHECKSUM_PARTIAL ;
682+
683+ if (unlikely (pool -> tx_sw_csum )) {
684+ int err ;
685+
686+ err = skb_checksum_help (skb );
687+ if (err )
688+ return err ;
689+ }
690+ }
691+
692+ if (meta -> flags & XDP_TXMD_FLAGS_LAUNCH_TIME )
693+ skb -> skb_mstamp_ns = meta -> request .launch_time ;
694+ xsk_tx_metadata_to_compl (meta , & skb_shinfo (skb )-> xsk_meta );
695+
696+ return 0 ;
697+ }
698+
660699static struct sk_buff * xsk_build_skb_zerocopy (struct xdp_sock * xs ,
661700 struct xdp_desc * desc )
662701{
@@ -669,6 +708,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
669708 int err , i ;
670709 u64 addr ;
671710
711+ addr = desc -> addr ;
712+ buffer = xsk_buff_raw_get_data (pool , addr );
713+
672714 if (!skb ) {
673715 hr = max (NET_SKB_PAD , L1_CACHE_ALIGN (xs -> dev -> needed_headroom ));
674716
@@ -679,6 +721,11 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
679721 skb_reserve (skb , hr );
680722
681723 xsk_skb_init_misc (skb , xs , desc -> addr );
724+ if (desc -> options & XDP_TX_METADATA ) {
725+ err = xsk_skb_metadata (skb , buffer , desc , pool , hr );
726+ if (unlikely (err ))
727+ return ERR_PTR (err );
728+ }
682729 } else {
683730 xsk_addr = kmem_cache_zalloc (xsk_tx_generic_cache , GFP_KERNEL );
684731 if (!xsk_addr )
@@ -692,11 +739,9 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
692739 list_add_tail (& xsk_addr -> addr_node , & XSKCB (skb )-> addrs_list );
693740 }
694741
695- addr = desc -> addr ;
696742 len = desc -> len ;
697743 ts = pool -> unaligned ? len : pool -> chunk_size ;
698744
699- buffer = xsk_buff_raw_get_data (pool , addr );
700745 offset = offset_in_page (buffer );
701746 addr = buffer - pool -> addrs ;
702747
@@ -727,7 +772,6 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
727772static struct sk_buff * xsk_build_skb (struct xdp_sock * xs ,
728773 struct xdp_desc * desc )
729774{
730- struct xsk_tx_metadata * meta = NULL ;
731775 struct net_device * dev = xs -> dev ;
732776 struct sk_buff * skb = xs -> skb ;
733777 int err ;
@@ -761,6 +805,12 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
761805 goto free_err ;
762806
763807 xsk_skb_init_misc (skb , xs , desc -> addr );
808+ if (desc -> options & XDP_TX_METADATA ) {
809+ err = xsk_skb_metadata (skb , buffer , desc ,
810+ xs -> pool , hr );
811+ if (unlikely (err ))
812+ goto free_err ;
813+ }
764814 } else {
765815 int nr_frags = skb_shinfo (skb )-> nr_frags ;
766816 struct xsk_addr_node * xsk_addr ;
@@ -795,42 +845,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
795845 xsk_addr -> addr = desc -> addr ;
796846 list_add_tail (& xsk_addr -> addr_node , & XSKCB (skb )-> addrs_list );
797847 }
798-
799- if (!skb_shinfo (skb )-> nr_frags && desc -> options & XDP_TX_METADATA ) {
800- if (unlikely (xs -> pool -> tx_metadata_len == 0 )) {
801- err = - EINVAL ;
802- goto free_err ;
803- }
804-
805- meta = buffer - xs -> pool -> tx_metadata_len ;
806- if (unlikely (!xsk_buff_valid_tx_metadata (meta ))) {
807- err = - EINVAL ;
808- goto free_err ;
809- }
810-
811- if (meta -> flags & XDP_TXMD_FLAGS_CHECKSUM ) {
812- if (unlikely (meta -> request .csum_start +
813- meta -> request .csum_offset +
814- sizeof (__sum16 ) > len )) {
815- err = - EINVAL ;
816- goto free_err ;
817- }
818-
819- skb -> csum_start = hr + meta -> request .csum_start ;
820- skb -> csum_offset = meta -> request .csum_offset ;
821- skb -> ip_summed = CHECKSUM_PARTIAL ;
822-
823- if (unlikely (xs -> pool -> tx_sw_csum )) {
824- err = skb_checksum_help (skb );
825- if (err )
826- goto free_err ;
827- }
828- }
829-
830- if (meta -> flags & XDP_TXMD_FLAGS_LAUNCH_TIME )
831- skb -> skb_mstamp_ns = meta -> request .launch_time ;
832- xsk_tx_metadata_to_compl (meta , & skb_shinfo (skb )-> xsk_meta );
833- }
834848 }
835849
836850 xsk_inc_num_desc (skb );
0 commit comments