Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a system hosting a number of KVM instances. All of these are connected to a single bridge (say, brvirt), to which is also connected eth1. This layer 2 environment is on a private network using for an address change. There are two other interfaces on the system that we'll call eth0 ( and eth2 (

In general, external connectivity is provided via SNAT to the address of eth0 (and the hosts's default gateway is also out this interface). For some systems, I want an explicit 1-1 SNAT rule on the network, which is attached to eth2.

This is a problem because by the time we hit the POSTROUTING chain to perform the SNAT the outbound interface selection has already been made. The kernel has already selected the default route (assuming a connection to anything other than a directly attached network), which means that when the SNAT rule modifies the source ip address, the local routing infrastructure drops the packet because it is originating on the wrong layer 2 network.

Is there any way around this? What I really want to do is make routing decisions based on the source address on the packet at the conclusion of the POSTROUTING chain...but it's called POSTROUTING for a good reason.

share|improve this question

this can be done with simple policy based routing.

you will need a set of rules and routes with the schema:

ip rule add from 172.16.10.X iif brvirt lookup 200
ip route add default via src dev ethY table 200


172.16.10.X = KVM's IP
200         = Example value for routing_table, has to be unique for each KVM
ethY        = either eth0 or eth2     = Example Gateway on iface ethY     = Example Source-IP for each KVM

This will route anything comming from 172.16.10.X over the specified iface ethY with the Source-Address of

You can also do it more complex with fwmarks but I dont think this is needed in this case.

You can verify the routes with: ip route get iif brvirt from 172.16.10.X This will display the route and output device the kernel would use for a connection from 172.16.10.X to

Hope it answers your question,


share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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