Merge branch 'hw-offload-auto'
This lets IPsec SA installation explicitly fail if HW offload is enabled but either the kernel or the device don't support it. And it adds a new configuration mode 'auto', which enables HW offload, if supported, but does not fail the installation otherwise.
This commit is contained in:
@@ -142,6 +142,11 @@ struct private_child_cfg_t {
|
|||||||
* anti-replay window size
|
* anti-replay window size
|
||||||
*/
|
*/
|
||||||
uint32_t replay_window;
|
uint32_t replay_window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HW offload mode
|
||||||
|
*/
|
||||||
|
hw_offload_t hw_offload;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(child_cfg_t, get_name, char*,
|
METHOD(child_cfg_t, get_name, char*,
|
||||||
@@ -467,6 +472,12 @@ METHOD(child_cfg_t, get_start_action, action_t,
|
|||||||
return this->start_action;
|
return this->start_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(child_cfg_t, get_hw_offload, hw_offload_t,
|
||||||
|
private_child_cfg_t *this)
|
||||||
|
{
|
||||||
|
return this->hw_offload;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(child_cfg_t, get_dpd_action, action_t,
|
METHOD(child_cfg_t, get_dpd_action, action_t,
|
||||||
private_child_cfg_t *this)
|
private_child_cfg_t *this)
|
||||||
{
|
{
|
||||||
@@ -652,6 +663,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
|||||||
.equals = _equals,
|
.equals = _equals,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
|
.get_hw_offload = _get_hw_offload,
|
||||||
},
|
},
|
||||||
.name = strdup(name),
|
.name = strdup(name),
|
||||||
.options = data->options,
|
.options = data->options,
|
||||||
@@ -674,6 +686,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
|||||||
.other_ts = linked_list_create(),
|
.other_ts = linked_list_create(),
|
||||||
.replay_window = lib->settings->get_int(lib->settings,
|
.replay_window = lib->settings->get_int(lib->settings,
|
||||||
"%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
|
"%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
|
||||||
|
.hw_offload = data->hw_offload,
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -182,6 +182,13 @@ struct child_cfg_t {
|
|||||||
*/
|
*/
|
||||||
action_t (*get_dpd_action) (child_cfg_t *this);
|
action_t (*get_dpd_action) (child_cfg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the HW offload mode to use for the CHILD_SA.
|
||||||
|
*
|
||||||
|
* @return hw offload mode
|
||||||
|
*/
|
||||||
|
hw_offload_t (*get_hw_offload) (child_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to take if CHILD_SA gets closed.
|
* Action to take if CHILD_SA gets closed.
|
||||||
*
|
*
|
||||||
@@ -305,14 +312,11 @@ enum child_cfg_option_t {
|
|||||||
/** Install outbound FWD IPsec policies to bypass drop policies */
|
/** Install outbound FWD IPsec policies to bypass drop policies */
|
||||||
OPT_FWD_OUT_POLICIES = (1<<4),
|
OPT_FWD_OUT_POLICIES = (1<<4),
|
||||||
|
|
||||||
/** Enable hardware offload, if supported by the IPsec backend */
|
|
||||||
OPT_HW_OFFLOAD = (1<<5),
|
|
||||||
|
|
||||||
/** Force 96-bit truncation for SHA-256 */
|
/** Force 96-bit truncation for SHA-256 */
|
||||||
OPT_SHA256_96 = (1<<6),
|
OPT_SHA256_96 = (1<<5),
|
||||||
|
|
||||||
/** Set mark on inbound SAs */
|
/** Set mark on inbound SAs */
|
||||||
OPT_MARK_IN_SA = (1<<7),
|
OPT_MARK_IN_SA = (1<<6),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -347,6 +351,8 @@ struct child_cfg_create_t {
|
|||||||
action_t close_action;
|
action_t close_action;
|
||||||
/** updown script to execute on up/down event (cloned) */
|
/** updown script to execute on up/down event (cloned) */
|
||||||
char *updown;
|
char *updown;
|
||||||
|
/** HW offload mode */
|
||||||
|
hw_offload_t hw_offload;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ struct kernel_ipsec_add_sa_t {
|
|||||||
uint16_t cpi;
|
uint16_t cpi;
|
||||||
/** TRUE to enable UDP encapsulation for NAT traversal */
|
/** TRUE to enable UDP encapsulation for NAT traversal */
|
||||||
bool encap;
|
bool encap;
|
||||||
/** TRUE to enable hardware offloading if available */
|
/** no (disabled), yes (enabled), auto (enabled if supported) */
|
||||||
bool hw_offload;
|
hw_offload_t hw_offload;
|
||||||
/** TRUE to use Extended Sequence Numbers */
|
/** TRUE to use Extended Sequence Numbers */
|
||||||
bool esn;
|
bool esn;
|
||||||
/** TRUE if initiator of the exchange creating the SA */
|
/** TRUE if initiator of the exchange creating the SA */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2017 Tobias Brunner
|
* Copyright (C) 2006-2018 Tobias Brunner
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2008-2016 Andreas Steffen
|
* Copyright (C) 2008-2016 Andreas Steffen
|
||||||
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
||||||
@@ -17,16 +17,40 @@
|
|||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Mellanox Technologies.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <linux/ipsec.h>
|
#include <linux/ipsec.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/xfrm.h>
|
#include <linux/xfrm.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
#include <linux/sockios.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -236,6 +260,27 @@ static kernel_algorithm_t compression_algs[] = {
|
|||||||
{IPCOMP_LZJH, "lzjh" },
|
{IPCOMP_LZJH, "lzjh" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPsec HW offload state in kernel
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
NL_OFFLOAD_UNKNOWN,
|
||||||
|
NL_OFFLOAD_UNSUPPORTED,
|
||||||
|
NL_OFFLOAD_SUPPORTED
|
||||||
|
} nl_offload_state_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global metadata used for IPsec HW offload
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
/** bit in feature set */
|
||||||
|
u_int bit;
|
||||||
|
/** total number of device feature blocks */
|
||||||
|
u_int total_blocks;
|
||||||
|
/** determined HW offload state */
|
||||||
|
nl_offload_state_t state;
|
||||||
|
} netlink_hw_offload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a kernel algorithm name and its key size
|
* Look up a kernel algorithm name and its key size
|
||||||
*/
|
*/
|
||||||
@@ -1290,6 +1335,190 @@ static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if kernel supports HW offload
|
||||||
|
*/
|
||||||
|
static void netlink_find_offload_feature(const char *ifname, int query_socket)
|
||||||
|
{
|
||||||
|
struct ethtool_sset_info *sset_info;
|
||||||
|
struct ethtool_gstrings *cmd = NULL;
|
||||||
|
struct ifreq ifr;
|
||||||
|
uint32_t sset_len, i;
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
netlink_hw_offload.state = NL_OFFLOAD_UNSUPPORTED;
|
||||||
|
|
||||||
|
/* determine number of device features */
|
||||||
|
INIT_EXTRA(sset_info, sizeof(uint32_t),
|
||||||
|
.cmd = ETHTOOL_GSSET_INFO,
|
||||||
|
.sset_mask = 1ULL << ETH_SS_FEATURES,
|
||||||
|
);
|
||||||
|
strcpy(ifr.ifr_name, ifname);
|
||||||
|
ifr.ifr_data = (void*)sset_info;
|
||||||
|
|
||||||
|
err = ioctl(query_socket, SIOCETHTOOL, &ifr);
|
||||||
|
if (err || sset_info->sset_mask != 1ULL << ETH_SS_FEATURES)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sset_len = sset_info->data[0];
|
||||||
|
|
||||||
|
/* retrieve names of device features */
|
||||||
|
INIT_EXTRA(cmd, ETH_GSTRING_LEN * sset_len,
|
||||||
|
.cmd = ETHTOOL_GSTRINGS,
|
||||||
|
.string_set = ETH_SS_FEATURES,
|
||||||
|
);
|
||||||
|
strcpy(ifr.ifr_name, ifname);
|
||||||
|
ifr.ifr_data = (void*)cmd;
|
||||||
|
|
||||||
|
err = ioctl(query_socket, SIOCETHTOOL, &ifr);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for the ESP_HW feature bit */
|
||||||
|
str = (char*)cmd->data;
|
||||||
|
for (i = 0; i < cmd->len; i++)
|
||||||
|
{
|
||||||
|
if (strneq(str, "esp-hw-offload", ETH_GSTRING_LEN))
|
||||||
|
{
|
||||||
|
netlink_hw_offload.bit = i;
|
||||||
|
netlink_hw_offload.total_blocks = (sset_len + 31) / 32;
|
||||||
|
netlink_hw_offload.state = NL_OFFLOAD_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str += ETH_GSTRING_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(sset_info);
|
||||||
|
free(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if interface supported HW offload
|
||||||
|
*/
|
||||||
|
static bool netlink_detect_offload(const char *ifname)
|
||||||
|
{
|
||||||
|
struct ethtool_gfeatures *cmd;
|
||||||
|
uint32_t feature_bit;
|
||||||
|
struct ifreq ifr;
|
||||||
|
int query_socket;
|
||||||
|
int block;
|
||||||
|
bool ret = FALSE;
|
||||||
|
|
||||||
|
query_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
|
||||||
|
if (query_socket < 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kernel requires a real interface in order to query the kernel-wide
|
||||||
|
* capability, so we do it here on first invocation.
|
||||||
|
*/
|
||||||
|
if (netlink_hw_offload.state == NL_OFFLOAD_UNKNOWN)
|
||||||
|
{
|
||||||
|
netlink_find_offload_feature(ifname, query_socket);
|
||||||
|
}
|
||||||
|
if (netlink_hw_offload.state == NL_OFFLOAD_UNSUPPORTED)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "HW offload is not supported by kernel");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* feature is supported by kernel, query device features */
|
||||||
|
INIT_EXTRA(cmd, sizeof(cmd->features[0]) * netlink_hw_offload.total_blocks,
|
||||||
|
.cmd = ETHTOOL_GFEATURES,
|
||||||
|
.size = netlink_hw_offload.total_blocks,
|
||||||
|
);
|
||||||
|
strcpy(ifr.ifr_name, ifname);
|
||||||
|
ifr.ifr_data = (void*)cmd;
|
||||||
|
|
||||||
|
if (ioctl(query_socket, SIOCETHTOOL, &ifr))
|
||||||
|
{
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = netlink_hw_offload.bit / 32;
|
||||||
|
feature_bit = 1U << (netlink_hw_offload.bit % 32);
|
||||||
|
if (cmd->features[block].active & feature_bit)
|
||||||
|
{
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
free(cmd);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "HW offload is not supported by device");
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
close(query_socket);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are 3 HW offload configuration values:
|
||||||
|
* 1. HW_OFFLOAD_NO : Do not configure HW offload.
|
||||||
|
* 2. HW_OFFLOAD_YES : Configure HW offload.
|
||||||
|
* Fail SA addition if offload is not supported.
|
||||||
|
* 3. HW_OFFLOAD_AUTO : Configure HW offload if supported by the kernel
|
||||||
|
* and device.
|
||||||
|
* Do not fail SA addition otherwise.
|
||||||
|
*/
|
||||||
|
static bool config_hw_offload(kernel_ipsec_sa_id_t *id,
|
||||||
|
kernel_ipsec_add_sa_t *data, struct nlmsghdr *hdr,
|
||||||
|
int buflen)
|
||||||
|
{
|
||||||
|
host_t *local = data->inbound ? id->dst : id->src;
|
||||||
|
struct xfrm_user_offload *offload;
|
||||||
|
bool hw_offload_yes, ret = FALSE;
|
||||||
|
char *ifname;
|
||||||
|
|
||||||
|
/* do Ipsec configuration without offload */
|
||||||
|
if (data->hw_offload == HW_OFFLOAD_NO)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hw_offload_yes = (data->hw_offload == HW_OFFLOAD_YES);
|
||||||
|
|
||||||
|
if (!charon->kernel->get_interface(charon->kernel, local, &ifname))
|
||||||
|
{
|
||||||
|
return !hw_offload_yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if interface supports hw_offload */
|
||||||
|
if (!netlink_detect_offload(ifname))
|
||||||
|
{
|
||||||
|
ret = !hw_offload_yes;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* activate HW offload */
|
||||||
|
offload = netlink_reserve(hdr, buflen,
|
||||||
|
XFRMA_OFFLOAD_DEV, sizeof(*offload));
|
||||||
|
if (!offload)
|
||||||
|
{
|
||||||
|
ret = !hw_offload_yes;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(ifname);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, add_sa, status_t,
|
METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||||
private_kernel_netlink_ipsec_t *this, kernel_ipsec_sa_id_t *id,
|
private_kernel_netlink_ipsec_t *this, kernel_ipsec_sa_id_t *id,
|
||||||
kernel_ipsec_add_sa_t *data)
|
kernel_ipsec_add_sa_t *data)
|
||||||
@@ -1650,30 +1879,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||||||
data->replay_window);
|
data->replay_window);
|
||||||
sa->replay_window = data->replay_window;
|
sa->replay_window = data->replay_window;
|
||||||
}
|
}
|
||||||
if (data->hw_offload)
|
|
||||||
|
DBG2(DBG_KNL, " HW offload: %N", hw_offload_names, data->hw_offload);
|
||||||
|
if (!config_hw_offload(id, data, hdr, sizeof(request)))
|
||||||
{
|
{
|
||||||
host_t *local = data->inbound ? id->dst : id->src;
|
DBG1(DBG_KNL, "failed to configure HW offload");
|
||||||
char *ifname;
|
goto failed;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ static void log_child_data(child_data_t *data, char *name)
|
|||||||
DBG2(DBG_CFG, " proposals = %#P", data->proposals);
|
DBG2(DBG_CFG, " proposals = %#P", data->proposals);
|
||||||
DBG2(DBG_CFG, " local_ts = %#R", data->local_ts);
|
DBG2(DBG_CFG, " local_ts = %#R", data->local_ts);
|
||||||
DBG2(DBG_CFG, " remote_ts = %#R", data->remote_ts);
|
DBG2(DBG_CFG, " remote_ts = %#R", data->remote_ts);
|
||||||
DBG2(DBG_CFG, " hw_offload = %u", has_opt(OPT_HW_OFFLOAD));
|
DBG2(DBG_CFG, " hw_offload = %N", hw_offload_names, cfg->hw_offload);
|
||||||
DBG2(DBG_CFG, " sha256_96 = %u", has_opt(OPT_SHA256_96));
|
DBG2(DBG_CFG, " sha256_96 = %u", has_opt(OPT_SHA256_96));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,14 +892,6 @@ CALLBACK(parse_opt_ipcomp, bool,
|
|||||||
return parse_option(out, OPT_IPCOMP, 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 OPT_SHA256_96 option
|
* Parse OPT_SHA256_96 option
|
||||||
@@ -943,6 +935,27 @@ CALLBACK(parse_action, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an hw_offload_t
|
||||||
|
*/
|
||||||
|
CALLBACK(parse_hw_offload, bool,
|
||||||
|
action_t *out, chunk_t v)
|
||||||
|
{
|
||||||
|
enum_map_t map[] = {
|
||||||
|
{ "no", HW_OFFLOAD_NO },
|
||||||
|
{ "yes", HW_OFFLOAD_YES },
|
||||||
|
{ "auto", HW_OFFLOAD_AUTO },
|
||||||
|
};
|
||||||
|
int d;
|
||||||
|
|
||||||
|
if (parse_map(map, countof(map), &d, v))
|
||||||
|
{
|
||||||
|
*out = d;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a uint32_t with the given base
|
* Parse a uint32_t with the given base
|
||||||
*/
|
*/
|
||||||
@@ -1578,7 +1591,7 @@ CALLBACK(child_kv, bool,
|
|||||||
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
||||||
{ "priority", parse_uint32, &child->cfg.priority },
|
{ "priority", parse_uint32, &child->cfg.priority },
|
||||||
{ "interface", parse_string, &child->cfg.interface },
|
{ "interface", parse_string, &child->cfg.interface },
|
||||||
{ "hw_offload", parse_opt_hw_offl, &child->cfg.options },
|
{ "hw_offload", parse_hw_offload, &child->cfg.hw_offload },
|
||||||
{ "sha256_96", parse_opt_sha256_96,&child->cfg.options },
|
{ "sha256_96", parse_opt_sha256_96,&child->cfg.options },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
|||||||
.ipcomp = this->ipcomp,
|
.ipcomp = this->ipcomp,
|
||||||
.cpi = cpi,
|
.cpi = cpi,
|
||||||
.encap = this->encap,
|
.encap = this->encap,
|
||||||
.hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD),
|
.hw_offload = this->config->get_hw_offload(this->config),
|
||||||
.esn = esn,
|
.esn = esn,
|
||||||
.initiator = initiator,
|
.initiator = initiator,
|
||||||
.inbound = inbound,
|
.inbound = inbound,
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH,
|
|||||||
"IPCOMP_LZJH"
|
"IPCOMP_LZJH"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ENUM(hw_offload_names, HW_OFFLOAD_NO, HW_OFFLOAD_AUTO,
|
||||||
|
"no",
|
||||||
|
"yes",
|
||||||
|
"auto",
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header
|
* See header
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ typedef enum policy_dir_t policy_dir_t;
|
|||||||
typedef enum policy_type_t policy_type_t;
|
typedef enum policy_type_t policy_type_t;
|
||||||
typedef enum policy_priority_t policy_priority_t;
|
typedef enum policy_priority_t policy_priority_t;
|
||||||
typedef enum ipcomp_transform_t ipcomp_transform_t;
|
typedef enum ipcomp_transform_t ipcomp_transform_t;
|
||||||
|
typedef enum hw_offload_t hw_offload_t;
|
||||||
typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t;
|
typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t;
|
||||||
typedef struct lifetime_cfg_t lifetime_cfg_t;
|
typedef struct lifetime_cfg_t lifetime_cfg_t;
|
||||||
typedef struct mark_t mark_t;
|
typedef struct mark_t mark_t;
|
||||||
@@ -116,6 +117,20 @@ enum ipcomp_transform_t {
|
|||||||
*/
|
*/
|
||||||
extern enum_name_t *ipcomp_transform_names;
|
extern enum_name_t *ipcomp_transform_names;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HW offload mode options
|
||||||
|
*/
|
||||||
|
enum hw_offload_t {
|
||||||
|
HW_OFFLOAD_NO = 0,
|
||||||
|
HW_OFFLOAD_YES = 1,
|
||||||
|
HW_OFFLOAD_AUTO = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum names for hw_offload_t.
|
||||||
|
*/
|
||||||
|
extern enum_name_t *hw_offload_names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct contains details about IPsec SA(s) tied to a policy.
|
* This struct contains details about IPsec SA(s) tied to a policy.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user