Lines Matching +full:tx +full:- +full:ping +full:- +full:pong

1 // SPDX-License-Identifier: GPL-2.0
7 * - UDP 9091 packets are diverted into AF_XDP
8 * - Metadata verified:
9 * - rx_timestamp
10 * - rx_hash
12 * TX:
13 * - UDP 9091 packets trigger TX reply
14 * - TX HW timestamp is requested and reported back upon completion
15 * - TX checksum is requested
53 struct xsk_ring_prod tx; member
90 xsk->umem_area = mmap(NULL, UMEM_SIZE, PROT_READ | PROT_WRITE, mmap_flags, -1, 0); in open_xsk()
91 if (xsk->umem_area == MAP_FAILED) in open_xsk()
92 return -ENOMEM; in open_xsk()
94 ret = xsk_umem__create(&xsk->umem, in open_xsk()
95 xsk->umem_area, UMEM_SIZE, in open_xsk()
96 &xsk->fill, in open_xsk()
97 &xsk->comp, in open_xsk()
102 ret = xsk_socket__create(&xsk->socket, ifindex, queue_id, in open_xsk()
103 xsk->umem, in open_xsk()
104 &xsk->rx, in open_xsk()
105 &xsk->tx, in open_xsk()
110 /* First half of umem is for TX. This way address matches 1-to-1 in open_xsk()
116 printf("%p: tx_desc[%d] -> %lx\n", xsk, i, addr); in open_xsk()
121 ret = xsk_ring_prod__reserve(&xsk->fill, UMEM_NUM / 2, &idx); in open_xsk()
124 printf("%p: rx_desc[%d] -> %lx\n", xsk, i, addr); in open_xsk()
125 *xsk_ring_prod__fill_addr(&xsk->fill, idx + i) = addr; in open_xsk()
127 xsk_ring_prod__submit(&xsk->fill, ret); in open_xsk()
134 if (xsk->umem) in close_xsk()
135 xsk_umem__delete(xsk->umem); in close_xsk()
136 if (xsk->socket) in close_xsk()
137 xsk_socket__delete(xsk->socket); in close_xsk()
138 munmap(xsk->umem_area, UMEM_SIZE); in close_xsk()
145 if (xsk_ring_prod__reserve(&xsk->fill, 1, &idx) == 1) { in refill_rx()
147 *xsk_ring_prod__fill_addr(&xsk->fill, idx) = addr; in refill_rx()
148 xsk_ring_prod__submit(&xsk->fill, 1); in refill_rx()
154 return sendto(xsk_socket__fd(xsk->socket), NULL, 0, MSG_DONTWAIT, NULL, 0); in kick_tx()
159 return recvfrom(xsk_socket__fd(xsk->socket), NULL, 0, MSG_DONTWAIT, NULL, NULL); in kick_rx()
180 __s64 delta = (__s64)reference - (__s64)tstamp; in print_tstamp_delta()
204 meta = data - sizeof(*meta); in verify_xdp_metadata()
206 if (meta->hint_valid & XDP_META_FIELD_RSS) in verify_xdp_metadata()
208 meta->rx_hash, meta->rx_hash_type); in verify_xdp_metadata()
210 printf("No rx_hash, err=%d\n", meta->rx_hash_err); in verify_xdp_metadata()
212 if (meta->hint_valid & XDP_META_FIELD_TS) { in verify_xdp_metadata()
215 /* store received timestamps to calculate a delta at tx */ in verify_xdp_metadata()
216 last_hw_rx_timestamp = meta->rx_timestamp; in verify_xdp_metadata()
217 last_xdp_rx_timestamp = meta->xdp_timestamp; in verify_xdp_metadata()
219 print_tstamp_delta("HW RX-time", "User RX-time", in verify_xdp_metadata()
220 meta->rx_timestamp, ref_tstamp); in verify_xdp_metadata()
221 print_tstamp_delta("XDP RX-time", "User RX-time", in verify_xdp_metadata()
222 meta->xdp_timestamp, ref_tstamp); in verify_xdp_metadata()
224 printf("No rx_timestamp, err=%d\n", meta->rx_timestamp_err); in verify_xdp_metadata()
227 if (meta->hint_valid & XDP_META_FIELD_VLAN_TAG) { in verify_xdp_metadata()
228 printf("rx_vlan_proto: 0x%X\n", ntohs(meta->rx_vlan_proto)); in verify_xdp_metadata()
230 print_vlan_tci(meta->rx_vlan_tci); in verify_xdp_metadata()
233 meta->rx_vlan_tag_err); in verify_xdp_metadata()
262 if (cmsg->cmsg_level != SOL_SOCKET) in verify_skb_metadata()
265 switch (cmsg->cmsg_type) { in verify_skb_metadata()
268 if (ts->ts[2].tv_sec || ts->ts[2].tv_nsec) { in verify_skb_metadata()
270 ts->ts[2].tv_sec, ts->ts[2].tv_nsec); in verify_skb_metadata()
289 if (!xsk_ring_cons__peek(&xsk->comp, 1, &idx)) in complete_tx()
292 addr = *xsk_ring_cons__comp_addr(&xsk->comp, idx); in complete_tx()
293 data = xsk_umem__get_data(xsk->umem_area, addr); in complete_tx()
294 meta = data - sizeof(struct xsk_tx_metadata); in complete_tx()
296 printf("%p: complete tx idx=%u addr=%llx\n", xsk, idx, addr); in complete_tx()
298 if (meta->completion.tx_timestamp) { in complete_tx()
301 print_tstamp_delta("HW TX-complete-time", "User TX-complete-time", in complete_tx()
302 meta->completion.tx_timestamp, ref_tstamp); in complete_tx()
303 print_tstamp_delta("XDP RX-time", "User TX-complete-time", in complete_tx()
305 print_tstamp_delta("HW RX-time", "HW TX-complete-time", in complete_tx()
306 last_hw_rx_timestamp, meta->completion.tx_timestamp); in complete_tx()
311 xsk_ring_cons__release(&xsk->comp, 1); in complete_tx()
338 ret = xsk_ring_prod__reserve(&xsk->tx, 1, &idx); in ping_pong()
340 printf("%p: failed to reserve tx slot\n", xsk); in ping_pong()
344 tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx); in ping_pong()
345 tx_desc->addr = idx % (UMEM_NUM / 2) * UMEM_FRAME_SIZE + sizeof(struct xsk_tx_metadata); in ping_pong()
346 data = xsk_umem__get_data(xsk->umem_area, tx_desc->addr); in ping_pong()
348 meta = data - sizeof(struct xsk_tx_metadata); in ping_pong()
350 meta->flags = XDP_TXMD_FLAGS_TIMESTAMP; in ping_pong()
354 if (eth->h_proto == htons(ETH_P_IP)) { in ping_pong()
357 } else if (eth->h_proto == htons(ETH_P_IPV6)) { in ping_pong()
361 printf("%p: failed to detect IP version for ping pong %04x\n", xsk, eth->h_proto); in ping_pong()
362 xsk_ring_prod__cancel(&xsk->tx, 1); in ping_pong()
368 len += sizeof(*ip6h) + ntohs(ip6h->payload_len); in ping_pong()
370 len += ntohs(iph->tot_len); in ping_pong()
372 swap(eth->h_dest, eth->h_source, ETH_ALEN); in ping_pong()
374 swap(&iph->saddr, &iph->daddr, 4); in ping_pong()
376 swap(&ip6h->saddr, &ip6h->daddr, 16); in ping_pong()
377 swap(&udph->source, &udph->dest, 2); in ping_pong()
379 want_csum = udph->check; in ping_pong()
381 udph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, in ping_pong()
382 ntohs(udph->len), IPPROTO_UDP, 0); in ping_pong()
384 udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, in ping_pong()
385 ntohs(udph->len), IPPROTO_UDP, 0); in ping_pong()
387 meta->flags |= XDP_TXMD_FLAGS_CHECKSUM; in ping_pong()
389 meta->request.csum_start = sizeof(*eth) + sizeof(*iph); in ping_pong()
391 meta->request.csum_start = sizeof(*eth) + sizeof(*ip6h); in ping_pong()
392 meta->request.csum_offset = offsetof(struct udphdr, check); in ping_pong()
394 printf("%p: ping-pong with csum=%04x (want %04x) csum_start=%d csum_offset=%d\n", in ping_pong()
395 xsk, ntohs(udph->check), ntohs(want_csum), in ping_pong()
396 meta->request.csum_start, meta->request.csum_offset); in ping_pong()
399 tx_desc->options |= XDP_TX_METADATA; in ping_pong()
400 tx_desc->len = len; in ping_pong()
402 xsk_ring_prod__submit(&xsk->tx, 1); in ping_pong()
436 ret, errno, bpf_obj->bss->pkts_skip, in verify_metadata()
437 bpf_obj->bss->pkts_fail, bpf_obj->bss->pkts_redir); in verify_metadata()
455 ret = xsk_ring_cons__peek(&xsk->rx, 1, &idx); in verify_metadata()
460 rx_desc = xsk_ring_cons__rx_desc(&xsk->rx, idx); in verify_metadata()
461 comp_addr = xsk_umem__extract_addr(rx_desc->addr); in verify_metadata()
462 addr = xsk_umem__add_offset_to_addr(rx_desc->addr); in verify_metadata()
463 is_eop = !(rx_desc->options & XDP_PKT_CONTD); in verify_metadata()
464 printf("%p: rx_desc[%u]->addr=%llx addr=%llx comp_addr=%llx%s\n", in verify_metadata()
465 xsk, idx, rx_desc->addr, addr, comp_addr, is_eop ? " EoP" : ""); in verify_metadata()
467 verify_xdp_metadata(xsk_umem__get_data(xsk->umem_area, addr), in verify_metadata()
473 ping_pong(xsk, xsk_umem__get_data(xsk->umem_area, addr), in verify_metadata()
488 xsk_ring_cons__release(&xsk->rx, 1); in verify_metadata()
507 strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1); in rxq_num()
528 strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1); in hwtstamp_ioctl()
570 opts.old_prog_fd = bpf_program__fd(bpf_obj->progs.rx); in cleanup()
606 " -c Run in copy mode (zerocopy is default)\n" in print_usage()
607 " -h Display this help and exit\n\n" in print_usage()
608 " -m Enable multi-buffer XDP for larger MTU\n" in print_usage()
609 " -r Don't generate AF_XDP reply (rx metadata only)\n" in print_usage()
611 " echo -n xdp | nc -u -q1 <dst_ip> 9091\n"; in print_usage()
620 while ((opt = getopt(argc, argv, "chmr")) != -1) { in read_args()
638 fprintf(stderr, "Unknown option: -%c\n", optopt); in read_args()
642 error(-1, opterr, "Command line options error"); in read_args()
649 exit(-1); in read_args()
656 error(-1, errno, "Invalid interface name"); in read_args()
662 int server_fd = -1; in main()
684 error(1, -ret, "open_xsk"); in main()
686 printf("xsk_socket__fd() -> %d\n", xsk_socket__fd(rx_xsk[i].socket)); in main()
694 prog = bpf_object__find_program_by_name(bpf_obj->obj, "rx"); in main()
701 error(1, -ret, "xdp_hw_metadata__load"); in main()
717 ret = bpf_map_update_elem(bpf_map__fd(bpf_obj->maps.xsk), &queue_id, &sock_fd, 0); in main()
719 error(1, -ret, "bpf_map_update_elem"); in main()
724 bpf_program__fd(bpf_obj->progs.rx), in main()
727 error(1, -ret, "bpf_xdp_attach"); in main()
734 error(1, -ret, "verify_metadata"); in main()