Virtual systems using NFMARK in place of eroutes

"Wayne Schroeder" <[email protected]> Tue, 6 Jan 2004 11:02:31 -0600
Newsgroups gmane.network.freeswan.user,gmane.network.freeswan.devel
Message-ID <F6C3E684F292D14E9BC8A6626231455C011966@exchange.positivenetworks.net>
I wanted to bounce an attempt (one that currently works in testing at
the moment) to implement virtual systems in freeswan off the design
people and anyone who may have tried something similar on the users list
as well.

Background:=20

Virtual systems are something I was first introduced to on a netscreen
device.  The basic concept is to have the ability to break up your ipsec
concentrator into virtual routing domains and to be able to route
packets in a 'virtual router / system' environment where packets from
one system would never be seen on the other unless specifically routed
to it.  A more physical example might be the following network setup.
Assume that you have a freeswan box with two nics in it... a public nic
and a private side nic with 802.1q plugged into a trunk port on a
switch.  There are two remote networks with the same ip address ranges
which have ipsec tunnels to said freeswan box.  In the end, you want the
network traffic from site 1 to come out vlan 10 on the private side, and
site 2 to come out vlan 11.  This would not be a problem if the remote
networks were numbered differently--you could simply throw it into the
routing table as normal and have eroutes handle outbound routes based on
destination and the normal routes to said vlan interfaces work on
inbound.  The ability to break your routing / ipsec tunnels up into
'virtual systems' allows you to have multiple remote networks with the
same ranges connect to the freeswan box and do independent routing based
on what tunnel the packet came in on.

My solution:

What I ended up doing was basically extending on what I already saw in
place in the freeswan code.  The obvious starting point was NFMARKs
since you can iptables and iproute2 on them.  I noticed that packets
that hit the routing tables in linux coming from ipsec0 were tagged with
an spi identifier in the nfmark field.  I went ahead and changed this to
mark the packet with the 32bit ipv4 address of the remote gateway from
where the packet came in.  Now I can do specific routing on this packet
based on the nfmark (which is static, not dynamic like spi).  This was
by far the easiest change.  Next I had to tackle outbound.  Basically
what I ended up doing is hijacking the msg parser for eroutes and
storing my own hash for keeping track of the network/netmask ranges and
spi's for outbound packets.  I keyed the hash on remote gateway so all I
have to do to get a packet to go out a given tunnel is set the nfmark to
the desired remote gateway on it before it hits ipsec0 and the nfmark
alone (not the network ranges) will determine what spi / remote gateway
are used.  This with a combination of routing / iptables / vlan
interfaces seems to work quite well in my initial testing.

Thoughts?

I am really interested to hear from the design people on this method.
Does this sound like it's going to break anything that I didn't intend
to break (like erouting).  Does this sound like a good way to do what
I'm trying to accomplish.

Wayne