aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r--src/libcharon/plugins/android/android_service.c2
-rw-r--r--src/libcharon/plugins/ha/ha_tunnel.c4
-rw-r--r--src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c27
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c323
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c25
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c2
-rw-r--r--src/libcharon/plugins/medcli/medcli_config.c6
-rw-r--r--src/libcharon/plugins/nm/nm_service.c2
-rw-r--r--src/libcharon/plugins/sql/sql_config.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c6
-rw-r--r--src/libcharon/plugins/uci/uci_config.c2
11 files changed, 322 insertions, 79 deletions
diff --git a/src/libcharon/plugins/android/android_service.c b/src/libcharon/plugins/android/android_service.c
index c60aa861d..80d068c1f 100644
--- a/src/libcharon/plugins/android/android_service.c
+++ b/src/libcharon/plugins/android/android_service.c
@@ -291,7 +291,7 @@ static job_requeue_t initiate(private_android_service_t *this)
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
ts = traffic_selector_create_dynamic(0, 0, 65535);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c
index faa3b2c5b..e2807c08f 100644
--- a/src/libcharon/plugins/ha/ha_tunnel.c
+++ b/src/libcharon/plugins/ha/ha_tunnel.c
@@ -233,8 +233,8 @@ static void setup_tunnel(private_ha_tunnel_t *this,
identification_create_from_string(remote));
peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
- child_cfg = child_cfg_create("ha", &lifetime, NULL, TRUE,
- MODE_TRANSPORT, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ child_cfg = child_cfg_create("ha", &lifetime, NULL, TRUE, MODE_TRANSPORT,
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c
index 01df4f71a..6b5aeb342 100644
--- a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -1690,10 +1690,11 @@ static status_t group_ipip_sa(private_kernel_klips_ipsec_t *this,
METHOD(kernel_ipsec_t, add_sa, status_t,
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid, lifetime_cfg_t *lifetime,
- u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
- bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ protocol_id_t protocol, u_int32_t reqid, mark_t mark,
+ lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+ u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
+ u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1849,7 +1850,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
METHOD(kernel_ipsec_t, update_sa, status_t,
private_kernel_klips_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap)
+ bool encap, bool new_encap, mark_t mark)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1920,14 +1921,14 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
METHOD(kernel_ipsec_t, query_sa, status_t,
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
+ u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
{
return NOT_SUPPORTED; /* TODO */
}
METHOD(kernel_ipsec_t, del_sa, status_t,
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1992,8 +1993,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool routed)
+ u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int16_t cpi, bool routed)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -2210,7 +2211,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
METHOD(kernel_ipsec_t, query_policy, status_t,
private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ u_int32_t *use_time)
{
#define IDLE_PREFIX "idle="
static const char *path_eroute = "/proc/net/ipsec_eroute";
@@ -2365,7 +2367,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
METHOD(kernel_ipsec_t, del_policy, status_t,
private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ bool unrouted)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg = (struct sadb_msg*)request, *out;
@@ -2574,7 +2577,7 @@ METHOD(kernel_ipsec_t, destroy, void,
{
close(this->socket);
}
- if (this->socket_evnets > 0)
+ if (this->socket_events > 0)
{
close(this->socket_events);
}
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 1b8c1b879..019ec93f8 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -280,6 +280,9 @@ struct policy_entry_t {
/** parameters of installed policy */
struct xfrm_selector sel;
+ /** optional mark */
+ u_int32_t mark;
+
/** associated route installed for this policy */
route_entry_t *route;
@@ -292,7 +295,8 @@ struct policy_entry_t {
*/
static u_int policy_hash(policy_entry_t *key)
{
- chunk_t chunk = chunk_create((void*)&key->sel, sizeof(struct xfrm_selector));
+ chunk_t chunk = chunk_create((void*)&key->sel,
+ sizeof(struct xfrm_selector) + sizeof(u_int32_t));
return chunk_hash(chunk);
}
@@ -301,7 +305,8 @@ static u_int policy_hash(policy_entry_t *key)
*/
static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key)
{
- return memeq(&key->sel, &other_key->sel, sizeof(struct xfrm_selector)) &&
+ return memeq(&key->sel, &other_key->sel,
+ sizeof(struct xfrm_selector) + sizeof(u_int32_t)) &&
key->direction == other_key->direction;
}
@@ -917,11 +922,11 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
METHOD(kernel_ipsec_t, add_sa, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int32_t reqid,
+ u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool inbound, traffic_selector_t* src_ts,
- traffic_selector_t* dst_ts)
+ u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int16_t cpi, bool encap, bool inbound,
+ traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
{
netlink_buf_t request;
char *alg_name;
@@ -934,8 +939,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (ipcomp != IPCOMP_NONE && cpi != 0)
{
lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
- add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, &lft,
- ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
+ add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
+ &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
mode, ipcomp, 0, FALSE, inbound, NULL, NULL);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
@@ -944,9 +949,16 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
- ntohl(spi), reqid);
-
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} "
+ "(mark %u/0x%8x)", ntohl(spi), reqid, mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
+ ntohl(spi), reqid);
+ }
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
@@ -1151,6 +1163,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (encap)
{
+ struct xfrm_encap_tmpl *tmpl;
+
rthdr->rta_type = XFRMA_ENCAP;
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
@@ -1160,7 +1174,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
return FAILED;
}
- struct xfrm_encap_tmpl* tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
+ tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
tmpl->encap_sport = htons(src->get_port(src));
tmpl->encap_dport = htons(dst->get_port(dst));
@@ -1177,9 +1191,36 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
rthdr = XFRM_RTA_NEXT(rthdr);
}
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ rthdr = XFRM_RTA_NEXT(rthdr);
+ }
+
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
+ if (mark.value)
+ {
+ DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x "
+ "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
+ }
return FAILED;
}
return SUCCESS;
@@ -1275,7 +1316,7 @@ static status_t get_replay_state(private_kernel_netlink_ipsec_t *this,
METHOD(kernel_ipsec_t, query_sa, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
+ u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
{
netlink_buf_t request;
struct nlmsghdr *out = NULL, *hdr;
@@ -1285,8 +1326,15 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
-
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%8x)",
+ ntohl(spi), mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
+ }
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETSA;
@@ -1298,6 +1346,24 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
sa_id->proto = proto_ike2kernel(protocol);
sa_id->family = dst->get_family(dst);
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+ struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ }
+
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
{
hdr = out;
@@ -1313,8 +1379,20 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
case NLMSG_ERROR:
{
struct nlmsgerr *err = NLMSG_DATA(hdr);
- DBG1(DBG_KNL, "querying SAD entry with SPI %.8x failed: %s (%d)",
- ntohl(spi), strerror(-err->error), -err->error);
+
+ if (mark.value)
+ {
+ DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
+ "(mark %u/0x%8x) failed: %s (%d)",
+ ntohl(spi), mark.value, mark.mask,
+ strerror(-err->error), -err->error);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
+ "failed: %s (%d)", ntohl(spi),
+ strerror(-err->error), -err->error);
+ }
break;
}
default:
@@ -1341,7 +1419,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
METHOD(kernel_ipsec_t, del_sa, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
{
netlink_buf_t request;
struct nlmsghdr *hdr;
@@ -1350,13 +1428,20 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
/* if IPComp was used, we first delete the additional IPComp SA */
if (cpi)
{
- del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0);
+ del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark);
}
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
-
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%8x)",
+ ntohl(spi), mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
+ }
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = XFRM_MSG_DELSA;
@@ -1368,19 +1453,53 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
sa_id->proto = proto_ike2kernel(protocol);
sa_id->family = dst->get_family(dst);
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+ struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ }
+
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
+ if (mark.value)
+ {
+ DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x "
+ "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
+ }
return FAILED;
}
- DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x (mark %u/0x%8x)",
+ ntohl(spi), mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
+ }
return SUCCESS;
}
METHOD(kernel_ipsec_t, update_sa, status_t,
private_kernel_netlink_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool old_encap, bool new_encap)
+ bool old_encap, bool new_encap, mark_t mark)
{
netlink_buf_t request;
u_char *pos;
@@ -1398,7 +1517,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
if (cpi)
{
update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0,
- src, dst, new_src, new_dst, FALSE, FALSE);
+ src, dst, new_src, new_dst, FALSE, FALSE, mark);
}
memset(&request, 0, sizeof(request));
@@ -1459,7 +1578,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
}
/* delete the old SA (without affecting the IPComp SA) */
- if (del_sa(this, src, dst, spi, protocol, 0) != SUCCESS)
+ if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
{
DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", ntohl(spi));
free(out);
@@ -1558,8 +1677,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool routed)
+ u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int16_t cpi, bool routed)
{
policy_entry_t *current, *policy;
bool found = FALSE;
@@ -1571,6 +1690,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
policy = malloc_thing(policy_entry_t);
memset(policy, 0, sizeof(policy_entry_t));
policy->sel = ts2selector(src_ts, dst_ts);
+ policy->mark = mark.value & mark.mask;
policy->direction = direction;
/* find the policy, which matches EXACTLY */
@@ -1580,9 +1700,19 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
{
/* use existing policy */
current->refcount++;
- DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
- "refcount", src_ts, dst_ts,
- policy_dir_names, direction);
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "policy %R === %R %N (mark %u/0x%8x) "
+ "already exists, increasing refcount",
+ src_ts, dst_ts, policy_dir_names, direction,
+ mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "policy %R === %R %N "
+ "already exists, increasing refcount",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
free(policy);
policy = current;
found = TRUE;
@@ -1593,8 +1723,17 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
policy->refcount = 1;
}
- DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "adding policy %R === %R %N (mark %u/0x%8x)",
+ src_ts, dst_ts, policy_dir_names, direction,
+ mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "adding policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
memset(&request, 0, sizeof(request));
hdr = (struct nlmsghdr*)request;
@@ -1673,6 +1812,25 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
tmpl->mode = mode2kernel(mode);
tmpl->family = src->get_family(src);
+ rthdr = XFRM_RTA_NEXT(rthdr);
+
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ }
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
@@ -1741,7 +1899,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
METHOD(kernel_ipsec_t, query_policy, status_t,
private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ u_int32_t *use_time)
{
netlink_buf_t request;
struct nlmsghdr *out = NULL, *hdr;
@@ -1751,9 +1910,17 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "querying policy %R === %R %N (mark %u/0x%8x)",
+ src_ts, dst_ts, policy_dir_names, direction,
+ mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
+ policy_dir_names, direction);
+ }
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
@@ -1763,6 +1930,25 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
policy_id->sel = ts2selector(src_ts, dst_ts);
policy_id->dir = direction;
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+ struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ }
+
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
{
hdr = out;
@@ -1816,7 +2002,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
METHOD(kernel_ipsec_t, del_policy, status_t,
private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ bool unrouted)
{
policy_entry_t *current, policy, *to_delete = NULL;
route_entry_t *route;
@@ -1824,12 +2011,22 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
struct nlmsghdr *hdr;
struct xfrm_userpolicy_id *policy_id;
- DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x)",
+ src_ts, dst_ts, policy_dir_names, direction,
+ mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "deleting policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
/* create a policy */
memset(&policy, 0, sizeof(policy_entry_t));
policy.sel = ts2selector(src_ts, dst_ts);
+ policy.mark = mark.value & mark.mask;
policy.direction = direction;
/* find the policy */
@@ -1851,8 +2048,17 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
this->mutex->unlock(this->mutex);
if (!to_delete)
{
- DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
- dst_ts, policy_dir_names, direction);
+ if (mark.value)
+ {
+ DBG1(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x) "
+ "failed, not found", src_ts, dst_ts, policy_dir_names,
+ direction, mark.value, mark.mask);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
return NOT_FOUND;
}
@@ -1867,13 +2073,40 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
policy_id->sel = to_delete->sel;
policy_id->dir = direction;
+ if (mark.value)
+ {
+ struct xfrm_mark *mrk;
+ struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
+
+ rthdr->rta_type = XFRMA_MARK;
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
+ hdr->nlmsg_len += rthdr->rta_len;
+ if (hdr->nlmsg_len > sizeof(request))
+ {
+ return FAILED;
+ }
+
+ mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
+ mrk->v = mark.value;
+ mrk->m = mark.mask;
+ }
+
route = to_delete->route;
free(to_delete);
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
+ if (mark.value)
+ {
+ DBG1(DBG_KNL, "unable to delete policy %R === %R %N "
+ "(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names,
+ direction, mark.value, mark.mask);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "unable to delete policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
return FAILED;
}
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 04abf9f4a..a64c27f6f 100644
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1245,10 +1245,11 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
METHOD(kernel_ipsec_t, add_sa, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid, lifetime_cfg_t *lifetime,
- u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
- bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ protocol_id_t protocol, u_int32_t reqid, mark_t mark,
+ lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+ u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
+ u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1392,7 +1393,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
METHOD(kernel_ipsec_t, update_sa, status_t,
private_kernel_pfkey_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap)
+ bool encap, bool new_encap, mark_t mark)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1525,7 +1526,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
METHOD(kernel_ipsec_t, query_sa, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
+ u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1581,7 +1582,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
METHOD(kernel_ipsec_t, del_sa, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1632,8 +1633,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool routed)
+ u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int16_t cpi, bool routed)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1834,7 +1835,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
METHOD(kernel_ipsec_t, query_policy, status_t,
private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ u_int32_t *use_time)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1937,7 +1939,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
METHOD(kernel_ipsec_t, del_policy, status_t,
private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
+ traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+ bool unrouted)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index b9a6f0561..528c9a31b 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -224,7 +224,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
}
child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE,
- MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
child_cfg->add_proposal(child_cfg, proposal);
ts = traffic_selector_create_dynamic(0, 0, 65535);
diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c
index 7b9b5aa40..e57491044 100644
--- a/src/libcharon/plugins/medcli/medcli_config.c
+++ b/src/libcharon/plugins/medcli/medcli_config.c
@@ -181,8 +181,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
identification_create_from_encoding(ID_KEY_ID, other));
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
- child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE,
- MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
@@ -260,7 +260,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
this->current->add_auth_cfg(this->current, auth, FALSE);
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c
index d9badec77..20e6c1529 100644
--- a/src/libcharon/plugins/nm/nm_service.c
+++ b/src/libcharon/plugins/nm/nm_service.c
@@ -444,7 +444,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
child_cfg = child_cfg_create(priv->name, &lifetime,
NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
- ACTION_NONE, ACTION_NONE, ipcomp, 0, 0);
+ ACTION_NONE, ACTION_NONE, ipcomp, 0, 0, NULL);
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
ts = traffic_selector_create_dynamic(0, 0, 65535);
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c
index 8893beaad..d9964cea8 100644
--- a/src/libcharon/plugins/sql/sql_config.c
+++ b/src/libcharon/plugins/sql/sql_config.c
@@ -134,7 +134,7 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
.time = { .life = lifetime, .rekey = rekeytime, .jitter = jitter }
};
child_cfg = child_cfg_create(name, &lft, updown, hostaccess, mode,
- dpd, close, ipcomp, 0, 0);
+ dpd, close, ipcomp, 0, 0, NULL);
/* TODO: read proposal from db */
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
add_traffic_selectors(this, child_cfg, id);
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index c86d1457a..41bf5d1a1 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -769,6 +769,10 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
.jitter = msg->add_conn.rekey.margin_packets * msg->add_conn.rekey.fuzz / 100
}
};
+ mark_t mark = {
+ .value = msg->add_conn.mark.value,
+ .mask = msg->add_conn.mark.mask
+ };
switch (msg->add_conn.dpd.action)
{ /* map startes magic values to our action type */
@@ -787,7 +791,7 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
msg->add_conn.name, &lifetime,
msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
msg->add_conn.mode, dpd, dpd, msg->add_conn.ipcomp,
- msg->add_conn.inactivity, msg->add_conn.reqid);
+ msg->add_conn.inactivity, msg->add_conn.reqid, &mark);
child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,
msg->add_conn.install_policy);
add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c
index 00d05c401..ba93d8734 100644
--- a/src/libcharon/plugins/uci/uci_config.c
+++ b/src/libcharon/plugins/uci/uci_config.c
@@ -196,7 +196,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
- ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
+ ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));