kernel-netlink: Try to add new inbound SA if update fails
authorThomas Egerer <thomas.egerer@secunet.com>
Thu, 9 Mar 2017 17:26:35 +0000 (18:26 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 23 May 2017 15:58:51 +0000 (17:58 +0200)
When establishing a traffic-triggered CHILD_SA involves the setup of an
IKE_SA more than one exchange is required. As a result the temporary
acquire state may have expired -- even if the acquire expiration
(xfrm_acq_expires) time is set properly (165 by default).  The expire
message sent by the kernel is not processed in charon since no trap can
be found by the trap manager.
A possible solution could be to track allocated SPIs.  But since this is
a corner case and the tracking introduces quite a bit of overhead, it
seems much more sensible to add a new state if the update of a state
fails with NOT_FOUND.

Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c

index 9a40927..6f18674 100644 (file)
@@ -1666,10 +1666,19 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
                }
        }
 
-       if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
+       status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr);
+       if (status == NOT_FOUND && data->update)
        {
-               DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x%s", ntohl(id->spi),
-                        markstr);
+               DBG1(DBG_KNL, "allocated SPI not found anymore, try to add SAD entry");
+               hdr->nlmsg_type = XFRM_MSG_NEWSA;
+               status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr);
+       }
+
+       if (status != SUCCESS)
+       {
+               DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x%s (%N)", ntohl(id->spi),
+                        markstr, status_names, status);
+               status = FAILED;
                goto failed;
        }