/**
* 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, linked_list_t *hosts)
+static u_int get_ts_match(child_cfg_t *cfg, bool local,
+ linked_list_t *sup_list, linked_list_t *hosts,
+ linked_list_t *sup_labels)
{
linked_list_t *cfg_list;
enumerator_t *sup_enum, *cfg_enum;
traffic_selector_t *sup_ts, *cfg_ts, *subset;
- int match = 0, round;
+ sec_label_t *label;
+ u_int match = 0, round;
+ bool exact = FALSE;
+
+ if (cfg->select_label(cfg, sup_labels, TRUE, &label, &exact))
+ {
+ if (label)
+ {
+ match += exact ? 500 : 100;
+ }
+ }
+ else
+ { /* label config doesn't match, no need to check TS */
+ return match;
+ }
/* fetch configured TS list, narrowing dynamic TS */
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
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,
- linked_list_t *my_hosts, linked_list_t *other_hosts)
+ linked_list_t *my_hosts, linked_list_t *other_hosts,
+ linked_list_t *my_labels, linked_list_t *other_labels)
{
child_cfg_t *current, *found = NULL;
enumerator_t *enumerator;
- int best = 0;
+ u_int best = 0;
DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
enumerator = create_child_cfg_enumerator(this);
while (enumerator->enumerate(enumerator, ¤t))
{
- int my_prio, other_prio;
-
- my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
- other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
+ u_int my_prio, other_prio;
- if (my_prio && other_prio)
+ my_prio = get_ts_match(current, TRUE, my_ts, my_hosts, my_labels);
+ if (!my_prio)
+ {
+ continue;
+ }
+ other_prio = get_ts_match(current, FALSE, other_ts, other_hosts,
+ other_labels);
+ if (other_prio)
{
- DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d",
+ DBG2(DBG_CFG, " candidate \"%s\" with prio %u+%u",
current->get_name(current), my_prio, other_prio);
if (my_prio + other_prio > best)
{
enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
/**
- * Select a CHILD config from traffic selectors.
+ * Select a CHILD config from received traffic selectors.
*
* @param my_ts TS for local side
* @param other_ts 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
+ * @param my_labels optional local security labels
+ * @param other_labels optional remove security labels
+ * @return selected CHILD config, or NULL if no match found
*/
- child_cfg_t* (*select_child_cfg) (peer_cfg_t *this,
+ 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);
+ linked_list_t *my_hosts, linked_list_t *other_hosts,
+ linked_list_t *my_labels, linked_list_t *other_labels);
/**
* Add an authentication config to the peer configuration.
listi = get_dynamic_hosts(this->ike_sa, FALSE);
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
tsr ?: this->tsr, tsi ?: this->tsi,
- listr, listi);
+ listr, listi, NULL, NULL);
if ((tsi || tsr) && child_cfg &&
child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
{
{
/* no match for the substituted NAT selectors, try it without */
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
- this->tsr, this->tsi, listr, listi);
+ this->tsr, this->tsi,
+ listr, listi, NULL, NULL);
}
listr->destroy(listr);
listi->destroy(listi);