I'm trying to set up a linux router, basing some routing on destination port. To do this, I'm using iptables, policy-based routing, and the netfilter packet mark.

So I set up a rule in the mangle prerouting table of iptables to set the mark on packets destined for the port I'm interested in:

iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 5200 -j MARK --set-mark 2

Then I do a rule to use a different routing table based on presence of that mark:

ip rule add fwmark 2 table 2

The problem is, the packets are routed the same as all the other packets. So is the mark that iptables supposedly sets the same as the mark the 'ip rule' command checks for?

I tried to verify that the mark really was getting set by iptables, by adding LOG lines in the nat prerouting table:

iptables -t nat -I PREROUTING -m mark --mark 2 -j LOG --log-prefix "nat PREROUTING mark 2"
iptalbes -t nat -I PREROUTING -i eth0 -p tcp --dport 5200 -j LOG --log-prefix "nat PREROUTING port 5200"

and, just to make sure the packets were really going through the mangle tables, a LOG line there:

iptables -t mangle -I PREROUTING -i eth0 -p tcp --dport 5200 -j log --log-prefix "mangle PREROUTING port 5200"

Then sent packets with destination port 5200 on eth0 of the router. I saw the log lines coming out for both "mangle PREROUTING port 5200" and "nat PREROUTING port 5200", but no "nat PREROUTING mark 2" messages. So the packets were clearly going through both the mangle and nat PREROUTING hooks, but the MARK line was not having the effect that I expected. Even if iptables and "ip rule" are referring to different "mark"s, the MARK line isn't setting it.

Is there a problem in iptables setting this mark? Or am I using it wrong? Is there a better way of routing based on destination port?

Thanks