On 28.04.2017 12:27, Peltonen, Janne (Nokia - FI/Espoo) wrote:
> Hi,
> 
>> -----Original Message-----
>> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On Behalf Of Dmitry 
>> Eremin-
>> Solenikov
>> Sent: Friday, April 28, 2017 11:59 AM
>> To: lng-odp-forward <lng-odp@lists.linaro.org>
>> Subject: [lng-odp] IPsec SA disabling
>>
>> Hello,
>>
>> While responding to Janne's email, I've come to an issue which warrants
>> a separate discussion IMO.
>>
>> Consider the following scenario. Application with two thread.
>>
>> - First thread: gets outbound packet, finds SA through SPD, configures
>> IPsec request, submits it.
>>
>> - Second thread: wants to disable SA, pending deletion.
>>
>> Is that an application error if SA was disabled after being looked up,
>> but before being submitted by another thread? Yes it is.
> 
> Yes, it would be an error.
> 
>> Right now SA
>> disabling/deletion is susceptible to race conditions. It requires an app
>> to lock SA after lookup, unlock it after submission, etc. 
> 
> To avoid races one indeed currently needs some synchronization in the
> application side. Not necessarily locks but something.
> 
> The OFP IPsec draft code (which is just draft, trying to use the ODP API),
> refcounts SA usage and disables an SA only after it has been removed
> from the SAD and after ongoing operations (tracked through the refcount)
> have completed.

Basically as we already have refcounting on ODP side, I'd suggest
reusing it in applications.

> 
> Because of the above, one could wonder why even have disable() in the
> API. The main reason is to be able to disable offloaded inbound SA
> lookup for the SA so that the SA can be safely deleted (the application
> needs to be able to clean up its own SA state but cannot do it if there
> are in-flight inbound operations that may still refer (through the ctx ptr)
> to the application SA state).

How do you track references of SA instances returned from ODP after
lookup? How will application cope with disabling/deleting SA if it is
returned to another thread by ODP?

> 
>> Should ODP
>> provide API to 'lock' SA?
> 
> It would be convenient to the application if disable() could be called
> at any time. But that could impose difficult synchronization needs
> in the ODP implementation side and therefore we thought that it is
> better to leave that to the application which may need to do some
> synchronization anyway due to its own needs.
> 
> But this is definitely a good topic to ponder about. It is possible
> that the current API got this wrong, but it is not easy to see how
> things should be if they need to be changed.

Well, right now there is a need to do synchronization on ODP side
because odp_ipsec_sa_disable() is not an optional call.

>> I was thinking about smth like:
>>
>> int odp_ipsec_sa_use(odp_ipsec_sa_t sa);
>>
>> void odp_ipsec_sa_unuse(odp_ipsec_sa_t sa);
>>
>> One would use first function when an app has looked up SA in it's own
>> tables and is going to submit it via one of odp_ipsec_* processing calls
>> (except or including SA deletion/disabling -- TBD).
> 
> I am not sure how this would help and be better than something done
> totally at the application side. This would anyway require a bit more
> specification to define the semantics. For instance, when unuse() could
> be called with respect to the enque operations and what exactly it
> would mean.

I'm just suggesting to move reference counting from application to ODP
side, since ODP has to do refcounting anyway (_disable() should wait
till all currently running operations with this SA finish).

I thought basic refounting in mind. Probably we can get this as easy as:

- odp_ipsec_sa_create:

  Create SA with refcnt = 1

- App looks up SA in SAD
  odp_ipsec_sa_use(sa)

- App has looked up SA in SAD, but then changed its mind
  odp_ipsec_sa_unuse(sa)

- ODP looks up SA in cache (via a request from app or via inline inbound
operation
  odp_ipsec_sa_use(sa)

- Application receives SA via a return from IPsec.
  - Processes it and then calls odp_ipsec_sa_unuse().

- Application wants to disable SA in ASYNC mode.
  odp_ipsec_sa_disable() marks SA for disablement.
  - ASYNC case. It calls ipsec_sa_unuse() then returns.

  - SYNC case. It waits for refcount to drop to 1, unuses it then
returns.
  - OR(!) SYNC case. It calls ipsec_sa_unuse(), waits for refcount to
drop to 0, then reutrns.

- odp_ipsec_sa_unuse() is called with refount becoming 0.
  - ASYNC case:
    submit an even.

  - SYNC case:
    do nothing.

-- 
With best wishes
Dmitry

Reply via email to