-
Notifications
You must be signed in to change notification settings - Fork 112
Description
I wrote a very simple function which sends XDP packets, based on https://github.com/xdp-project/bpf-examples/blob/master/AF_XDP-example/xdpsock.c#L1535. There should be one packet sent once every 100ms. The problem is that all the packets are sent in ~10us after every 2 seconds ( I attached a Whireshark screenshot ). Any ideea why and how to fix this?
This is the function:
static int send_xdp_packet(struct xsk_socket_info* xsk, uint32_t* frame_nb, int batch_size)
{
uint32_t idx, idx_tx, tv_sec, tv_usec;
unsigned int i, rcvd;
if (xsk_ring_prod__reserve(&xsk->tx, batch_size, &idx_tx) != batch_size) {
perror("Error xsk_ring_prod__reserve() failed");
return (-1);
}
uint32_t len = PKT_SIZE;
// write entries in the Tx ring
xsk_ring_prod__tx_desc(&xsk->tx, idx_tx)->addr = *frame_nb * XSK_UMEM__DEFAULT_FRAME_SIZE;
xsk_ring_prod__tx_desc(&xsk->tx, idx_tx)->len = PKT_SIZE;
xsk_ring_prod__tx_desc(&xsk->tx, idx_tx)->options = 0;
*frame_nb = (*frame_nb + 1) % NUM_FRAMES;
++numOfPacketsSent;
xsk_ring_prod__submit(&xsk->tx, batch_size);
kick_tx(xsk);
rcvd = xsk_ring_cons__peek(&xsk->umem->cq, batch_size, &idx);
if (rcvd > 0) {
xsk_ring_cons__release(&xsk->umem->cq, rcvd);
}
return 0;
}
static void kick_tx(struct xsk_socket_info* xsk)
{
int ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
if (ret < 0) {
perror("kick_tx");
close(xsk_socket__fd(xsk->xsk));
exit(EXIT_FAILURE);
}
else if ((errno == ENOBUFS) || (errno == EAGAIN) || (errno == EBUSY) || (errno == ENETDOWN)) {
printf("WARNING kick_tx() sendto() returned error: %d\n", errno);
}
}
int main() {
/* ... */
xdp_mode = XDP_FLAGS_DRV_MODE;
xsks = xsk_configure_socket(umem, rx, tx, ifName, xdp_mode);
sockfd = xsk_socket__fd(xsks->xsk);
uint32_t frame_nb = 0;
gen_eth_hdr_data();
for (size_t i = 0; i < NUM_FRAMES; i++) // NUM_FRAMES = 1
gen_eth_frame(umem, i * opt_xsk_frame_size, PKT_SIZE, pkt_data);
while (true) {
uint32_t frame_nb = 0;
if (useXDP) {
ssize_t n = send_xdp_packet(xsks, &frame_nb, opt_batch_size * frames_per_pkt); // opt_batch_size * frames_per_pkt = 1
}
usleep(100000);
}