@@ -56,7 +56,8 @@ static int open_xsk(int ifindex, struct xsk *xsk)
56
56
.fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS ,
57
57
.comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS ,
58
58
.frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE ,
59
- .flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG ,
59
+ .flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG | XDP_UMEM_TX_SW_CSUM ,
60
+ .tx_metadata_len = sizeof (struct xsk_tx_metadata ),
60
61
};
61
62
__u32 idx ;
62
63
u64 addr ;
@@ -138,6 +139,7 @@ static void ip_csum(struct iphdr *iph)
138
139
139
140
static int generate_packet (struct xsk * xsk , __u16 dst_port )
140
141
{
142
+ struct xsk_tx_metadata * meta ;
141
143
struct xdp_desc * tx_desc ;
142
144
struct udphdr * udph ;
143
145
struct ethhdr * eth ;
@@ -151,10 +153,14 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
151
153
return -1 ;
152
154
153
155
tx_desc = xsk_ring_prod__tx_desc (& xsk -> tx , idx );
154
- tx_desc -> addr = idx % (UMEM_NUM / 2 ) * UMEM_FRAME_SIZE ;
156
+ tx_desc -> addr = idx % (UMEM_NUM / 2 ) * UMEM_FRAME_SIZE + sizeof ( struct xsk_tx_metadata ) ;
155
157
printf ("%p: tx_desc[%u]->addr=%llx\n" , xsk , idx , tx_desc -> addr );
156
158
data = xsk_umem__get_data (xsk -> umem_area , tx_desc -> addr );
157
159
160
+ meta = data - sizeof (struct xsk_tx_metadata );
161
+ memset (meta , 0 , sizeof (* meta ));
162
+ meta -> flags = XDP_TXMD_FLAGS_TIMESTAMP ;
163
+
158
164
eth = data ;
159
165
iph = (void * )(eth + 1 );
160
166
udph = (void * )(iph + 1 );
@@ -178,11 +184,17 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
178
184
udph -> source = htons (AF_XDP_SOURCE_PORT );
179
185
udph -> dest = htons (dst_port );
180
186
udph -> len = htons (sizeof (* udph ) + UDP_PAYLOAD_BYTES );
181
- udph -> check = 0 ;
187
+ udph -> check = ~csum_tcpudp_magic (iph -> saddr , iph -> daddr ,
188
+ ntohs (udph -> len ), IPPROTO_UDP , 0 );
182
189
183
190
memset (udph + 1 , 0xAA , UDP_PAYLOAD_BYTES );
184
191
192
+ meta -> flags |= XDP_TXMD_FLAGS_CHECKSUM ;
193
+ meta -> request .csum_start = sizeof (* eth ) + sizeof (* iph );
194
+ meta -> request .csum_offset = offsetof(struct udphdr , check );
195
+
185
196
tx_desc -> len = sizeof (* eth ) + sizeof (* iph ) + sizeof (* udph ) + UDP_PAYLOAD_BYTES ;
197
+ tx_desc -> options |= XDP_TX_METADATA ;
186
198
xsk_ring_prod__submit (& xsk -> tx , 1 );
187
199
188
200
ret = sendto (xsk_socket__fd (xsk -> socket ), NULL , 0 , MSG_DONTWAIT , NULL , 0 );
@@ -194,13 +206,21 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
194
206
195
207
static void complete_tx (struct xsk * xsk )
196
208
{
197
- __u32 idx ;
209
+ struct xsk_tx_metadata * meta ;
198
210
__u64 addr ;
211
+ void * data ;
212
+ __u32 idx ;
199
213
200
214
if (ASSERT_EQ (xsk_ring_cons__peek (& xsk -> comp , 1 , & idx ), 1 , "xsk_ring_cons__peek" )) {
201
215
addr = * xsk_ring_cons__comp_addr (& xsk -> comp , idx );
202
216
203
217
printf ("%p: complete tx idx=%u addr=%llx\n" , xsk , idx , addr );
218
+
219
+ data = xsk_umem__get_data (xsk -> umem_area , addr );
220
+ meta = data - sizeof (struct xsk_tx_metadata );
221
+
222
+ ASSERT_NEQ (meta -> completion .tx_timestamp , 0 , "tx_timestamp" );
223
+
204
224
xsk_ring_cons__release (& xsk -> comp , 1 );
205
225
}
206
226
}
@@ -221,6 +241,7 @@ static int verify_xsk_metadata(struct xsk *xsk)
221
241
const struct xdp_desc * rx_desc ;
222
242
struct pollfd fds = {};
223
243
struct xdp_meta * meta ;
244
+ struct udphdr * udph ;
224
245
struct ethhdr * eth ;
225
246
struct iphdr * iph ;
226
247
__u64 comp_addr ;
@@ -257,6 +278,7 @@ static int verify_xsk_metadata(struct xsk *xsk)
257
278
ASSERT_EQ (eth -> h_proto , htons (ETH_P_IP ), "eth->h_proto" );
258
279
iph = (void * )(eth + 1 );
259
280
ASSERT_EQ ((int )iph -> version , 4 , "iph->version" );
281
+ udph = (void * )(iph + 1 );
260
282
261
283
/* custom metadata */
262
284
@@ -270,6 +292,9 @@ static int verify_xsk_metadata(struct xsk *xsk)
270
292
271
293
ASSERT_EQ (meta -> rx_hash_type , 0 , "rx_hash_type" );
272
294
295
+ /* checksum offload */
296
+ ASSERT_EQ (udph -> check , htons (0x721c ), "csum" );
297
+
273
298
xsk_ring_cons__release (& xsk -> rx , 1 );
274
299
refill_rx (xsk , comp_addr );
275
300
0 commit comments