What I (mis)understand so far:
The Buffering:
- There is just one big buffer providing memory to store a couple of ethernet packets
- A pointer is pointing at the starting location of each packet
- If the packets location is free/unused, the pointer is put on a stack that holds all pointers to free/unused packets (at program start: all of the pointers are on the stack)
- The buffer_manager (BM from here on) grabs a pointer from the stack and passes a it to the low level driver (lld)
- the lld fills the buffer and notifies the BM when a packet has been received by sending the pointer back over a channel
- BM reacts by trying to grab a free buffer from the stack
- if there is no free buffer available, the current buffer is sent back to the lld resulting in the packet to be overwritten/dropped
- If a free buffer is available, this buffer is grabbed and sent to the lld, processing continues
- The BM checks the packets destination MAC address
- If not for any of our client threads, put the buffer on the stack for free buffers
- Else add the buffer pointer to a list with pointers of buffers in use
There is an additional function doing more filtering (e.g. ethertype). This function grabs one of the pointers to a buffer in use and if the packet does not pass the additional filtering the packet pointer is simply added to the stack with unused buffers. In this case, using a fifo/ring buffer is fine to me.
On passing the additional filtering, there are n Clients that want a packet. The packets pointer is added to the respective clients FIFOs. If the FIFO is full, the packet is dropped for just the client.
The clients get a notification, so they can (at some point) grab the packet. Maybe Client 1 and 3 want the current packet and client 2 wants the packet received next. We don't know when client 1 and 3 have grabbed their Packet, so it is possible for Client 2 to grab its packet earlier? In this case a fifo/ring buffer would end up with a hole, so I am wondering, what the actual buffering mechanism is.