On Tue, Jun 13, 2023 at 8:03 AM Willem de Bruijn <willemdebruijn.kernel@xxxxxxxxx> wrote: > > On Mon, Jun 12, 2023 at 7:26 PM Stanislav Fomichev <sdf@xxxxxxxxxx> wrote: > > > > When we get packets on port 9091, we swap src/dst and send it out. > > At this point, we also request the timestamp and plumb it back > > to the userspace. The userspace simply prints the timestamp. > > > > Haven't really tested, still working on mlx5 patches... > > > > Cc: netdev@xxxxxxxxxxxxxxx > > Signed-off-by: Stanislav Fomichev <sdf@xxxxxxxxxx> > > > > +++ b/tools/testing/selftests/bpf/xdp_hw_metadata.c > > @@ -10,7 +10,8 @@ > > * - rx_hash > > * > > * TX: > > - * - TBD > > + * - UDP 9091 packets trigger TX reply > > This branch on port is missing? That's the ping_pong part. Evey packet arriving on 9091 port gets received by af_xdp and is sent back. > > +static void ping_pong(struct xsk *xsk, void *rx_packet) > > +{ > > + struct ipv6hdr *ip6h = NULL; > > + struct iphdr *iph = NULL; > > + struct xdp_desc *tx_desc; > > + struct udphdr *udph; > > + struct ethhdr *eth; > > + void *data; > > + __u32 idx; > > + int ret; > > + int len; > > + > > + ret = xsk_ring_prod__reserve(&xsk->tx, 1, &idx); > > + if (ret != 1) { > > + printf("%p: failed to reserve tx slot\n", xsk); > > + return; > > + } > > + > > + tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx); > > + tx_desc->addr = idx % (UMEM_NUM / 2) * UMEM_FRAME_SIZE; > > + data = xsk_umem__get_data(xsk->umem_area, tx_desc->addr); > > + > > + eth = data; > > + > > + if (eth->h_proto == htons(ETH_P_IP)) { > > + iph = (void *)(eth + 1); > > + udph = (void *)(iph + 1); > > + } else if (eth->h_proto == htons(ETH_P_IPV6)) { > > + ip6h = (void *)(eth + 1); > > + udph = (void *)(ip6h + 1); > > + } else { > > + xsk_ring_prod__cancel(&xsk->tx, 1); > > + return; > > + } > > + > > + len = ETH_HLEN; > > + if (ip6h) > > + len += ntohs(ip6h->payload_len); > > sizeof(*ip6h) + ntohs(ip6h->payload_len) ? Ooop, thanks, that's clearly not tested :-) > > + if (iph) > > + len += ntohs(iph->tot_len); > > + > > + memcpy(data, rx_packet, len); > > + swap(eth->h_dest, eth->h_source, ETH_ALEN); > > + if (iph) > > + swap(&iph->saddr, &iph->daddr, 4); > > need to recompute ipv4 checksum? Discussed offline: swapping the aligned-u16 chunks preserves the checksum.