uint32_t if_id_in, uint32_t if_id_out)
{
private_child_sa_t *this;
- static refcount_t unique_id = 0, unique_mark = 0, unique_if_id = 0;
+ static refcount_t unique_id = 0, unique_mark = 0;
INIT(this,
.public = {
this->if_id_out = if_id_out;
}
+ allocate_unique_if_ids(&this->if_id_in, &this->if_id_out);
+
if (MARK_IS_UNIQUE(this->mark_in.value) ||
MARK_IS_UNIQUE(this->mark_out.value))
{
}
}
- if (IF_ID_IS_UNIQUE(this->if_id_in) ||
- IF_ID_IS_UNIQUE(this->if_id_out))
- {
- refcount_t if_id = 0;
- bool unique_dir = this->if_id_in == IF_ID_UNIQUE_DIR ||
- this->if_id_out == IF_ID_UNIQUE_DIR;
-
- if (!unique_dir)
- {
- if_id = ref_get(&unique_if_id);
- }
- if (IF_ID_IS_UNIQUE(this->if_id_in))
- {
- this->if_id_in = unique_dir ? ref_get(&unique_if_id) : if_id;
- }
- if (IF_ID_IS_UNIQUE(this->if_id_out))
- {
- this->if_id_out = unique_dir ? ref_get(&unique_if_id) : if_id;
- }
- }
-
if (!this->reqid)
{
/* reuse old reqid if we are rekeying an existing CHILD_SA and when
}
/*
- * See header
+ * Described in header
*/
bool if_id_from_string(const char *value, uint32_t *if_id)
{
}
return TRUE;
}
+
+/*
+ * Described in header
+ */
+void allocate_unique_if_ids(uint32_t *in, uint32_t *out)
+{
+ static refcount_t unique_if_id = 0;
+
+ if (IF_ID_IS_UNIQUE(*in) || IF_ID_IS_UNIQUE(*out))
+ {
+ refcount_t if_id = 0;
+ bool unique_dir = *in == IF_ID_UNIQUE_DIR ||
+ *out == IF_ID_UNIQUE_DIR;
+
+ if (!unique_dir)
+ {
+ if_id = ref_get(&unique_if_id);
+ }
+ if (IF_ID_IS_UNIQUE(*in))
+ {
+ *in = unique_dir ? ref_get(&unique_if_id) : if_id;
+ }
+ if (IF_ID_IS_UNIQUE(*out))
+ {
+ *out = unique_dir ? ref_get(&unique_if_id) : if_id;
+ }
+ }
+}
}
END_TEST
+/*******************************************************************************
+ * allocate_unique_if_ids
+ */
+
+static struct {
+ uint32_t in;
+ uint32_t out;
+ uint32_t exp_in;
+ uint32_t exp_out;
+} unique_if_id_data[] = {
+ {0, 0, 0, 0 },
+ {42, 42, 42, 42 },
+ {42, 1337, 42, 1337 },
+ /* each call increases the internal counter by 1 or 2*/
+ {IF_ID_UNIQUE, 42, 1, 42 },
+ {42, IF_ID_UNIQUE, 42, 2 },
+ {IF_ID_UNIQUE_DIR, 42, 3, 42 },
+ {42, IF_ID_UNIQUE_DIR, 42, 4 },
+ {IF_ID_UNIQUE, IF_ID_UNIQUE, 5, 5 },
+ {IF_ID_UNIQUE_DIR, IF_ID_UNIQUE, 6, 7 },
+ {IF_ID_UNIQUE, IF_ID_UNIQUE_DIR, 8, 9 },
+ {IF_ID_UNIQUE_DIR, IF_ID_UNIQUE_DIR, 10, 11 },
+};
+
+START_TEST(test_allocate_unique_if_ids)
+{
+ uint32_t if_id_in = unique_if_id_data[_i].in,
+ if_id_out = unique_if_id_data[_i].out;
+
+ allocate_unique_if_ids(&if_id_in, &if_id_out);
+ ck_assert_int_eq(if_id_in, unique_if_id_data[_i].exp_in);
+ ck_assert_int_eq(if_id_out, unique_if_id_data[_i].exp_out);
+}
+END_TEST
+
/*******************************************************************************
* signature_schemes_for_key
*/
tcase_add_loop_test(tc, test_if_id_from_string, 0, countof(if_id_data));
suite_add_tcase(s, tc);
+ tc = tcase_create("allocate_unique_if_ids");
+ tcase_add_loop_test(tc, test_allocate_unique_if_ids, 0, countof(unique_if_id_data));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("signature_schemes_for_key");
tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data));
suite_add_tcase(s, tc);