seqs icon indicating copy to clipboard operation
seqs copied to clipboard

Zero Copy Rx packet buffering

Open soypat opened this issue 2 years ago • 0 comments

Seqs today

  1. eth package which represents packet headers as structs with fields..
  2. Above implies that when packets are parsed the header bytes are copied onto the stack
  3. The stack.TCPPacket and stack.UDPPacket types are more resource intensive than really necessary since they require copying IP/TCP options and payload

While point 3 can be easily fixed by just passing around the buffer, removing copying in point 2 is not as easy and would require the creation of a new package.

zc package

A Zero Copy package is proposed to reduce sopying during packet processing and alleviating stack growth. This package would likely have a larger scope than the current eth package. Below are some thoughts/suggestions on types to start a conversation:

  1. A base Buffer type which has a backing []byte type. This type offers no guarantees of what is contained inside the buffer. It offers methods such as

    func (b Buffer) Ethernet() (EthernetBuffer, error)
    func (b Buffer) IPv4() (IPv4Buffer, error)
    
  2. These EthernetBuffer and IPv4Buffer types are guaranteed to contain valid buffer information up to where their header ends. All these really need is a single uintptr or unsafe.Pointer backing type. Their methods would be roughly equivalent to the fields of the eth types today and would use unsafe package to extract the data. Methods should check for nullity and panic if pointer is null, which means the Ethernet/IPv4 method returned an error and the error was ignored before trying to extract data. Maybe as a first approximation the backing type can be a byte slice and this be changed in the future to use thin pointers.

  3. TCP/UDP: TCPBuffer and UDPBuffer types, which can be returned by IPv4Buffer (along with an error since buffer length may not be sufficient). The TCPBuffer type would need to be a semi-fat pointer since it has no information on the end of the payload. The UDPBuffer type could do with only a thin pointer.

    func (ipb IPv4Buffer) TCP() (TCPBuffer, error)
    func (ipb IPv4Buffer) UDP() (UDPBuffer, error)
    

Development

I think the above description is enough to start writing and testing the package out. The first step I'd imagine would be to start with a partial/complete zc package implementation and try replacing the packet parsing in PortStack.RecvEth method and benchmark speed improvements to see if Zero Copy benefits are really worth it.

soypat avatar Dec 09 '23 17:12 soypat