Zero Copy Rx packet buffering
Seqs today
ethpackage which represents packet headers as structs with fields..- Above implies that when packets are parsed the header bytes are copied onto the stack
- The
stack.TCPPacketandstack.UDPPackettypes 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:
-
A base
Buffertype which has a backing[]bytetype. This type offers no guarantees of what is contained inside the buffer. It offers methods such asfunc (b Buffer) Ethernet() (EthernetBuffer, error) func (b Buffer) IPv4() (IPv4Buffer, error) -
These
EthernetBufferandIPv4Buffertypes are guaranteed to contain valid buffer information up to where their header ends. All these really need is a singleuintptrorunsafe.Pointerbacking type. Their methods would be roughly equivalent to the fields of theethtypes today and would useunsafepackage to extract the data. Methods should check for nullity and panic if pointer is null, which means theEthernet/IPv4method 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. -
TCP/UDP:
TCPBufferandUDPBuffertypes, which can be returned byIPv4Buffer(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.