diff --git a/src/af_xdp.c b/src/af_xdp.c index e6acb3b..78605d4 100644 --- a/src/af_xdp.c +++ b/src/af_xdp.c @@ -15,9 +15,13 @@ #include #include #include +#include +#include #include #include +#include + #include "af_xdp.h" __u32 flags = XDP_FLAGS_DRV_MODE | XDP_FLAGS_UPDATE_IF_NOEXIST; @@ -42,20 +46,23 @@ static void complete_tx(struct xsk_socket_info *xsk) return; } - sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); + if (xsk_ring_prod__needs_wakeup(&xsk->tx)) + { + int fd = xsk_socket__fd(xsk->xsk); + printf("sendto() executed with FD %d.\n", fd); + sendto(fd, NULL, 0, MSG_DONTWAIT, NULL, 0); + } /* Collect/free completed TX buffers */ completed = xsk_ring_cons__peek(&xsk->umem->cq, XSK_RING_CONS__DEFAULT_NUM_DESCS, &idx_cq); - if (completed > 0) + if (completed > 0) { - for (int i = 0; i < completed; i++) - { - xsk_free_umem_frame(xsk, *xsk_ring_cons__comp_addr(&xsk->umem->cq, idx_cq++)); - } + printf("completed > 0.\n"); xsk_ring_cons__release(&xsk->umem->cq, completed); - xsk->outstanding_tx -= completed < xsk->outstanding_tx ? completed : xsk->outstanding_tx; + xsk->outstanding_tx -= completed; + printf("New outstanding TX => %u.\n", xsk->outstanding_tx); } } @@ -120,7 +127,7 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem, xsk_cfg.tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS; xsk_cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD; xsk_cfg.xdp_flags = flags; - xsk_cfg.bind_flags = 0; + xsk_cfg.bind_flags = XDP_USE_NEED_WAKEUP; ret = xsk_socket__create(&xsk_info->xsk, dev, queue_id, umem->umem, NULL, &xsk_info->tx, &xsk_cfg); @@ -139,23 +146,6 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem, xsk_info->umem_frame_free = NUM_FRAMES; - // Stuff the receive path with buffers, we assume we have enough. - ret = xsk_ring_prod__reserve(&xsk_info->umem->fq, XSK_RING_PROD__DEFAULT_NUM_DESCS, &idx); - - if (ret != XSK_RING_PROD__DEFAULT_NUM_DESCS) - { - fprintf(stderr, "ret != XSK_RING_PROD__DEFAULT_NUM_DESCS :: Error.\n"); - - goto error_exit; - } - - for (i = 0; i < XSK_RING_PROD__DEFAULT_NUM_DESCS; i++) - { - *xsk_ring_prod__fill_addr(&xsk_info->umem->fq, idx++) = xsk_alloc_umem_frame(xsk_info); - } - - xsk_ring_prod__submit(&xsk_info->umem->fq, XSK_RING_PROD__DEFAULT_NUM_DESCS); - return xsk_info; error_exit: @@ -174,8 +164,17 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem, * * @return Returns 0 on success and -1 on failure. **/ -int send_packet(int thread_id, void *pckt, __u16 length, __u8 verbose) +int send_packet(int thread_id, void *pckt, __u32 length, __u8 verbose) { + __u64 addr = (__u64)pckt; + + struct ethhdr *eth = (struct ethhdr *)addr; + + struct iphdr *iph = (struct iphdr *)(eth + 1); + + printf("%hhx:%hhx:%hhx:%hhx:%hhx:%hhx => %hhx:%hhx:%hhx:%hhx:%hhx:%hhx.\n", eth->h_source[0], eth->h_source[1], eth->h_source[2], eth->h_source[3], eth->h_source[4], eth->h_source[5], eth->h_dest[0], eth->h_dest[1], eth->h_dest[2], eth->h_dest[3], eth->h_dest[4], eth->h_dest[5]); + printf("%u => %u.\n", iph->saddr, iph->daddr); + __u32 tx_idx = 0; int ret = xsk_ring_prod__reserve(&xsk_socket[thread_id]->tx, 1, &tx_idx); @@ -189,14 +188,19 @@ int send_packet(int thread_id, void *pckt, __u16 length, __u8 verbose) return -1; } - xsk_ring_prod__tx_desc(&xsk_socket[thread_id]->tx, tx_idx)->addr = (__u64)pckt; + // Insert packet into umem. + __u64 addrat = xsk_socket[thread_id]->outstanding_tx * FRAME_SIZE; + + memcpy(xsk_umem__get_data(xsk_socket[thread_id]->umem->buffer, addrat), pckt, length); + + xsk_ring_prod__tx_desc(&xsk_socket[thread_id]->tx, tx_idx)->addr = addrat; xsk_ring_prod__tx_desc(&xsk_socket[thread_id]->tx, tx_idx)->len = length; xsk_ring_prod__submit(&xsk_socket[thread_id]->tx, 1); xsk_socket[thread_id]->outstanding_tx++; if (verbose) { - printf("AF_XDP Info :: Address => %llu. Length => %u. Outstanding TX => %u.\n", (__u64)pckt, length, xsk_socket[thread_id]->outstanding_tx); + printf("AF_XDP Info :: Address => %llu. Length => %u. Outstanding TX => %u. TX Index => %u.\n", (__u64)pckt, length, xsk_socket[thread_id]->outstanding_tx, tx_idx); } complete_tx(xsk_socket[thread_id]); diff --git a/src/af_xdp.h b/src/af_xdp.h index 624c8ca..6851b34 100644 --- a/src/af_xdp.h +++ b/src/af_xdp.h @@ -41,6 +41,6 @@ struct xsk_socket_info }; -int send_packet(int thread_id, void *pckt, __u16 length, __u8 verbose); +int send_packet(int thread_id, void *pckt, __u32 length, __u8 verbose); int setup_socket(const char *dev, __u32 xdp_flags, __u16 thread_id); void cleanup_socket(__u16 id); \ No newline at end of file diff --git a/src/sequence.c b/src/sequence.c index 3e7a2be..32c6690 100644 --- a/src/sequence.c +++ b/src/sequence.c @@ -653,10 +653,10 @@ void *thread_hdl(void *temp) } // Attempt to send packet. - __u16 pckt_len = ntohs(iph->tot_len) + sizeof(struct ethhdr); + __u32 pckt_len = ntohs(iph->tot_len) + sizeof(struct ethhdr); int ret; - if ((ret = send_packet(ti->id, &buffer, pckt_len, ti->cmd.verbose)) != 0) + if ((ret = send_packet(ti->id, (void *)buffer, pckt_len, ti->cmd.verbose)) != 0) { fprintf(stderr, "ERROR - Could not send packet on AF_XDP socket (%d) :: %s.\n", ti->id, strerror(errno)); }