summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/attr/attr_provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/attr/attr_provider.c')
-rw-r--r--src/libcharon/plugins/attr/attr_provider.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c
index cac0ae4bf..1de571c3f 100644
--- a/src/libcharon/plugins/attr/attr_provider.c
+++ b/src/libcharon/plugins/attr/attr_provider.c
@@ -54,6 +54,8 @@ struct attribute_entry_t {
configuration_attribute_type_t type;
/** attribute value */
chunk_t value;
+ /** associated IKE version */
+ ike_version_t ike;
};
/**
@@ -66,26 +68,51 @@ static void attribute_destroy(attribute_entry_t *this)
}
/**
+ * Data for attribute enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ ike_version_t ike;
+} enumerator_data_t;
+
+/**
* convert enumerator value from attribute_entry
*/
-static bool attr_enum_filter(void *null, attribute_entry_t **in,
+static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in,
configuration_attribute_type_t *type, void* none, chunk_t *value)
{
- *type = (*in)->type;
- *value = (*in)->value;
- return TRUE;
+ if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike)
+ {
+ *type = (*in)->type;
+ *value = (*in)->value;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+CALLBACK(attr_enum_destroy, void,
+ enumerator_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_attr_provider_t *this, linked_list_t *pools,
ike_sa_t *ike_sa, linked_list_t *vips)
{
+ enumerator_data_t *data;
+
if (vips->get_count(vips))
{
+ INIT(data,
+ .lock = this->lock,
+ .ike = ike_sa->get_version(ike_sa),
+ );
this->lock->read_lock(this->lock);
return enumerator_create_filter(
this->attributes->create_enumerator(this->attributes),
- (void*)attr_enum_filter, this->lock, (void*)this->lock->unlock);
+ (void*)attr_enum_filter, data, attr_enum_destroy);
}
return enumerator_create_empty();
}
@@ -116,8 +143,6 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
host = host_create_from_string(str, 0);
if (host)
{
- entry = malloc_thing(attribute_entry_t);
-
if (host->get_family(host) == AF_INET6)
{
switch (type)
@@ -132,8 +157,11 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
break;
}
}
- entry->type = type;
- entry->value = chunk_clone(host->get_address(host));
+ INIT(entry,
+ .type = type,
+ .value = chunk_clone(host->get_address(host)),
+ .ike = IKE_ANY,
+ );
host->destroy(host);
DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value);
@@ -149,18 +177,20 @@ typedef struct {
char *name;
configuration_attribute_type_t v4;
configuration_attribute_type_t v6;
+ ike_version_t ike;
} attribute_type_key_t;
static attribute_type_key_t keys[] = {
- {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS},
- {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS},
- {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS},
- {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP},
- {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK},
- {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER},
- {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET},
- {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE},
- {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN},
+ {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY},
+ {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY},
+ {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY},
+ {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY},
+ {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY},
+ {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY},
+ {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY},
+ {"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2},
+ {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1},
+ {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1},
};
/**
@@ -275,6 +305,7 @@ static void load_entries(private_attr_provider_t *this)
INIT(entry,
.type = type,
.value = data,
+ .ike = mapped ? mapped->ike : IKE_ANY,
);
DBG2(DBG_CFG, "loaded attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value);