Linux's IP forwarding settings summarized
Unlike many Unixes, Linux determines whether or not it does IP
forwarding on an interface by interface basis, based on interface the
packet arrived on. While Linux has a global IP forwarding sysctl,
net.ipv4.ip_forward, pretty much all this really does is (re)set the
value for all of the interfaces and make it the default; you can still
change individual interfaces later.
The fine controls are in
/proc/sys/net/ipv4/conf/, where things
go like this:
interface/forwarding: controls whether incoming packets on interface can get forwarded or not.
(I believe that the setting for the
lointerface does nothing, since locally generated packets are always routed.)
all/forwarding: setting this is the same as setting the global sysctl.
default/forwarding: controls the default state of forwarding; this state gets used by interfaces that have not set a specific value. Setting the global sysctl counts as giving all existing interfaces a specific value.
For most purposes I suspect that you want to ignore the '
stuff and use either the global settings or per-interface settings. If
you want to make a machine a router in general, the easiest way is to
set the global sysctl; if you want people to only be able to route
through some of your interfaces, you need the interface-specific
(And if you want to entirely turn off IP forwarding on a machine in an emergency, the global sysctl is definitely the way to go.)
Note that a forwarded packet can get routed out through any active interface, regardless of the interface's forwarding setting. If you need to restrict what outgoing interfaces forwarded packets can use, you need some form of policy based routing.
(This is one of those entries I write to make sure that I have this information handy the next time I need it, since it is not really well covered in the documentation I could find.)