I have just succesfully opened a RAW socket and I am trying to export Kernel TX and RX rings with the function below. However, setsockopt() returns EBUSY (Device or resource busy) when trying to tell the kernel to export the SECOND of the rings. This is, executing the code below once works fine, so I can get the first of the rings (either for TX or for RX). The problem comes when I try to export the second ring (for TX if the first was for RX or viceceversa).
Cannot an application use the same socket both for TX and RX with mmap()ed memory? This is, do I have to open one socket for TX and one socket for RX?
/* init_ring */
void *init_ring(ll_socket_t *ll_socket, int type)
{
void *ring = NULL;
int ring_len = 0;
int ring_access_flags = PROT_READ | PROT_WRITE;
struct tpacket_req tp;
// 1) tell kernel to export data through mmap()ped ring
tp.tp_block_size = FRAMES_PER_RING * getpagesize();
tp.tp_block_nr = 1;
tp.tp_frame_size = getpagesize();
tp.tp_frame_nr = FRAMES_PER_RING;
ring_len = tp.tp_block_size * tp.tp_block_nr;
if ( setsockopt(ll_socket->socket_fd, SOL_PACKET, type, &tp, sizeof(struct tpacket_req) ) < 0 )
{ handle_sys_error("Setting socket options for this ring"); }
// 2) open ring
if ( ( ring = mmap(NULL, ring_len, ring_access_flags, MAP_SHARED, ll_socket->socket_fd, 0) ) == NULL )
{ handle_sys_error("mmap()ing error"); }
return(ring);
}