Before I ask my question, let me first pose the situation:

  • I have 2 network interfaces: eth0 and eth1
  • I bridge those 2 (using brctl) and form a new interface: br0
  • This bridge gets the ip address
  • I'm running a custom linux (3.12 kernel from ti), with busybox, iptables, ebtables, arptables and nginx with php-fpm on a beaglebone.

The problem that I want to solve:

  • I want to be able to chose any interface to plug my network cable into, and still use the same IP address to access an administration website on this device. However, I'd like to know which physical device was used to access the site.

My wannabe solution:

  • I thought about simply "marking" packetings coming from physdev eth1 as "1", so that I could DNAT this into another port. This different port would be much simpler to detect in nginx/php. For eth0 I use port 80, whilst for eth1 is use port 81.

My iptables entries:

iptables -t mangle -A PREROUTING -m physdev --physdev-in eth1 -j MARK --set-mark 0x01
iptables -t nat -A PREROUTING -p tcp --dport 80 -m mark --mark 0x01 -j DNAT --to-destination :81

What happens (a.k.a. the actual problem):

  • The marking seems to work when I'm locally connected to the device, meaning, there's not much traffic going on. However, when I'm on my company network, I get a whole lot more traffic which apparantly causes this trick to fail. This is visible because being plugged in in interface eth0, causes the port 80 to be used, where I expected port 81. However, if I refresh rapidly a few times, I see that port 81 gets used... so, this makes me more confused.

When I run: iptables -t nat -L -n -v

I see that the rule only nats a few packets, certainly not all packets. I test this simply by looking at the pkts counter after each page refresh (although, maybe my browser doesn't always refresh). Could this be due too browser caching or something?

edit: it has nothing to do with browser caching apparantly.

Thank you in advance!

Kind regards, Xabre

  • The snippets in your question and answer do not redirect/nat to, but to <ETH1_IP>:81. Is anything listening there? $man iptables > REDIRECT [...] redirects the packet to the machine itself by changing > the destination IP to the primary address of the incoming > interface (locally-generated packets are mapped to the > address).
    – Enos
    Dec 23, 2014 at 10:18
  • Totally misinterpreted the documentation then. Actually, my eth1 and eth0 are not bound to any ip address, they are, however, on the same bridge, which is bound to ip I was trying something new now, this time with UDP packets. But I kinda see the same behaviour here. When I look at the iptables counters, I see that a packet is only parsed once => the pkt counter remains zero. The UDP protocol is a custom protocol with no "request" tracking at all.
    – Xabre
    Dec 23, 2014 at 10:52
  • So, another path I'm trying out, is one in which I track the connection. What I was hoping for, was that, once I tracked the established connections, that it would, in face, be re-evaluated (I know about the overhead this would bring). I don't see any difference, however. When I look in wireshark, I effectivly have to wait for an RST before the packet is re-evaluated. But in my test, I quite rappidly change my ethernet cable from one phy to another, over and over again. Although not very real-life, I want to figure out what I could do in such a case where the network is very dynamic!
    – Xabre
    Dec 23, 2014 at 15:47

1 Answer 1


I found a solution, although I don't really understand it yet. I'm using REDIRECT instead of DNAT, and what do you know, it works like a charm!

The only thing I could come up with, is the fact that in my DNAT rule I kept my actual IP address to which I want to redirect, whilst REDIRECT actually just reroutes to

Kind regards, Xabre

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.