IPsec SA manager implements update_sa()
authorTobias Brunner <tobias@strongswan.org>
Wed, 10 Oct 2012 13:31:02 +0000 (15:31 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 16 Oct 2012 12:16:17 +0000 (14:16 +0200)
src/libipsec/ipsec_sa_mgr.c
src/libipsec/ipsec_sa_mgr.h

index e42c77a..30db46e 100644 (file)
@@ -487,6 +487,44 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
        return SUCCESS;
 }
 
+METHOD(ipsec_sa_mgr_t, update_sa, status_t,
+       private_ipsec_sa_mgr_t *this, u_int32_t spi, u_int8_t protocol,
+       u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
+       bool encap, bool new_encap, mark_t mark)
+{
+       ipsec_sa_entry_t *entry = NULL;
+
+       DBG2(DBG_ESP, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
+                ntohl(spi), src, dst, new_src, new_dst);
+
+       if (!new_encap)
+       {
+               DBG1(DBG_ESP, "failed to update SAD entry: can't deactivate UDP "
+                        "encapsulation");
+               return NOT_SUPPORTED;
+       }
+
+       this->mutex->lock(this->mutex);
+       if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst,
+                                                        (void**)&entry, spi, src, dst) == SUCCESS &&
+               wait_for_entry(this, entry))
+       {
+               entry->sa->set_source(entry->sa, new_src);
+               entry->sa->set_destination(entry->sa, new_dst);
+               /* checkin the entry */
+               entry->locked = FALSE;
+               entry->condvar->signal(entry->condvar);
+       }
+       this->mutex->unlock(this->mutex);
+
+       if (!entry)
+       {
+               DBG1(DBG_ESP, "failed to update SAD entry: not found");
+               return FAILED;
+       }
+       return SUCCESS;
+}
+
 METHOD(ipsec_sa_mgr_t, del_sa, status_t,
        private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, u_int32_t spi,
        u_int8_t protocol, u_int16_t cpi, mark_t mark)
@@ -609,6 +647,7 @@ ipsec_sa_mgr_t *ipsec_sa_mgr_create()
                .public = {
                        .get_spi = _get_spi,
                        .add_sa = _add_sa,
+                       .update_sa = _update_sa,
                        .del_sa = _del_sa,
                        .checkout_by_spi = _checkout_by_spi,
                        .checkout_by_reqid = _checkout_by_reqid,
index 303b36f..db30a86 100644 (file)
@@ -86,6 +86,27 @@ struct ipsec_sa_mgr_t {
                                           traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
 
        /**
+        * Update the hosts on an installed SA.
+        *
+        * @param spi                   SPI of the SA
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param cpi                   CPI for IPComp, 0 if no IPComp is used
+        * @param src                   current source address
+        * @param dst                   current destination address
+        * @param new_src               new source address
+        * @param new_dst               new destination address
+        * @param encap                 current use of UDP encapsulation
+        * @param new_encap             new use of UDP encapsulation
+        * @param mark                  optional mark for this SA
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*update_sa)(ipsec_sa_mgr_t *this,
+                                                 u_int32_t spi, u_int8_t protocol, u_int16_t cpi,
+                                                 host_t *src, host_t *dst,
+                                                 host_t *new_src, host_t *new_dst,
+                                                 bool encap, bool new_encap, mark_t mark);
+
+       /**
         * Delete a previously added SA
         *
         * @param spi                   SPI of the SA