kernel-interface: Add a separate "update" flag to add_sa()
authorMartin Willi <martin@revosec.ch>
Mon, 9 Mar 2015 17:04:54 +0000 (18:04 +0100)
committerMartin Willi <martin@revosec.ch>
Mon, 9 Mar 2015 17:18:20 +0000 (18:18 +0100)
The current "inbound" flag is used for two purposes: To define the actual
direction of the SA, but also to determine the operation used for SA
installation. If an SPI has been allocated, an update operation is required
instead of an add.

While the inbound flag normally defines the kind of operation required, this
is not necessarily true in all cases. On the HA passive node, we install inbound
SAs without prior SPI allocation.

src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
src/libcharon/plugins/load_tester/load_tester_ipsec.c
src/libcharon/sa/child_sa.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_ipsec.h
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c

index 69341a4..734b1ec 100644 (file)
@@ -86,7 +86,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t* src_ts, linked_list_t* dst_ts)
 {
        esa_info_t esa;
index e6c5d6a..eabcb93 100644 (file)
@@ -254,7 +254,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t *src_ts, linked_list_t *dst_ts)
 {
        return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,
index 86db9e6..b38ded8 100644 (file)
@@ -2103,7 +2103,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t *src_ts, linked_list_t *dst_ts)
 {
        host_t *local, *remote;
index 68af479..62d43e3 100644 (file)
@@ -55,7 +55,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t *src_ts, linked_list_t *dst_ts)
 {
        return SUCCESS;
index 1f37fac..9c74b95 100644 (file)
@@ -750,7 +750,7 @@ METHOD(child_sa_t, install, status_t,
                                inbound ? this->mark_in : this->mark_out, tfc,
                                lifetime, enc_alg, encr, int_alg, integ, this->mode,
                                this->ipcomp, cpi, this->config->get_replay_window(this->config),
-                               initiator, this->encap, esn, update, src_ts, dst_ts);
+                               initiator, this->encap, esn, inbound, update, src_ts, dst_ts);
 
        free(lifetime);
 
index 943b513..ce31bd4 100644 (file)
@@ -421,7 +421,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t *src_ts, linked_list_t *dst_ts)
 {
        if (!this->ipsec)
@@ -431,7 +431,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
        return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
                                mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
                                ipcomp, cpi, replay_window, initiator, encap, esn, inbound,
-                               src_ts, dst_ts);
+                               update, src_ts, dst_ts);
 }
 
 METHOD(kernel_interface_t, update_sa, status_t,
index 2d48425..96ce9e2 100644 (file)
@@ -180,6 +180,7 @@ struct kernel_interface_t {
         * @param encap                 enable UDP encapsulation for NAT traversal
         * @param esn                   TRUE to use Extended Sequence Numbers
         * @param inbound               TRUE if this is an inbound SA
+        * @param update                TRUE if an SPI has already been allocated for SA
         * @param src_ts                list of source traffic selectors
         * @param dst_ts                list of destination traffic selectors
         * @return                              SUCCESS if operation completed
@@ -191,8 +192,8 @@ struct kernel_interface_t {
                                                u_int16_t enc_alg, chunk_t enc_key,
                                                u_int16_t int_alg, chunk_t int_key,
                                                ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
-                                               u_int32_t replay_window,
-                                               bool initiator, bool encap, bool esn, bool inbound,
+                                               u_int32_t replay_window, bool initiator, bool encap,
+                                               bool esn, bool inbound, bool update,
                                                linked_list_t *src_ts, linked_list_t *dst_ts);
 
        /**
index f6705ff..19caaa4 100644 (file)
@@ -101,6 +101,7 @@ struct kernel_ipsec_t {
         * @param encap                 enable UDP encapsulation for NAT traversal
         * @param esn                   TRUE to use Extended Sequence Numbers
         * @param inbound               TRUE if this is an inbound SA
+        * @param update                TRUE if an SPI has already been allocated for SA
         * @param src_ts                list of source traffic selectors
         * @param dst_ts                list of destination traffic selectors
         * @return                              SUCCESS if operation completed
@@ -112,8 +113,8 @@ struct kernel_ipsec_t {
                                                u_int16_t enc_alg, chunk_t enc_key,
                                                u_int16_t int_alg, chunk_t int_key,
                                                ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
-                                               u_int32_t replay_window,
-                                               bool initiator, bool encap, bool esn, bool inbound,
+                                               u_int32_t replay_window, bool initiator, bool encap,
+                                               bool esn, bool inbound, bool update,
                                                linked_list_t *src_ts, linked_list_t *dst_ts);
 
        /**
index b4875ba..9534ef0 100644 (file)
@@ -1197,7 +1197,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t* src_ts, linked_list_t* dst_ts)
 {
        netlink_buf_t request;
@@ -1217,7 +1217,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
                add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
                           tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
                           chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE,
-                          inbound, src_ts, dst_ts);
+                          inbound, update, src_ts, dst_ts);
                ipcomp = IPCOMP_NONE;
                /* use transport mode ESP SA, IPComp uses tunnel mode */
                mode = MODE_TRANSPORT;
@@ -1230,7 +1230,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 
        hdr = &request.hdr;
        hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-       hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
+       hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
 
        sa = NLMSG_DATA(hdr);
index 423b57e..3b32ba5 100644 (file)
@@ -1615,7 +1615,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
        u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
        u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-       bool initiator, bool encap, bool esn, bool inbound,
+       bool initiator, bool encap, bool esn, bool inbound, bool update,
        linked_list_t *src_ts, linked_list_t *dst_ts)
 {
        unsigned char request[PFKEY_BUFFER_SIZE];
@@ -1634,13 +1634,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
                add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
                           tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
                           chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound,
-                          NULL, NULL);
+                          update, NULL, NULL);
                ipcomp = IPCOMP_NONE;
                /* use transport mode ESP SA, IPComp uses tunnel mode */
                mode = MODE_TRANSPORT;
        }
 
-       if (inbound)
+       if (update)
        {
                /* As we didn't know the reqid during SPI allocation, we used reqid
                 * zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we