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? > +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) ? > + 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?