I have been experimenting with using tc, tc-nat and tc-pedit to perform stateless nat operations. My goal is to mirror packets from one interface (eth0) to another (eth1), but I also want to change the destination IP, and destination MAC, so the packets can be delivered to another host.
Host A [Eth0 - > Eth1 (change IP dst, change MAC dst)] -------> HOST B
Because I have other applications listening on Eth0, I can't perform either tc-nat or tc-pedit on the ingress/egress on Eth0. So this is what I did
- Create a dummy interface
- Mirror packets from Eth0 to dummy interface
- Run tc-nat (to change destination IP) on egress side of dummy, pipe into tc-pedit (to change destination MAC), and pipe to mirror to Eth1.
The above contraption works as expected, but the performance is terrible (particularly when compared to a libpcap based application such as tcpbridge).
I started this approach hoping to achieve better performance in kernel space vs libpcap based application in user space. I'm curious is there a better way.