Hi Marco, On Tue, Oct 26, 2021 at 04:54:32PM +0200, pupilla@xxxxxxxxx wrote: > Hello everyone, > > I would like to know if it's possible to mangle a > packet like this one with linux netfilter (linux > kernel 5.14 or 5.15). > > My goal is to match the innermost ip header > (23.200.208.68/10.18.102.237) and then change the > mss of the tcp packet. > > Frame 48007: 1450 bytes on wire (11600 bits), 1450 bytes captured (11600 bits) > Ethernet II, Src: LcfcHefe_32:48:cf, Dst: HewlettP_da:f5:07 > Internet Protocol Version 4, Src: 10.18.46.63, Dst: 10.18.153.156 > User Datagram Protocol, Src Port: 5247, Dst Port: 5248 > Control And Provisioning of Wireless Access Points - Data > IEEE 802.11 Data, Flags: ......F. > Logical-Link Control > Internet Protocol Version 4, Src: 23.200.208.68, Dst: 10.18.102.237 > Transmission Control Protocol, Src Port: 443, Dst Port: 52500, Seq: 2753105, Ack: 1818, Len: 1316 > > Is there any way to do this? > > Thanks in advance > Marco Certainly it can be done, on the basis that "you can change anything" using a netfilter-queue program. The question is, how much work is involved? With the current libnetfilter_queue API, the answer is "maybe more than it should". So if I was trying to do this, I would be hacking the libnetfilter_queue source first. For a project of this complexity, you want the source anyway. The deprecated functions can't do packet mangling, so start with examples/nf-queue.c which uses the modern libmnl-based interface. You need an nft rule to queue UDP according to some filter maybe e.g. spt 5247 & dpt 5248 (iptables would also work). So your nfq program gets a UDP packet with an IP4 frame as data. The UDP frame is described by a struct pktbuff (an opaque structure you can read about at <https://netfilter.org/projects/libnetfilter_queue/index.html>). What you want, but we don't provide at the moment, is a struct pktbuff that describes the inner frame. Then mangle using the API and the TCP checksum will get updated. The current API always makes a copy of whatever the struct pktbuff describes, so you would have to move the updated frame back into the outer one. You have changed UDP data so mangle the outer frame to fix its checksum. How I would do it: I would apply my yet-to-be-accepted patch <https://patchwork.ozlabs.org/project/netfilter-devel/patch/20210518030848.17694-2-duncan_roe@xxxxxxxxxxxxxxx/>. Now packets are mangled in_situ and struct pktbuff is purely a descriptor instead of having a buffer tacked on the end of it, so no more need to move the mangled inner frame. The new pktb_populate() function can set up a struct pktbuff for the tunnelled IP, although I might make struct pktbuff publically visible if only so I can declare the inner one using `sizeof(struct pktbuff)`. (I find the procedural interface to get values out of a struct pktbuff to be a pain but that's just me: I realise that stuff is fashionable). Cheers ... Duncan.