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

Oliver oliver.d at prodege.com
Tue Sep 29 22:09:33 CEST 2015


On Tuesday 29 September 2015 11:20:14 Tobias Brunner wrote:
> Hi Oliver,
> 
> > Upon attaching to the errant thread I discovered it was happening within
> > the get_route() code for libhydra's netlink plugin. I then noticed that
> > the code for triggering a full dump of the routing table looked very
> > wrong and was certainly incongruous with the comment directly below it.
> 
> It's not wrong.  The whole point of this function is to find a source
> address for the daemon to reach the other peer (or a nexthop when
> installing routes for IPsec tunnels).  The problem is that if, for
> example, a virtual IP is used with rightsubnet=0.0.0.0/0 there will be a
> default route in routing table 220 that forces that virtual IP as source
> IP for all traffic so packets will match the installed IPsec policies.
> Now for the IKE daemon we obviously don't want to use the virtual IP as
> source address as that would send IKE traffic through the tunnel.
> However, a lookup with RTM_GETROUTE without NLM_F_DUMP will just return
> the default route in table 220.  There is no option to tell the kernel
> to ignore routes in only that table (except, see below).  So we get all
> routes and ignore routes from routing table 220 or if the set source IP
> is a virtual IP (e.g. if the routes are not installed in a separate
> routing table).  We always do that for IPv4, but for IPv6 on older
> kernels, i.e. without support for the RTA_PREFSRC attribute, we can only
> ignore these routes if they are installed in a separate routing table as
> the routes won't have the virtual IP set (which means virtual IPs won't
> work anyway for IPv6 on such systems).

OK, I'm not quite seeing how there's a problem here. If you don't use 
NLM_F_DUMP the kernel will return the longest matching route prefix even if you 
set rtm_dst_len to 0 - in fact, the *only* time you need NLM_F_DUMP is if you 
want to specifically know the default route which Strongswan never should.

Also, as I understand it, IPsec transformation policies match on both the 
source and destination regardless of the actual routing - so whether or not a 
packet gets ESP/AH'd is independent of the actual route it's going to be sent 
on.

So, let's take the following scenario:

left=192.0.2.1
right=192.0.2.2
leftsubnet=10.0.0.0/16
rightsubnet=0.0.0.0/0
leftsourceip=192.168.0.1
rightsourceip=192.168.0.2

When we install the routes and IPsec xfrm, there is no risk to the IKE traffic 
because whilst the source on the right will be 192.0.2.2 which matches the 0/0 
xfrm, the destination clearly won't, the same is obviously true in the 
opposite direction.

Now, if *both* sides use the subnet 0.0.0.0/0 that should require special 
handling: an explicit null xfrm policy matching on the /32 of both peers will 
need to be there in order to prevent transformation of the IKE traffic. A route 
shouldn't be necessary because the 0/0 we install should have a nexthop that 
points traffic at the remote endpoint anyway. Additionally, the xfrm in this 
situation will ostensibly break communication with everyone in the local 
routing table (i.e. neighbours) without appropriate overriding null xfrm 
policies.

Finally, just so I'm clear, my expectation of how Strongswan should behave as 
far as installing routes goes is that it should query the kernel for the route 
to the remote peer and then use the nexthop/interface of that route depending 
on whether the link is L2 or L3. So I still can't see how it's necessary to 
download the entire routing table from the kernel.

> 
> > I also note commit 6bd1216e7a8a41eb6c103c27a05f50871e1aef99 which appears
> > to have wanted to fix the issue without actually fixing it.
> 
> No, this commit added a workaround for the whole route lookup using
> marks.  This avoids dumping the routing table altogether if the routing
> rule that directs traffic to table 220 is inverted and has a mark set
> (i.e. charon.plugins.kernel-netlink.fwmark = !<mark> is configured).
> That way we can set that mark on the RTM_GETROUTE message and the kernel
> will automatically ignore routes in routing table 220.  You should
> definitely use this if you have a huge routing table.
> 
> Regards,
> Tobias

Regards,
Oliver.


More information about the Dev mailing list