[strongSwan-dev] [PATCH] Fix unnecessary dumping of entire routing table.

Oliver oliver.d at prodege.com
Mon Oct 5 22:03:57 CEST 2015

On Wednesday 30 September 2015 12:13:14 Tobias Brunner wrote:
> Hi Oliver,
> > So, let's take the following scenario:
> > 
> > left=
> > right=
> > leftsubnet=
> > rightsubnet=
> > leftsourceip=
> > rightsourceip=
> Please have a look at [1] as this config is invalid.  Let's use a
> classic roadwarrior config:
> right=<vpn gateway>
> rightsubnet=
> leftsourceip=%config
> The VPN gateway will assign a virtual IP to the client and the IPsec
> policies will be for <virtual IP>/32 <->  But after
> installing the virtual IP on the system the client won't automatically
> use it for outbound traffic.  Instead, it would use the physical IP, but
> that wouldn't match the outbound policy with a source selector of
> <virtual IP>/32.  Therefore, charon will install a default route in
> table 220 with that virtual IP set as source IP.  This forces the
> virtual IP as source address for ALL traffic that does not match any
> more specific routes in the same table (or one with higher priority) or
> has not explicitly set a source IP/interface (e.g. via IP_PKTINFO).  So
> even for IKE packets the virtual IP would be used as source, which we
> clearly don't want.
OK, sounds fine.

> That's why the plugin does its own route lookup to
> find the actual route and source IP to reach the other peer while
> ignoring such source routes installed by the daemon.  As explained in my
> last email this last part won't work without dumping the whole routing
> table, unless the approach with marks is used.  The found source IP is
> then finally forced on IKE packets using IP_PKTINFO.

I don't see how this requires us to dump the routing table given that:

1) We know which routing table is ours (i.e. the one to exclude from lookups)
2) We are able to query the kernel for which tables are referenced.
3) We are able to query the kernel on a per-table basis.
4) The kernel will perform longest prefix matching for us.

Why can't we ascertain which routing tables are actually referenced within 
policy routing (aka ip rule) and then successively query each specific table to 
have the kernel tell us which nexthop we need rather than dumping the whole 
thing and trying to do it ourselves.

On a side-note, even with ~500k routes, I don't expect Strongswan to just be 
(apparently endlessly) chewing up a whole CPU core and completely frozen, 
which is exactly what it did. This is basically a self-induced DoS.

> The same is true if you don't use leftsourceip but, for instance, have a
> host with two interfaces one in and one attached to the
> public Internet and you have a config like this:
> leftsubnet=
> rightsubnet=
> In order for traffic generated on the gateway itself to get tunneled,
> charon will also install a source route that forces the IP in the
> subnet installed on the internal interface as source IP for
> all traffic.  As again, the source address would otherwise be the
> physical IP and thus not match the IPsec policies with a source selector
> of  If that's unwanted the route installation can also be
> disabled (charon.install_routes, however, this currently does not
> disable dumping the routing table).

I don't think it's a valid assumption to assume that the IPsec node is 
participating in - that could easily be a routed prefix coming from 
elsewhere. But in any case, let's say that it is - We don't need to download 
the whole routing table in order to figure out what to add.


> Regards,
> Tobias
> [1] https://wiki.strongswan.org/projects/strongswan/wiki/VirtualIp

More information about the Dev mailing list