@@ -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