On Mon, Aug 16, 2021 at 06:10:09PM +0200, Pablo Neira Ayuso wrote: [...] > > BTW, leading and trailing netlink message blocks to the kernel are not > required for nfnetlink_queue. Sorry, sloppy explanation on my part. This had nothing to do with batches. The idea was to attain a zero-copy nfq program by using sendmsg with an iov pointing at the mangled packet, wherever it is. A previous iov has to point to the struct nlmsghdr that starts the message. That first buffer ends with the struct nlattr for the packet data addressed by the next iov. If padding was required, I was sending a 3rd buffer. It's almost certainly fine to append the padding to the packet buffer instead, and for sure fine if check `pktb_tailroom > pad` first. Then I was sending the ACCEPT verdict in a 4th buffer. As you point out, I could have sent that earlier, before the trailing struct nlattr. When I originally started writing nfq programs I was concerned that the kernel might accept the original packet as soon as it encountered the ACCEPT, and miss that there was an updated packet following. I now realise it doesn't work that way, but got stuck with the old order of doing thins. So the code would be down to trading 1 kernel user buffer validate against 2 userland data copies. Which method is faster might well depend on packet length. I don't plan to pursue this further for now. Cheers ... Duncan.