Derive a dynamic TS to multiple virtual IPs
This commit is contained in:
@@ -237,12 +237,16 @@ METHOD(child_cfg_t, add_traffic_selector, void,
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
|
||||
private_child_cfg_t *this, bool local, linked_list_t *supplied, host_t *host)
|
||||
private_child_cfg_t *this, bool local, linked_list_t *supplied,
|
||||
linked_list_t *hosts)
|
||||
{
|
||||
enumerator_t *e1, *e2;
|
||||
traffic_selector_t *ts1, *ts2, *selected;
|
||||
linked_list_t *result = linked_list_create();
|
||||
linked_list_t *result, *derived;
|
||||
host_t *host;
|
||||
|
||||
result = linked_list_create();
|
||||
derived = linked_list_create();
|
||||
if (local)
|
||||
{
|
||||
e1 = this->my_ts->create_enumerator(this->my_ts);
|
||||
@@ -251,42 +255,48 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
|
||||
{
|
||||
e1 = this->other_ts->create_enumerator(this->other_ts);
|
||||
}
|
||||
/* In a first step, replace "dynamic" TS with the host list */
|
||||
while (e1->enumerate(e1, &ts1))
|
||||
{
|
||||
if (ts1->is_dynamic(ts1))
|
||||
{
|
||||
if (hosts)
|
||||
{
|
||||
e2 = hosts->create_enumerator(hosts);
|
||||
while (e2->enumerate(e2, &host))
|
||||
{
|
||||
ts2 = ts1->clone(ts1);
|
||||
ts2->set_address(ts2, host);
|
||||
result->insert_last(derived, ts2);
|
||||
}
|
||||
e2->destroy(e2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
derived->insert_last(derived, ts1->clone(ts1));
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
|
||||
/* no list supplied, just fetch the stored traffic selectors */
|
||||
DBG2(DBG_CFG, "%s traffic selectors for %s:",
|
||||
supplied ? "selecting" : "proposing", local ? "us" : "other");
|
||||
if (supplied == NULL)
|
||||
{
|
||||
DBG2(DBG_CFG, "proposing traffic selectors for %s:",
|
||||
local ? "us" : "other");
|
||||
while (e1->enumerate(e1, &ts1))
|
||||
while (derived->remove_first(derived, (void**)&ts1) == SUCCESS)
|
||||
{
|
||||
/* we make a copy of the TS, this allows us to update dynamic TS' */
|
||||
selected = ts1->clone(ts1);
|
||||
if (host && selected->is_dynamic(selected))
|
||||
{
|
||||
selected->set_address(selected, host);
|
||||
}
|
||||
DBG2(DBG_CFG, " %R (derived from %R)", selected, ts1);
|
||||
result->insert_last(result, selected);
|
||||
DBG2(DBG_CFG, " %R", ts1);
|
||||
result->insert_last(result, ts1);
|
||||
}
|
||||
e1->destroy(e1);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_CFG, "selecting traffic selectors for %s:",
|
||||
local ? "us" : "other");
|
||||
e2 = supplied->create_enumerator(supplied);
|
||||
/* iterate over all stored selectors */
|
||||
while (e1->enumerate(e1, &ts1))
|
||||
e1 = supplied->create_enumerator(supplied);
|
||||
/* enumerate all configured/derived selectors */
|
||||
while (derived->remove_first(derived, (void**)&ts1) == SUCCESS)
|
||||
{
|
||||
/* we make a copy of the TS, as we have to update dynamic TS' */
|
||||
ts1 = ts1->clone(ts1);
|
||||
if (host && ts1->is_dynamic(ts1))
|
||||
{
|
||||
ts1->set_address(ts1, host);
|
||||
}
|
||||
|
||||
/* iterate over all supplied traffic selectors */
|
||||
while (e2->enumerate(e2, &ts2))
|
||||
/* enumerate all supplied traffic selectors */
|
||||
while (e1->enumerate(e1, &ts2))
|
||||
{
|
||||
selected = ts1->get_subset(ts1, ts2);
|
||||
if (selected)
|
||||
@@ -301,13 +311,12 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
|
||||
ts1, ts2);
|
||||
}
|
||||
}
|
||||
e2->destroy(e2);
|
||||
e2 = supplied->create_enumerator(supplied);
|
||||
supplied->reset_enumerator(supplied, e1);
|
||||
ts1->destroy(ts1);
|
||||
}
|
||||
e1->destroy(e1);
|
||||
e2->destroy(e2);
|
||||
}
|
||||
derived->destroy(derived);
|
||||
|
||||
/* remove any redundant traffic selectors in the list */
|
||||
e1 = result->create_enumerator(result);
|
||||
@@ -322,16 +331,14 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
|
||||
{
|
||||
result->remove_at(result, e2);
|
||||
ts2->destroy(ts2);
|
||||
e1->destroy(e1);
|
||||
e1 = result->create_enumerator(result);
|
||||
result->reset_enumerator(result, e1);
|
||||
break;
|
||||
}
|
||||
if (ts1->is_contained_in(ts1, ts2))
|
||||
{
|
||||
result->remove_at(result, e1);
|
||||
ts1->destroy(ts1);
|
||||
e2->destroy(e2);
|
||||
e2 = result->create_enumerator(result);
|
||||
result->reset_enumerator(result, e2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,12 +129,12 @@ struct child_cfg_t {
|
||||
*
|
||||
* @param local TRUE for TS on local side, FALSE for remote
|
||||
* @param supplied list with TS to select from, or NULL
|
||||
* @param host address to use for narrowing "dynamic" TS', or NULL
|
||||
* @param hosts addresses to use for narrowing "dynamic" TS', host_t
|
||||
* @return list containing the traffic selectors
|
||||
*/
|
||||
linked_list_t *(*get_traffic_selectors)(child_cfg_t *this, bool local,
|
||||
linked_list_t *supplied,
|
||||
host_t *host);
|
||||
linked_list_t *hosts);
|
||||
/**
|
||||
* Get the updown script to run for the CHILD_SA.
|
||||
*
|
||||
|
||||
@@ -256,7 +256,7 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
|
||||
* Check how good a list of TS matches a given child config
|
||||
*/
|
||||
static int get_ts_match(child_cfg_t *cfg, bool local,
|
||||
linked_list_t *sup_list, host_t *host)
|
||||
linked_list_t *sup_list, linked_list_t *hosts)
|
||||
{
|
||||
linked_list_t *cfg_list;
|
||||
enumerator_t *sup_enum, *cfg_enum;
|
||||
@@ -264,7 +264,7 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
|
||||
int match = 0, round;
|
||||
|
||||
/* fetch configured TS list, narrowing dynamic TS */
|
||||
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, host);
|
||||
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts);
|
||||
|
||||
/* use a round counter to rate leading TS with higher priority */
|
||||
round = sup_list->get_count(sup_list);
|
||||
@@ -297,7 +297,7 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
|
||||
|
||||
METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
|
||||
private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
|
||||
host_t *my_host, host_t *other_host)
|
||||
linked_list_t *my_hosts, linked_list_t *other_hosts)
|
||||
{
|
||||
child_cfg_t *current, *found = NULL;
|
||||
enumerator_t *enumerator;
|
||||
@@ -309,8 +309,8 @@ METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
|
||||
{
|
||||
int my_prio, other_prio;
|
||||
|
||||
my_prio = get_ts_match(current, TRUE, my_ts, my_host);
|
||||
other_prio = get_ts_match(current, FALSE, other_ts, other_host);
|
||||
my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
|
||||
other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
|
||||
|
||||
if (my_prio && other_prio)
|
||||
{
|
||||
|
||||
@@ -183,13 +183,13 @@ struct peer_cfg_t {
|
||||
*
|
||||
* @param my_ts TS for local side
|
||||
* @param other_ts TS for remote side
|
||||
* @param my_host host to narrow down dynamic TS for local side
|
||||
* @param other_host host to narrow down dynamic TS for remote side
|
||||
* @param my_hosts hosts to narrow down dynamic TS for local side
|
||||
* @param other_hosts hosts to narrow down dynamic TS for remote side
|
||||
* @return selected CHILD config, or NULL if no match found
|
||||
*/
|
||||
child_cfg_t* (*select_child_cfg) (peer_cfg_t *this, linked_list_t *my_ts,
|
||||
linked_list_t *other_ts, host_t *my_host,
|
||||
host_t *other_host);
|
||||
child_cfg_t* (*select_child_cfg) (peer_cfg_t *this,
|
||||
linked_list_t *my_ts, linked_list_t *other_ts,
|
||||
linked_list_t *my_hosts, linked_list_t *other_hosts);
|
||||
|
||||
/**
|
||||
* Add an authentication config to the peer configuration.
|
||||
|
||||
Reference in New Issue
Block a user