mirror of
https://github.com/strongswan/strongswan.git
synced 2025-11-22 00:01:45 -05:00
Merge branch 'hw-offload'
Allows enabling hardware offload for IPsec SAs as introduced by Linux 4.11 for specific hardware.
This commit is contained in:
commit
6b9361f714
@ -346,7 +346,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||
str = nm_setting_vpn_get_data_item(vpn, "encap");
|
||||
encap = streq(str, "yes");
|
||||
str = nm_setting_vpn_get_data_item(vpn, "ipcomp");
|
||||
child.ipcomp = streq(str, "yes");
|
||||
child.options |= streq(str, "yes") ? OPT_IPCOMP : 0;
|
||||
str = nm_setting_vpn_get_data_item(vpn, "method");
|
||||
if (streq(str, "psk"))
|
||||
{
|
||||
|
||||
@ -296,10 +296,12 @@ enum xfrm_attr_type_t {
|
||||
XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */
|
||||
XFRMA_MARK, /* struct xfrm_mark */
|
||||
XFRMA_TFCPAD, /* __u32 */
|
||||
XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */
|
||||
XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_state_esn */
|
||||
XFRMA_SA_EXTRA_FLAGS, /* __u32 */
|
||||
XFRMA_PROTO, /* __u8 */
|
||||
XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */
|
||||
XFRMA_PAD,
|
||||
XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */
|
||||
__XFRMA_MAX
|
||||
|
||||
#define XFRMA_MAX (__XFRMA_MAX - 1)
|
||||
@ -491,6 +493,13 @@ struct xfrm_address_filter {
|
||||
__u8 dplen;
|
||||
};
|
||||
|
||||
struct xfrm_user_offload {
|
||||
int ifindex;
|
||||
__u8 flags;
|
||||
};
|
||||
#define XFRM_OFFLOAD_IPV6 1
|
||||
#define XFRM_OFFLOAD_INBOUND 2
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/* backwards compatibility for userspace */
|
||||
#define XFRMGRP_ACQUIRE 1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2008-2016 Tobias Brunner
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
@ -53,6 +53,11 @@ struct private_child_cfg_t {
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
child_cfg_option_t options;
|
||||
|
||||
/**
|
||||
* list for all proposals
|
||||
*/
|
||||
@ -73,11 +78,6 @@ struct private_child_cfg_t {
|
||||
*/
|
||||
char *updown;
|
||||
|
||||
/**
|
||||
* allow host access
|
||||
*/
|
||||
bool hostaccess;
|
||||
|
||||
/**
|
||||
* Mode to propose for a initiated CHILD: tunnel/transport
|
||||
*/
|
||||
@ -103,11 +103,6 @@ struct private_child_cfg_t {
|
||||
*/
|
||||
lifetime_cfg_t lifetime;
|
||||
|
||||
/**
|
||||
* enable IPComp
|
||||
*/
|
||||
bool use_ipcomp;
|
||||
|
||||
/**
|
||||
* Inactivity timeout
|
||||
*/
|
||||
@ -143,21 +138,6 @@ struct private_child_cfg_t {
|
||||
*/
|
||||
char *interface;
|
||||
|
||||
/**
|
||||
* set up IPsec transport SA in MIPv6 proxy mode
|
||||
*/
|
||||
bool proxy_mode;
|
||||
|
||||
/**
|
||||
* enable installation and removal of kernel IPsec policies
|
||||
*/
|
||||
bool install_policy;
|
||||
|
||||
/**
|
||||
* Install outbound FWD policies
|
||||
*/
|
||||
bool fwd_out_policy;
|
||||
|
||||
/**
|
||||
* anti-replay window size
|
||||
*/
|
||||
@ -170,6 +150,12 @@ METHOD(child_cfg_t, get_name, char*,
|
||||
return this->name;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, has_option, bool,
|
||||
private_child_cfg_t *this, child_cfg_option_t option)
|
||||
{
|
||||
return this->options & option;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, add_proposal, void,
|
||||
private_child_cfg_t *this, proposal_t *proposal)
|
||||
{
|
||||
@ -311,8 +297,9 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
|
||||
{
|
||||
if (hosts && hosts->get_count(hosts))
|
||||
{ /* set hosts if TS is dynamic or as initiator in transport mode */
|
||||
bool dynamic = ts1->is_dynamic(ts1);
|
||||
if (dynamic || (this->mode == MODE_TRANSPORT && !this->proxy_mode &&
|
||||
bool dynamic = ts1->is_dynamic(ts1),
|
||||
proxy_mode = has_option(this, OPT_PROXY_MODE);
|
||||
if (dynamic || (this->mode == MODE_TRANSPORT && !proxy_mode &&
|
||||
!supplied))
|
||||
{
|
||||
e2 = hosts->create_enumerator(hosts);
|
||||
@ -428,12 +415,6 @@ METHOD(child_cfg_t, get_updown, char*,
|
||||
return this->updown;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, get_hostaccess, bool,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
return this->hostaccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies jitter to the rekey value. Returns the new rekey value.
|
||||
* Note: The distribution of random values is not perfect, but it
|
||||
@ -508,12 +489,6 @@ METHOD(child_cfg_t, get_dh_group, diffie_hellman_group_t,
|
||||
return dh_group;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, use_ipcomp, bool,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
return this->use_ipcomp;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, get_inactivity, uint32_t,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
@ -562,24 +537,6 @@ METHOD(child_cfg_t, set_replay_window, void,
|
||||
this->replay_window = replay_window;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, use_proxy_mode, bool,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
return this->proxy_mode;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, install_policy, bool,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
return this->install_policy;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, install_fwd_out_policy, bool,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
return this->fwd_out_policy;
|
||||
}
|
||||
|
||||
#define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; })
|
||||
#define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); })
|
||||
|
||||
@ -611,13 +568,12 @@ METHOD(child_cfg_t, equals, bool,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return this->hostaccess == other->hostaccess &&
|
||||
return this->options == other->options &&
|
||||
this->mode == other->mode &&
|
||||
this->start_action == other->start_action &&
|
||||
this->dpd_action == other->dpd_action &&
|
||||
this->close_action == other->close_action &&
|
||||
LIFETIME_EQUALS(this->lifetime, other->lifetime) &&
|
||||
this->use_ipcomp == other->use_ipcomp &&
|
||||
this->inactivity == other->inactivity &&
|
||||
this->reqid == other->reqid &&
|
||||
this->mark_in.value == other->mark_in.value &&
|
||||
@ -627,9 +583,6 @@ METHOD(child_cfg_t, equals, bool,
|
||||
this->tfc == other->tfc &&
|
||||
this->manual_prio == other->manual_prio &&
|
||||
this->replay_window == other->replay_window &&
|
||||
this->proxy_mode == other->proxy_mode &&
|
||||
this->install_policy == other->install_policy &&
|
||||
this->fwd_out_policy == other->fwd_out_policy &&
|
||||
streq(this->updown, other->updown) &&
|
||||
streq(this->interface, other->interface);
|
||||
}
|
||||
@ -672,14 +625,12 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
||||
.get_proposals = _get_proposals,
|
||||
.select_proposal = _select_proposal,
|
||||
.get_updown = _get_updown,
|
||||
.get_hostaccess = _get_hostaccess,
|
||||
.get_mode = _get_mode,
|
||||
.get_start_action = _get_start_action,
|
||||
.get_dpd_action = _get_dpd_action,
|
||||
.get_close_action = _get_close_action,
|
||||
.get_lifetime = _get_lifetime,
|
||||
.get_dh_group = _get_dh_group,
|
||||
.use_ipcomp = _use_ipcomp,
|
||||
.get_inactivity = _get_inactivity,
|
||||
.get_reqid = _get_reqid,
|
||||
.get_mark = _get_mark,
|
||||
@ -688,19 +639,16 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
||||
.get_interface = _get_interface,
|
||||
.get_replay_window = _get_replay_window,
|
||||
.set_replay_window = _set_replay_window,
|
||||
.use_proxy_mode = _use_proxy_mode,
|
||||
.install_policy = _install_policy,
|
||||
.install_fwd_out_policy = _install_fwd_out_policy,
|
||||
.has_option = _has_option,
|
||||
.equals = _equals,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.name = strdup(name),
|
||||
.options = data->options,
|
||||
.updown = strdupnull(data->updown),
|
||||
.hostaccess = data->hostaccess,
|
||||
.reqid = data->reqid,
|
||||
.mode = data->mode,
|
||||
.proxy_mode = data->proxy_mode,
|
||||
.start_action = data->start_action,
|
||||
.dpd_action = data->dpd_action,
|
||||
.close_action = data->close_action,
|
||||
@ -708,12 +656,9 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
||||
.mark_out = data->mark_out,
|
||||
.lifetime = data->lifetime,
|
||||
.inactivity = data->inactivity,
|
||||
.use_ipcomp = data->ipcomp,
|
||||
.tfc = data->tfc,
|
||||
.manual_prio = data->priority,
|
||||
.interface = strdupnull(data->interface),
|
||||
.install_policy = !data->suppress_policies,
|
||||
.fwd_out_policy = data->fwd_out_policies,
|
||||
.refcount = 1,
|
||||
.proposals = linked_list_create(),
|
||||
.my_ts = linked_list_create(),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2008-2016 Tobias Brunner
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
@ -25,6 +25,7 @@
|
||||
#define CHILD_CFG_H_
|
||||
|
||||
typedef enum action_t action_t;
|
||||
typedef enum child_cfg_option_t child_cfg_option_t;
|
||||
typedef struct child_cfg_t child_cfg_t;
|
||||
typedef struct child_cfg_create_t child_cfg_create_t;
|
||||
|
||||
@ -146,13 +147,6 @@ struct child_cfg_t {
|
||||
*/
|
||||
char* (*get_updown)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Should we allow access to the local host (gateway)?
|
||||
*
|
||||
* @return value of hostaccess flag
|
||||
*/
|
||||
bool (*get_hostaccess) (child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the lifetime configuration of a CHILD_SA.
|
||||
*
|
||||
@ -202,14 +196,6 @@ struct child_cfg_t {
|
||||
*/
|
||||
diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Check whether IPComp should be used, if the other peer supports it.
|
||||
*
|
||||
* @return TRUE, if IPComp should be used
|
||||
* FALSE, otherwise
|
||||
*/
|
||||
bool (*use_ipcomp)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the inactivity timeout value.
|
||||
*
|
||||
@ -263,33 +249,17 @@ struct child_cfg_t {
|
||||
/**
|
||||
* Set anti-replay window size
|
||||
*
|
||||
* @param window anti-replay window size
|
||||
* @param window anti-replay window size
|
||||
*/
|
||||
void (*set_replay_window)(child_cfg_t *this, uint32_t window);
|
||||
|
||||
/**
|
||||
* Check whether IPsec transport SA should be set up in proxy mode.
|
||||
* Check if an option flag is set.
|
||||
*
|
||||
* @return TRUE, if proxy mode should be used
|
||||
* FALSE, otherwise
|
||||
* @param option option flag to check
|
||||
* @return TRUE if option flag set, FALSE otherwise
|
||||
*/
|
||||
bool (*use_proxy_mode)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Check whether IPsec policies should be installed in the kernel.
|
||||
*
|
||||
* @return TRUE, if IPsec kernel policies should be installed
|
||||
* FALSE, otherwise
|
||||
*/
|
||||
bool (*install_policy)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Check whether outbound FWD IPsec policies should be installed.
|
||||
*
|
||||
* @return TRUE, if outbound FWD policies should be installed
|
||||
* FALSE, otherwise
|
||||
*/
|
||||
bool (*install_fwd_out_policy)(child_cfg_t *this);
|
||||
bool (*has_option)(child_cfg_t *this, child_cfg_option_t option);
|
||||
|
||||
/**
|
||||
* Check if two child_cfg objects are equal.
|
||||
@ -315,11 +285,36 @@ struct child_cfg_t {
|
||||
void (*destroy) (child_cfg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Option flags that may be set on a child_cfg_t object
|
||||
*/
|
||||
enum child_cfg_option_t {
|
||||
|
||||
/** Use IPsec transport proxy mode */
|
||||
OPT_PROXY_MODE = (1<<0),
|
||||
|
||||
/** Use IPComp, if peer supports it */
|
||||
OPT_IPCOMP = (1<<1),
|
||||
|
||||
/** Allow access to the local host */
|
||||
OPT_HOSTACCESS = (1<<2),
|
||||
|
||||
/** Don't install any IPsec policies */
|
||||
OPT_NO_POLICIES = (1<<3),
|
||||
|
||||
/** Install outbound FWD IPsec policies to bypass drop policies */
|
||||
OPT_FWD_OUT_POLICIES = (1<<4),
|
||||
|
||||
/** Enable hardware offload, if supported by the IPsec backend */
|
||||
OPT_HW_OFFLOAD = (1<<5),
|
||||
};
|
||||
|
||||
/**
|
||||
* Data passed to the constructor of a child_cfg_t object.
|
||||
*/
|
||||
struct child_cfg_create_t {
|
||||
/** Options set for CHILD_SA */
|
||||
child_cfg_option_t options;
|
||||
/** Specific reqid to use for CHILD_SA, 0 for auto assignment */
|
||||
uint32_t reqid;
|
||||
/** Optional inbound mark */
|
||||
@ -328,10 +323,6 @@ struct child_cfg_create_t {
|
||||
mark_t mark_out;
|
||||
/** Mode to propose for CHILD_SA */
|
||||
ipsec_mode_t mode;
|
||||
/** Use IPsec transport proxy mode */
|
||||
bool proxy_mode;
|
||||
/** Use IPComp, if peer supports it */
|
||||
bool ipcomp;
|
||||
/** TFC padding size, 0 to disable, -1 to pad to PMTU */
|
||||
uint32_t tfc;
|
||||
/** Optional manually-set IPsec policy priority */
|
||||
@ -350,12 +341,6 @@ struct child_cfg_create_t {
|
||||
action_t close_action;
|
||||
/** updown script to execute on up/down event (cloned) */
|
||||
char *updown;
|
||||
/** TRUE to allow access to the local host */
|
||||
bool hostaccess;
|
||||
/** Don't install IPsec policies */
|
||||
bool suppress_policies;
|
||||
/** Install outbound FWD IPsec policies to bypass drop policies */
|
||||
bool fwd_out_policies;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -91,6 +91,8 @@ struct kernel_ipsec_add_sa_t {
|
||||
uint16_t cpi;
|
||||
/** TRUE to enable UDP encapsulation for NAT traversal */
|
||||
bool encap;
|
||||
/** TRUE to enable hardware offloading if available */
|
||||
bool hw_offload;
|
||||
/** TRUE to use Extended Sequence Numbers */
|
||||
bool esn;
|
||||
/** TRUE if initiator of the exchange creating the SA */
|
||||
|
||||
@ -1639,6 +1639,31 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
data->replay_window);
|
||||
sa->replay_window = data->replay_window;
|
||||
}
|
||||
if (data->hw_offload)
|
||||
{
|
||||
host_t *local = data->inbound ? id->dst : id->src;
|
||||
char *ifname;
|
||||
|
||||
if (charon->kernel->get_interface(charon->kernel, local, &ifname))
|
||||
{
|
||||
struct xfrm_user_offload *offload;
|
||||
|
||||
offload = netlink_reserve(hdr, sizeof(request),
|
||||
XFRMA_OFFLOAD_DEV, sizeof(*offload));
|
||||
if (!offload)
|
||||
{
|
||||
free(ifname);
|
||||
goto failed;
|
||||
}
|
||||
offload->ifindex = if_nametoindex(ifname);
|
||||
if (local->get_family(local) == AF_INET6)
|
||||
{
|
||||
offload->flags |= XFRM_OFFLOAD_IPV6;
|
||||
}
|
||||
offload->flags |= data->inbound ? XFRM_OFFLOAD_INBOUND : 0;
|
||||
free(ifname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
|
||||
@ -1919,13 +1944,13 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
kernel_ipsec_update_sa_t *data)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
struct nlmsghdr *hdr, *out = NULL;
|
||||
struct nlmsghdr *hdr, *out_hdr = NULL, *out = NULL;
|
||||
struct xfrm_usersa_id *sa_id;
|
||||
struct xfrm_usersa_info *out_sa = NULL, *sa;
|
||||
struct xfrm_usersa_info *sa;
|
||||
size_t len;
|
||||
struct rtattr *rta;
|
||||
size_t rtasize;
|
||||
struct xfrm_encap_tmpl* tmpl = NULL;
|
||||
struct xfrm_encap_tmpl* encap = NULL;
|
||||
struct xfrm_replay_state *replay = NULL;
|
||||
struct xfrm_replay_state_esn *replay_esn = NULL;
|
||||
struct xfrm_lifetime_cur *lifetime = NULL;
|
||||
@ -1983,7 +2008,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
{
|
||||
case XFRM_MSG_NEWSA:
|
||||
{
|
||||
out_sa = NLMSG_DATA(hdr);
|
||||
out_hdr = hdr;
|
||||
break;
|
||||
}
|
||||
case NLMSG_ERROR:
|
||||
@ -2002,7 +2027,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (out_sa == NULL)
|
||||
if (!out_hdr)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x%s",
|
||||
ntohl(id->spi), markstr);
|
||||
@ -2029,7 +2054,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
hdr->nlmsg_type = XFRM_MSG_NEWSA;
|
||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
|
||||
sa = NLMSG_DATA(hdr);
|
||||
memcpy(sa, NLMSG_DATA(out), sizeof(struct xfrm_usersa_info));
|
||||
memcpy(sa, NLMSG_DATA(out_hdr), sizeof(struct xfrm_usersa_info));
|
||||
sa->family = data->new_dst->get_family(data->new_dst);
|
||||
|
||||
if (!id->src->ip_equals(id->src, data->new_src))
|
||||
@ -2041,8 +2066,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
host2xfrm(data->new_dst, &sa->id.daddr);
|
||||
}
|
||||
|
||||
rta = XFRM_RTA(out, struct xfrm_usersa_info);
|
||||
rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info);
|
||||
rta = XFRM_RTA(out_hdr, struct xfrm_usersa_info);
|
||||
rtasize = XFRM_PAYLOAD(out_hdr, struct xfrm_usersa_info);
|
||||
while (RTA_OK(rta, rtasize))
|
||||
{
|
||||
/* copy all attributes, but not XFRMA_ENCAP if we are disabling it */
|
||||
@ -2050,9 +2075,34 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
{
|
||||
if (rta->rta_type == XFRMA_ENCAP)
|
||||
{ /* update encap tmpl */
|
||||
tmpl = RTA_DATA(rta);
|
||||
tmpl->encap_sport = ntohs(data->new_src->get_port(data->new_src));
|
||||
tmpl->encap_dport = ntohs(data->new_dst->get_port(data->new_dst));
|
||||
encap = RTA_DATA(rta);
|
||||
encap->encap_sport = ntohs(data->new_src->get_port(data->new_src));
|
||||
encap->encap_dport = ntohs(data->new_dst->get_port(data->new_dst));
|
||||
}
|
||||
if (rta->rta_type == XFRMA_OFFLOAD_DEV)
|
||||
{ /* update offload device */
|
||||
struct xfrm_user_offload *offload;
|
||||
host_t *local;
|
||||
char *ifname;
|
||||
|
||||
offload = RTA_DATA(rta);
|
||||
local = offload->flags & XFRM_OFFLOAD_INBOUND ? data->new_dst
|
||||
: data->new_src;
|
||||
|
||||
if (charon->kernel->get_interface(charon->kernel, local,
|
||||
&ifname))
|
||||
{
|
||||
offload->ifindex = if_nametoindex(ifname);
|
||||
if (local->get_family(local) == AF_INET6)
|
||||
{
|
||||
offload->flags |= XFRM_OFFLOAD_IPV6;
|
||||
}
|
||||
else
|
||||
{
|
||||
offload->flags &= ~XFRM_OFFLOAD_IPV6;
|
||||
}
|
||||
free(ifname);
|
||||
}
|
||||
}
|
||||
netlink_add_attribute(hdr, rta->rta_type,
|
||||
chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)),
|
||||
@ -2061,17 +2111,18 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
rta = RTA_NEXT(rta, rtasize);
|
||||
}
|
||||
|
||||
if (tmpl == NULL && data->new_encap)
|
||||
if (encap == NULL && data->new_encap)
|
||||
{ /* add tmpl if we are enabling it */
|
||||
tmpl = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP, sizeof(*tmpl));
|
||||
if (!tmpl)
|
||||
encap = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP,
|
||||
sizeof(*encap));
|
||||
if (!encap)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
|
||||
tmpl->encap_sport = ntohs(data->new_src->get_port(data->new_src));
|
||||
tmpl->encap_dport = ntohs(data->new_dst->get_port(data->new_dst));
|
||||
memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
|
||||
encap->encap_type = UDP_ENCAP_ESPINUDP;
|
||||
encap->encap_sport = ntohs(data->new_src->get_port(data->new_src));
|
||||
encap->encap_dport = ntohs(data->new_dst->get_port(data->new_dst));
|
||||
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
|
||||
}
|
||||
|
||||
if (replay_esn)
|
||||
|
||||
@ -173,7 +173,8 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
|
||||
child_cfg_create_t child = {
|
||||
.mode = mode,
|
||||
.reqid = reqid,
|
||||
.ipcomp = ipcomp,
|
||||
.options = (ipcomp ? OPT_IPCOMP : 0) |
|
||||
(hostaccess ? OPT_HOSTACCESS : 0),
|
||||
.lifetime = {
|
||||
.time = {
|
||||
.life = lifetime, .rekey = rekeytime, .jitter = jitter
|
||||
@ -183,7 +184,6 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
|
||||
.dpd_action = dpd,
|
||||
.close_action = close,
|
||||
.updown = updown,
|
||||
.hostaccess = hostaccess,
|
||||
};
|
||||
child_cfg = child_cfg_create(name, &child);
|
||||
add_esp_proposals(this, child_cfg, id);
|
||||
|
||||
@ -1071,15 +1071,15 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
|
||||
},
|
||||
.reqid = msg->add_conn.reqid,
|
||||
.mode = msg->add_conn.mode,
|
||||
.proxy_mode = msg->add_conn.proxy_mode,
|
||||
.ipcomp = msg->add_conn.ipcomp,
|
||||
.options = (msg->add_conn.proxy_mode ? OPT_PROXY_MODE : 0) |
|
||||
(msg->add_conn.ipcomp ? OPT_IPCOMP : 0) |
|
||||
(msg->add_conn.me.hostaccess ? OPT_HOSTACCESS : 0) |
|
||||
(msg->add_conn.install_policy ? 0 : OPT_NO_POLICIES),
|
||||
.tfc = msg->add_conn.tfc,
|
||||
.inactivity = msg->add_conn.inactivity,
|
||||
.dpd_action = map_action(msg->add_conn.dpd.action),
|
||||
.close_action = map_action(msg->add_conn.close_action),
|
||||
.updown = msg->add_conn.me.updown,
|
||||
.hostaccess = msg->add_conn.me.hostaccess,
|
||||
.suppress_policies = !msg->add_conn.install_policy,
|
||||
};
|
||||
|
||||
child_cfg = child_cfg_create(msg->add_conn.name, &child);
|
||||
|
||||
@ -218,7 +218,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
|
||||
child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
|
||||
child_sa_state_names, child_sa->get_state(child_sa),
|
||||
ipsec_mode_names, child_sa->get_mode(child_sa),
|
||||
config->use_proxy_mode(config) ? "_PROXY" : "",
|
||||
config->has_option(config, OPT_PROXY_MODE) ? "_PROXY" : "",
|
||||
child_sa->get_reqid(child_sa));
|
||||
|
||||
if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
|
||||
|
||||
@ -366,7 +366,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa,
|
||||
push_env(envp, countof(envp), "PLUTO_IPCOMP=1");
|
||||
}
|
||||
push_dns_env(this, ike_sa, envp, countof(envp));
|
||||
if (config->get_hostaccess(config))
|
||||
if (config->has_option(config, OPT_HOSTACCESS))
|
||||
{
|
||||
push_env(envp, countof(envp), "PLUTO_HOST_ACCESS=1");
|
||||
}
|
||||
|
||||
@ -478,7 +478,6 @@ typedef struct {
|
||||
linked_list_t *remote_ts;
|
||||
uint32_t replay_window;
|
||||
bool policies;
|
||||
bool policies_fwd_out;
|
||||
child_cfg_create_t cfg;
|
||||
} child_data_t;
|
||||
|
||||
@ -500,12 +499,12 @@ static void log_child_data(child_data_t *data, char *name)
|
||||
DBG2(DBG_CFG, " life_packets = %llu", cfg->lifetime.packets.life);
|
||||
DBG2(DBG_CFG, " rand_packets = %llu", cfg->lifetime.packets.jitter);
|
||||
DBG2(DBG_CFG, " updown = %s", cfg->updown);
|
||||
DBG2(DBG_CFG, " hostaccess = %u", cfg->hostaccess);
|
||||
DBG2(DBG_CFG, " ipcomp = %u", cfg->ipcomp);
|
||||
DBG2(DBG_CFG, " hostaccess = %u", cfg->options & OPT_HOSTACCESS);
|
||||
DBG2(DBG_CFG, " ipcomp = %u", cfg->options & OPT_IPCOMP);
|
||||
DBG2(DBG_CFG, " mode = %N%s", ipsec_mode_names, cfg->mode,
|
||||
cfg->proxy_mode ? "_PROXY" : "");
|
||||
cfg->options & OPT_PROXY_MODE ? "_PROXY" : "");
|
||||
DBG2(DBG_CFG, " policies = %u", data->policies);
|
||||
DBG2(DBG_CFG, " policies_fwd_out = %u", data->policies_fwd_out);
|
||||
DBG2(DBG_CFG, " policies_fwd_out = %u", cfg->options & OPT_FWD_OUT_POLICIES);
|
||||
if (data->replay_window != REPLAY_UNDEFINED)
|
||||
{
|
||||
DBG2(DBG_CFG, " replay_window = %u", data->replay_window);
|
||||
@ -525,6 +524,7 @@ static void log_child_data(child_data_t *data, char *name)
|
||||
DBG2(DBG_CFG, " proposals = %#P", data->proposals);
|
||||
DBG2(DBG_CFG, " local_ts = %#R", data->local_ts);
|
||||
DBG2(DBG_CFG, " remote_ts = %#R", data->remote_ts);
|
||||
DBG2(DBG_CFG, " hw_offload = %u", cfg->options & OPT_HW_OFFLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -827,12 +827,70 @@ CALLBACK(parse_mode, bool,
|
||||
if (parse_map(map, countof(map), &d, v))
|
||||
{
|
||||
cfg->mode = d;
|
||||
cfg->proxy_mode = (d == MODE_TRANSPORT) && (v.len > 9);
|
||||
if ((d == MODE_TRANSPORT) && (v.len > 9))
|
||||
{
|
||||
cfg->options |= OPT_PROXY_MODE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a child_cfg_option_t
|
||||
*/
|
||||
static bool parse_option(child_cfg_option_t *out, child_cfg_option_t opt,
|
||||
chunk_t v)
|
||||
{
|
||||
bool val;
|
||||
|
||||
if (parse_bool(&val, v))
|
||||
{
|
||||
if (val)
|
||||
{
|
||||
*out |= opt;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OPT_HOSTACCESS option
|
||||
*/
|
||||
CALLBACK(parse_opt_haccess, bool,
|
||||
child_cfg_option_t *out, chunk_t v)
|
||||
{
|
||||
return parse_option(out, OPT_HOSTACCESS, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OPT_FWD_OUT_POLICIES option
|
||||
*/
|
||||
CALLBACK(parse_opt_fwd_out, bool,
|
||||
child_cfg_option_t *out, chunk_t v)
|
||||
{
|
||||
return parse_option(out, OPT_FWD_OUT_POLICIES, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OPT_FWD_OUT_POLICIES option
|
||||
*/
|
||||
CALLBACK(parse_opt_ipcomp, bool,
|
||||
child_cfg_option_t *out, chunk_t v)
|
||||
{
|
||||
return parse_option(out, OPT_IPCOMP, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OPT_HW_OFFLOAD option
|
||||
*/
|
||||
CALLBACK(parse_opt_hw_offl, bool,
|
||||
child_cfg_option_t *out, chunk_t v)
|
||||
{
|
||||
return parse_option(out, OPT_HW_OFFLOAD, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an action_t
|
||||
*/
|
||||
@ -1466,10 +1524,10 @@ CALLBACK(child_kv, bool,
|
||||
{
|
||||
parse_rule_t rules[] = {
|
||||
{ "updown", parse_string, &child->cfg.updown },
|
||||
{ "hostaccess", parse_bool, &child->cfg.hostaccess },
|
||||
{ "hostaccess", parse_opt_haccess, &child->cfg.options },
|
||||
{ "mode", parse_mode, &child->cfg },
|
||||
{ "policies", parse_bool, &child->policies },
|
||||
{ "policies_fwd_out", parse_bool, &child->policies_fwd_out },
|
||||
{ "policies_fwd_out", parse_opt_fwd_out, &child->cfg.options },
|
||||
{ "replay_window", parse_uint32, &child->replay_window },
|
||||
{ "rekey_time", parse_time, &child->cfg.lifetime.time.rekey },
|
||||
{ "life_time", parse_time, &child->cfg.lifetime.time.life },
|
||||
@ -1483,7 +1541,7 @@ CALLBACK(child_kv, bool,
|
||||
{ "dpd_action", parse_action, &child->cfg.dpd_action },
|
||||
{ "start_action", parse_action, &child->cfg.start_action },
|
||||
{ "close_action", parse_action, &child->cfg.close_action },
|
||||
{ "ipcomp", parse_bool, &child->cfg.ipcomp },
|
||||
{ "ipcomp", parse_opt_ipcomp, &child->cfg.options },
|
||||
{ "inactivity", parse_time, &child->cfg.inactivity },
|
||||
{ "reqid", parse_uint32, &child->cfg.reqid },
|
||||
{ "mark_in", parse_mark, &child->cfg.mark_in },
|
||||
@ -1491,6 +1549,7 @@ CALLBACK(child_kv, bool,
|
||||
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
||||
{ "priority", parse_uint32, &child->cfg.priority },
|
||||
{ "interface", parse_string, &child->cfg.interface },
|
||||
{ "hw_offload", parse_opt_hw_offl, &child->cfg.options },
|
||||
};
|
||||
|
||||
return parse_rules(rules, countof(rules), name, value,
|
||||
@ -1756,8 +1815,7 @@ CALLBACK(children_sn, bool,
|
||||
child.proposals->insert_last(child.proposals, proposal);
|
||||
}
|
||||
}
|
||||
child.cfg.suppress_policies = !child.policies;
|
||||
child.cfg.fwd_out_policies = child.policies_fwd_out;
|
||||
child.cfg.options |= child.policies ? 0 : OPT_NO_POLICIES;
|
||||
|
||||
check_lifetimes(&child.cfg.lifetime);
|
||||
|
||||
|
||||
@ -107,7 +107,7 @@ static void list_mode(vici_builder_t *b, child_sa_t *child, child_cfg_t *cfg)
|
||||
cfg = child->get_config(child);
|
||||
}
|
||||
mode = child ? child->get_mode(child) : cfg->get_mode(cfg);
|
||||
if (mode == MODE_TRANSPORT && cfg->use_proxy_mode(cfg))
|
||||
if (mode == MODE_TRANSPORT && cfg->has_option(cfg, OPT_PROXY_MODE))
|
||||
{ /* only report this if the negotiated mode is actually TRANSPORT */
|
||||
sub_mode = "_PROXY";
|
||||
}
|
||||
|
||||
@ -818,6 +818,7 @@ METHOD(child_sa_t, install, status_t,
|
||||
.ipcomp = this->ipcomp,
|
||||
.cpi = cpi,
|
||||
.encap = this->encap,
|
||||
.hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD),
|
||||
.esn = esn,
|
||||
.initiator = initiator,
|
||||
.inbound = inbound,
|
||||
@ -1052,7 +1053,7 @@ METHOD(child_sa_t, add_policies, status_t,
|
||||
enumerator->destroy(enumerator);
|
||||
array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
|
||||
|
||||
if (this->config->install_policy(this->config))
|
||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
||||
{
|
||||
policy_priority_t priority;
|
||||
ipsec_sa_cfg_t my_sa, other_sa;
|
||||
@ -1134,8 +1135,9 @@ METHOD(child_sa_t, update, status_t,
|
||||
|
||||
old = this->state;
|
||||
set_state(this, CHILD_UPDATING);
|
||||
transport_proxy_mode = this->config->use_proxy_mode(this->config) &&
|
||||
this->mode == MODE_TRANSPORT;
|
||||
transport_proxy_mode = this->mode == MODE_TRANSPORT &&
|
||||
this->config->has_option(this->config,
|
||||
OPT_PROXY_MODE);
|
||||
|
||||
if (!transport_proxy_mode)
|
||||
{
|
||||
@ -1189,7 +1191,8 @@ METHOD(child_sa_t, update, status_t,
|
||||
}
|
||||
}
|
||||
|
||||
if (this->config->install_policy(this->config) && require_policy_update())
|
||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
|
||||
require_policy_update())
|
||||
{
|
||||
if (!me->ip_equals(me, this->my_addr) ||
|
||||
!other->ip_equals(other, this->other_addr))
|
||||
@ -1287,7 +1290,7 @@ METHOD(child_sa_t, destroy, void,
|
||||
|
||||
set_state(this, CHILD_DESTROYING);
|
||||
|
||||
if (this->config->install_policy(this->config))
|
||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
||||
{
|
||||
ipsec_sa_cfg_t my_sa, other_sa;
|
||||
uint32_t manual_prio;
|
||||
@ -1456,7 +1459,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
.mark_in = config->get_mark(config, TRUE),
|
||||
.mark_out = config->get_mark(config, FALSE),
|
||||
.install_time = time_monotonic(NULL),
|
||||
.policies_fwd_out = config->install_fwd_out_policy(config),
|
||||
.policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
|
||||
);
|
||||
|
||||
this->config = config;
|
||||
@ -1509,7 +1512,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
|
||||
/* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
|
||||
if (config->get_mode(config) == MODE_TRANSPORT &&
|
||||
config->use_proxy_mode(config))
|
||||
config->has_option(config, OPT_PROXY_MODE))
|
||||
{
|
||||
this->mode = MODE_TRANSPORT;
|
||||
|
||||
|
||||
@ -853,7 +853,7 @@ METHOD(task_t, build_i, status_t,
|
||||
add_nat_oa_payloads(this, message);
|
||||
}
|
||||
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
if (this->config->has_option(this->config, OPT_IPCOMP))
|
||||
{
|
||||
this->cpi_i = this->child_sa->alloc_cpi(this->child_sa);
|
||||
if (!this->cpi_i)
|
||||
@ -1108,7 +1108,7 @@ METHOD(task_t, process_r, status_t,
|
||||
return send_notify(this, INVALID_ID_INFORMATION);
|
||||
}
|
||||
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
if (this->config->has_option(this->config, OPT_IPCOMP))
|
||||
{
|
||||
list = sa_payload->get_ipcomp_proposals(sa_payload,
|
||||
&this->cpi_i);
|
||||
|
||||
@ -602,7 +602,7 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
switch (this->mode)
|
||||
{
|
||||
case MODE_TRANSPORT:
|
||||
if (!this->config->use_proxy_mode(this->config) &&
|
||||
if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
|
||||
(!ts_list_is_host(this->tsi, other) ||
|
||||
!ts_list_is_host(this->tsr, me))
|
||||
)
|
||||
@ -1073,7 +1073,7 @@ METHOD(task_t, build_i, status_t,
|
||||
this->dh_group);
|
||||
}
|
||||
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
if (this->config->has_option(this->config, OPT_IPCOMP))
|
||||
{
|
||||
/* IPCOMP_DEFLATE is the only transform we support at the moment */
|
||||
add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
|
||||
@ -1327,7 +1327,7 @@ METHOD(task_t, build_r, status_t,
|
||||
|
||||
if (this->ipcomp_received != IPCOMP_NONE)
|
||||
{
|
||||
if (this->config->use_ipcomp(this->config))
|
||||
if (this->config->has_option(this->config, OPT_IPCOMP))
|
||||
{
|
||||
add_ipcomp_notify(this, message, this->ipcomp_received);
|
||||
}
|
||||
|
||||
@ -888,6 +888,10 @@ connections.<conn>.children.<child>.replay_window = 32
|
||||
default of 32 are supported using the Netlink backend only, a value of 0
|
||||
disables IPsec replay protection.
|
||||
|
||||
connections.<conn>.children.<child>.hw_offload = no
|
||||
Enable hardware offload for this CHILD_SA, if supported by the IPsec
|
||||
implementation.
|
||||
|
||||
connections.<conn>.children.<child>.start_action = none
|
||||
Action to perform after loading the configuration (_none_, _trap_, _start_).
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user