[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