Subject: Re: IPsec: Why do pfkey_getspi and xfrm_alloc_userspi call xfrm_find_acq_byseq?

From: Christophe Gouault <[email-masked]>
Date: Mon, 23 Aug 2010 16:47:18 +0200

Christophe Gouault wrote:
> Hi David,
>
> First of all, thank you for your answer.
>
> David Miller wrote:
>> From: Christophe Gouault <[email-masked]>
>> Date: Thu, 19 Aug 2010 14:55:21 +0200
>>
>>> The call to xfrm_find_acq_byseq() by the pfkey_getspi() and
>>> xfrm_alloc_userspi() functions is quite costly and proves to entail
>>> scalability issues when performing thousands of IKE negotiations with
>>> racoon (from ipsec-tools distribution) or charon (from strongswan
>>> distribution).
>>>
>>> Removing this call in the kernel drastically accelerates the
>>> processing and does not seem to entail functional problems.
>>>
>>> For now, I don't see the point of this call. I need to understand its
>>> purpose, because I'm highly tempted to simply remove it.
>> First of all, removing a function because you don't understand
>> why it's there is rarely a good idea :-)
> Yes, don't worry, I never act that way. I was deliberately a little 
> provocative ;-)
>> I think the semantics require that we check for existing ACQUIRE
>> state entries before we allocate an SPI.
> Well, I still don't see in which case this can happen. The only 
> situations in which an ACQUIRE state entry is created is when an 
> acquire message is raised by the kernel (this creates a temporary 
> outbound state) or when a getspi is issued from the userland (this 
> creates a temporary state, as far as I know, this is the future 
> inbound state negotiated by IKE).
>
> In my humble opinion, issuing a getspi for the output state does not 
> make sense since the SPI is chosen by the destination host.
> So the possibly existing ACQUIRE state entry would be the result of a 
> former getspi with the same value of the seq field. So this call would 
> aim at cancelling a former call to getspi,
Correction: it does not cancel the former call but returns the existing 
ACQUIRE state entry.

By the way, is it possible that the first call (to xfrm_find_acq_byseq) 
returns a state that the second call (to xfrm_find_acq) would not find?
> maybe to cope with an application that would retry a failed 
> negotiation before the former getspi expired?... I'm not really 
> convinced by this explanation.
>
> But there are maybe other uses of the getspi call than assigning a SPI 
> for the inbound state of an IKE negotiation...
>> The likelyhood of breaking something if you remove the call is very
>> high.
> Probably. I'm still interested in a concrete example ;-)
>
> Christophe