@@ -723,10 +723,48 @@ static struct sk_buff *xsk_build_skb_zerocopy(struct xdp_sock *xs,
723723 return skb ;
724724}
725725
726+ static int xsk_skb_metadata (struct sk_buff * skb , void * buffer ,
727+ struct xdp_desc * desc , struct xsk_buff_pool * pool ,
728+ u32 hr )
729+ {
730+ struct xsk_tx_metadata * meta = NULL ;
731+
732+ if (unlikely (pool -> tx_metadata_len == 0 ))
733+ return - EINVAL ;
734+
735+ meta = buffer - pool -> tx_metadata_len ;
736+ if (unlikely (!xsk_buff_valid_tx_metadata (meta )))
737+ return - EINVAL ;
738+
739+ if (meta -> flags & XDP_TXMD_FLAGS_CHECKSUM ) {
740+ if (unlikely (meta -> request .csum_start +
741+ meta -> request .csum_offset +
742+ sizeof (__sum16 ) > desc -> len ))
743+ return - EINVAL ;
744+
745+ skb -> csum_start = hr + meta -> request .csum_start ;
746+ skb -> csum_offset = meta -> request .csum_offset ;
747+ skb -> ip_summed = CHECKSUM_PARTIAL ;
748+
749+ if (unlikely (pool -> tx_sw_csum )) {
750+ int err ;
751+
752+ err = skb_checksum_help (skb );
753+ if (err )
754+ return err ;
755+ }
756+ }
757+
758+ if (meta -> flags & XDP_TXMD_FLAGS_LAUNCH_TIME )
759+ skb -> skb_mstamp_ns = meta -> request .launch_time ;
760+ xsk_tx_metadata_to_compl (meta , & skb_shinfo (skb )-> xsk_meta );
761+
762+ return 0 ;
763+ }
764+
726765static struct sk_buff * xsk_build_skb (struct xdp_sock * xs ,
727766 struct xdp_desc * desc )
728767{
729- struct xsk_tx_metadata * meta = NULL ;
730768 struct net_device * dev = xs -> dev ;
731769 struct sk_buff * skb = xs -> skb ;
732770 int err ;
@@ -764,6 +802,13 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
764802 skb -> priority = READ_ONCE (xs -> sk .sk_priority );
765803 skb -> mark = READ_ONCE (xs -> sk .sk_mark );
766804 skb -> destructor = xsk_destruct_skb ;
805+
806+ if (desc -> options & XDP_TX_METADATA ) {
807+ err = xsk_skb_metadata (skb , buffer , desc ,
808+ xs -> pool , hr );
809+ if (unlikely (err ))
810+ goto free_err ;
811+ }
767812 } else {
768813 int nr_frags = skb_shinfo (skb )-> nr_frags ;
769814 struct xsk_addr_node * xsk_addr ;
@@ -798,42 +843,6 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs,
798843 xsk_addr -> addr = desc -> addr ;
799844 list_add_tail (& xsk_addr -> addr_node , & XSKCB (skb )-> addrs_list );
800845 }
801-
802- if (!xsk_get_num_desc (skb ) && desc -> options & XDP_TX_METADATA ) {
803- if (unlikely (xs -> pool -> tx_metadata_len == 0 )) {
804- err = - EINVAL ;
805- goto free_err ;
806- }
807-
808- meta = buffer - xs -> pool -> tx_metadata_len ;
809- if (unlikely (!xsk_buff_valid_tx_metadata (meta ))) {
810- err = - EINVAL ;
811- goto free_err ;
812- }
813-
814- if (meta -> flags & XDP_TXMD_FLAGS_CHECKSUM ) {
815- if (unlikely (meta -> request .csum_start +
816- meta -> request .csum_offset +
817- sizeof (__sum16 ) > len )) {
818- err = - EINVAL ;
819- goto free_err ;
820- }
821-
822- skb -> csum_start = hr + meta -> request .csum_start ;
823- skb -> csum_offset = meta -> request .csum_offset ;
824- skb -> ip_summed = CHECKSUM_PARTIAL ;
825-
826- if (unlikely (xs -> pool -> tx_sw_csum )) {
827- err = skb_checksum_help (skb );
828- if (err )
829- goto free_err ;
830- }
831- }
832-
833- if (meta -> flags & XDP_TXMD_FLAGS_LAUNCH_TIME )
834- skb -> skb_mstamp_ns = meta -> request .launch_time ;
835- xsk_tx_metadata_to_compl (meta , & skb_shinfo (skb )-> xsk_meta );
836- }
837846 }
838847
839848 xsk_inc_num_desc (skb );
0 commit comments