kernel-interface: Consider interface ID when allocating reqids
authorTobias Brunner <tobias@strongswan.org>
Tue, 12 Feb 2019 10:10:04 +0000 (11:10 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 3 Apr 2019 10:00:08 +0000 (12:00 +0200)
src/libcharon/kernel/kernel_interface.c
src/libcharon/kernel/kernel_interface.h
src/libcharon/sa/child_sa.c

index 91ca259..e216c97 100644 (file)
@@ -199,6 +199,10 @@ typedef struct {
        mark_t mark_in;
        /** outbound mark used for SA */
        mark_t mark_out;
+       /** inbound interface ID used for SA */
+       uint32_t if_id_in;
+       /** outbound interface ID used for SA */
+       uint32_t if_id_out;
        /** local traffic selectors */
        array_t *local;
        /** remote traffic selectors */
@@ -222,7 +226,9 @@ static u_int hash_reqid(reqid_entry_t *entry)
 {
        return chunk_hash_inc(chunk_from_thing(entry->reqid),
                                chunk_hash_inc(chunk_from_thing(entry->mark_in),
-                                       chunk_hash(chunk_from_thing(entry->mark_out))));
+                                       chunk_hash_inc(chunk_from_thing(entry->mark_out),
+                                               chunk_hash_inc(chunk_from_thing(entry->if_id_in),
+                                                       chunk_hash(chunk_from_thing(entry->if_id_out))))));
 }
 
 /**
@@ -234,7 +240,9 @@ static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b)
                   a->mark_in.value == b->mark_in.value &&
                   a->mark_in.mask == b->mark_in.mask &&
                   a->mark_out.value == b->mark_out.value &&
-                  a->mark_out.mask == b->mark_out.mask;
+                  a->mark_out.mask == b->mark_out.mask &&
+                  a->if_id_in == b->if_id_in &&
+                  a->if_id_out == b->if_id_out;
 }
 
 /**
@@ -262,7 +270,9 @@ static u_int hash_reqid_by_ts(reqid_entry_t *entry)
 {
        return hash_ts_array(entry->local, hash_ts_array(entry->remote,
                        chunk_hash_inc(chunk_from_thing(entry->mark_in),
-                               chunk_hash(chunk_from_thing(entry->mark_out)))));
+                               chunk_hash_inc(chunk_from_thing(entry->mark_out),
+                                       chunk_hash_inc(chunk_from_thing(entry->if_id_in),
+                                               chunk_hash(chunk_from_thing(entry->if_id_out)))))));
 }
 
 /**
@@ -301,7 +311,9 @@ static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b)
                   a->mark_in.value == b->mark_in.value &&
                   a->mark_in.mask == b->mark_in.mask &&
                   a->mark_out.value == b->mark_out.value &&
-                  a->mark_out.mask == b->mark_out.mask;
+                  a->mark_out.mask == b->mark_out.mask &&
+                  a->if_id_in == b->if_id_in &&
+                  a->if_id_out == b->if_id_out;
 }
 
 /**
@@ -328,7 +340,8 @@ static array_t *array_from_ts_list(linked_list_t *list)
 METHOD(kernel_interface_t, alloc_reqid, status_t,
        private_kernel_interface_t *this,
        linked_list_t *local_ts, linked_list_t *remote_ts,
-       mark_t mark_in, mark_t mark_out, uint32_t *reqid)
+       mark_t mark_in, mark_t mark_out, uint32_t if_id_in, uint32_t if_id_out,
+       uint32_t *reqid)
 {
        static uint32_t counter = 0;
        reqid_entry_t *entry = NULL, *tmpl;
@@ -339,6 +352,8 @@ METHOD(kernel_interface_t, alloc_reqid, status_t,
                .remote = array_from_ts_list(remote_ts),
                .mark_in = mark_in,
                .mark_out = mark_out,
+               .if_id_in = if_id_in,
+               .if_id_out = if_id_out,
                .reqid = *reqid,
        );
 
@@ -381,12 +396,14 @@ METHOD(kernel_interface_t, alloc_reqid, status_t,
 
 METHOD(kernel_interface_t, release_reqid, status_t,
        private_kernel_interface_t *this, uint32_t reqid,
-       mark_t mark_in, mark_t mark_out)
+       mark_t mark_in, mark_t mark_out, uint32_t if_id_in, uint32_t if_id_out)
 {
        reqid_entry_t *entry, tmpl = {
                .reqid = reqid,
                .mark_in = mark_in,
                .mark_out = mark_out,
+               .if_id_in = if_id_in,
+               .if_id_out = if_id_out,
        };
 
        this->mutex->lock(this->mutex);
index f4f55ad..b7e3686 100644 (file)
@@ -143,13 +143,15 @@ struct kernel_interface_t {
         * @param remote_ts     traffic selectors of remote side for SA
         * @param mark_in       inbound mark on SA
         * @param mark_out      outbound mark on SA
+        * @param if_id_in      inbound interface ID on SA
+        * @param if_id_out     outbound interface ID on SA
         * @param reqid         allocated reqid
         * @return                      SUCCESS if reqid allocated
         */
        status_t (*alloc_reqid)(kernel_interface_t *this,
                                                        linked_list_t *local_ts, linked_list_t *remote_ts,
-                                                       mark_t mark_in, mark_t mark_out,
-                                                       uint32_t *reqid);
+                                                       mark_t mark_in, mark_t mark_out, uint32_t if_id_in,
+                                                       uint32_t if_id_out, uint32_t *reqid);
 
        /**
         * Release a previously allocated reqid.
@@ -157,10 +159,13 @@ struct kernel_interface_t {
         * @param reqid         reqid to release
         * @param mark_in       inbound mark on SA
         * @param mark_out      outbound mark on SA
+        * @param if_id_in      inbound interface ID on SA
+        * @param if_id_out     outbound interface ID on SA
         * @return                      SUCCESS if reqid released
         */
        status_t (*release_reqid)(kernel_interface_t *this, uint32_t reqid,
-                                                         mark_t mark_in, mark_t mark_out);
+                                                         mark_t mark_in, mark_t mark_out,
+                                                         uint32_t if_id_in, uint32_t if_id_out);
 
        /**
         * Add an SA to the SAD.
index a341f29..f74d0c2 100644 (file)
@@ -832,7 +832,8 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
        if (!this->reqid_allocated && !this->static_reqid)
        {
                status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts,
-                                                               this->mark_in, this->mark_out, &this->reqid);
+                                                               this->mark_in, this->mark_out, 0, 0,
+                                                               &this->reqid);
                if (status != SUCCESS)
                {
                        my_ts->destroy(my_ts);
@@ -1228,7 +1229,7 @@ METHOD(child_sa_t, install_policies, status_t,
                                                                        array_create_enumerator(this->other_ts));
                status = charon->kernel->alloc_reqid(
                                                        charon->kernel, my_ts_list, other_ts_list,
-                                                       this->mark_in, this->mark_out, &this->reqid);
+                                                       this->mark_in, this->mark_out, 0, 0, &this->reqid);
                my_ts_list->destroy(my_ts_list);
                other_ts_list->destroy(other_ts_list);
                if (status != SUCCESS)
@@ -1703,7 +1704,8 @@ METHOD(child_sa_t, destroy, void,
        if (this->reqid_allocated)
        {
                if (charon->kernel->release_reqid(charon->kernel,
-                                               this->reqid, this->mark_in, this->mark_out) != SUCCESS)
+                                               this->reqid, this->mark_in, this->mark_out,
+                                               0, 0) != SUCCESS)
                {
                        DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
                }