Merge branch 'hw-packet-offload'

This adds support for the new "packet" hardware offload feature that's
added to the Linux kernel with 6.2.  In this mode, the device handles
the complete framing of the ESP packet as well as the policy checks,
in addition to the crypto.

For the IKE sockets, port-based bypass policies are automatically
offloaded to devices that support it.

Closes strongswan/strongswan#1462
This commit is contained in:
Tobias Brunner
2023-02-17 13:29:56 +01:00
18 changed files with 831 additions and 374 deletions
+1 -4
View File
@@ -17,11 +17,8 @@ strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
pkcs1 pkcs8 pem xcbc hmac kdf kernel-netlink socket-default android-dns \ pkcs1 pkcs8 pem xcbc hmac kdf kernel-netlink socket-default android-dns \
stroke eap-identity eap-mschapv2 eap-md5 eap-gtc stroke eap-identity eap-mschapv2 eap-md5 eap-gtc
strongswan_STARTER_PLUGINS := kernel-netlink
# list of all plugins - used to enable them with the function below # list of all plugins - used to enable them with the function below
strongswan_PLUGINS := $(sort $(strongswan_CHARON_PLUGINS) \ strongswan_PLUGINS := $(sort $(strongswan_CHARON_PLUGINS))
$(strongswan_STARTER_PLUGINS))
include $(LOCAL_PATH)/Android.common.mk include $(LOCAL_PATH)/Android.common.mk
+4 -6
View File
@@ -1505,7 +1505,6 @@ m4_include(m4/macros/add-plugin.m4)
# plugin lists for all components # plugin lists for all components
charon_plugins= charon_plugins=
starter_plugins=
pool_plugins= pool_plugins=
attest_plugins= attest_plugins=
pki_plugins= pki_plugins=
@@ -1593,10 +1592,10 @@ ADD_PLUGIN([load-tester], [c charon])
ADD_PLUGIN([kernel-libipsec], [c charon cmd]) ADD_PLUGIN([kernel-libipsec], [c charon cmd])
ADD_PLUGIN([kernel-wfp], [c charon]) ADD_PLUGIN([kernel-wfp], [c charon])
ADD_PLUGIN([kernel-iph], [c charon]) ADD_PLUGIN([kernel-iph], [c charon])
ADD_PLUGIN([kernel-pfkey], [c charon starter nm cmd]) ADD_PLUGIN([kernel-pfkey], [c charon nm cmd])
ADD_PLUGIN([kernel-pfroute], [c charon starter nm cmd]) ADD_PLUGIN([kernel-pfroute], [c charon nm cmd])
ADD_PLUGIN([kernel-netlink], [c charon starter nm cmd]) ADD_PLUGIN([kernel-netlink], [c charon nm cmd])
ADD_PLUGIN([selinux], [c charon starter nm cmd]) ADD_PLUGIN([selinux], [c charon nm cmd])
ADD_PLUGIN([resolve], [c charon cmd]) ADD_PLUGIN([resolve], [c charon cmd])
ADD_PLUGIN([save-keys], [c]) ADD_PLUGIN([save-keys], [c])
ADD_PLUGIN([socket-default], [c charon nm cmd]) ADD_PLUGIN([socket-default], [c charon nm cmd])
@@ -1666,7 +1665,6 @@ ADD_PLUGIN([unity], [c charon])
ADD_PLUGIN([counters], [c charon]) ADD_PLUGIN([counters], [c charon])
AC_SUBST(charon_plugins) AC_SUBST(charon_plugins)
AC_SUBST(starter_plugins)
AC_SUBST(pool_plugins) AC_SUBST(pool_plugins)
AC_SUBST(attest_plugins) AC_SUBST(attest_plugins)
AC_SUBST(pki_plugins) AC_SUBST(pki_plugins)
+1
View File
@@ -503,6 +503,7 @@ struct xfrm_user_offload {
}; };
#define XFRM_OFFLOAD_IPV6 1 #define XFRM_OFFLOAD_IPV6 1
#define XFRM_OFFLOAD_INBOUND 2 #define XFRM_OFFLOAD_INBOUND 2
#define XFRM_OFFLOAD_PACKET 4
#ifndef __KERNEL__ #ifndef __KERNEL__
/* backwards compatibility for userspace */ /* backwards compatibility for userspace */
+3 -1
View File
@@ -95,7 +95,7 @@ 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;
/** no (disabled), yes (enabled), auto (enabled if supported) */ /** HW offload mode */
hw_offload_t hw_offload; hw_offload_t hw_offload;
/** Mark the SA should apply to packets after processing */ /** Mark the SA should apply to packets after processing */
mark_t mark; mark_t mark;
@@ -180,6 +180,8 @@ struct kernel_ipsec_manage_policy_t {
policy_priority_t prio; policy_priority_t prio;
/** Manually-set priority (automatic if set to 0) */ /** Manually-set priority (automatic if set to 0) */
uint32_t manual_prio; uint32_t manual_prio;
/** HW offload mode */
hw_offload_t hw_offload;
/** Source address of the SA(s) tied to this policy */ /** Source address of the SA(s) tied to this policy */
host_t *src; host_t *src;
/** Destination address of the SA(s) tied to this policy */ /** Destination address of the SA(s) tied to this policy */
File diff suppressed because it is too large Load Diff
@@ -79,9 +79,6 @@
#define ROUTING_TABLE_PRIO 0 #define ROUTING_TABLE_PRIO 0
#endif #endif
/** multicast groups (for groups > 31 setsockopt has to be used) */
#define nl_group(group) (1 << (group - 1))
ENUM(rt_msg_names, RTM_NEWLINK, RTM_GETRULE, ENUM(rt_msg_names, RTM_NEWLINK, RTM_GETRULE,
"RTM_NEWLINK", "RTM_NEWLINK",
"RTM_DELLINK", "RTM_DELLINK",
@@ -343,9 +340,9 @@ struct private_kernel_netlink_net_t {
netlink_socket_t *socket; netlink_socket_t *socket;
/** /**
* Netlink rt socket to receive address change events * Netlink rt event socket
*/ */
int socket_events; netlink_event_socket_t *socket_events;
/** /**
* earliest time of the next roam event * earliest time of the next roam event
@@ -1451,76 +1448,36 @@ static void process_rule(private_kernel_netlink_net_t *this,
#endif #endif
} }
/** CALLBACK(receive_events, void,
* Receives events from kernel private_kernel_netlink_net_t *this, struct nlmsghdr *hdr)
*/
static bool receive_events(private_kernel_netlink_net_t *this, int fd,
watcher_event_t event)
{ {
char response[netlink_get_buflen()]; switch (hdr->nlmsg_type)
struct nlmsghdr *hdr = (struct nlmsghdr*)response;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(addr);
int len;
len = recvfrom(this->socket_events, response, sizeof(response),
MSG_DONTWAIT, (struct sockaddr*)&addr, &addr_len);
if (len < 0)
{ {
switch (errno) case RTM_NEWADDR:
{ case RTM_DELADDR:
case EINTR: process_addr(this, hdr, TRUE);
/* interrupted, try again */ break;
return TRUE; case RTM_NEWLINK:
case EAGAIN: case RTM_DELLINK:
/* no data ready, select again */ process_link(this, hdr, TRUE);
return TRUE; break;
default: case RTM_NEWROUTE:
DBG1(DBG_KNL, "unable to receive from RT event socket %s (%d)", case RTM_DELROUTE:
strerror(errno), errno); if (this->process_route)
sleep(1); {
return TRUE; process_route(this, hdr);
} }
break;
case RTM_NEWRULE:
case RTM_DELRULE:
if (this->process_rules)
{
process_rule(this, hdr);
}
break;
default:
break;
} }
if (addr.nl_pid != 0)
{ /* not from kernel. not interested, try another one */
return TRUE;
}
while (NLMSG_OK(hdr, len))
{
/* looks good so far, dispatch netlink message */
switch (hdr->nlmsg_type)
{
case RTM_NEWADDR:
case RTM_DELADDR:
process_addr(this, hdr, TRUE);
break;
case RTM_NEWLINK:
case RTM_DELLINK:
process_link(this, hdr, TRUE);
break;
case RTM_NEWROUTE:
case RTM_DELROUTE:
if (this->process_route)
{
process_route(this, hdr);
}
break;
case RTM_NEWRULE:
case RTM_DELRULE:
if (this->process_rules)
{
process_rule(this, hdr);
}
break;
default:
break;
}
hdr = NLMSG_NEXT(hdr, len);
}
return TRUE;
} }
/** enumerator over addresses */ /** enumerator over addresses */
@@ -3056,11 +3013,7 @@ METHOD(kernel_net_t, destroy, void,
manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table, manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table,
this->routing_table_prio); this->routing_table_prio);
} }
if (this->socket_events > 0) DESTROY_IF(this->socket_events);
{
lib->watcher->remove(lib->watcher, this->socket_events);
close(this->socket_events);
}
enumerator = this->routes->ht.create_enumerator(&this->routes->ht); enumerator = this->routes->ht.create_enumerator(&this->routes->ht);
while (enumerator->enumerate(enumerator, NULL, (void**)&route)) while (enumerator->enumerate(enumerator, NULL, (void**)&route))
{ {
@@ -3096,7 +3049,7 @@ kernel_netlink_net_t *kernel_netlink_net_create()
{ {
private_kernel_netlink_net_t *this; private_kernel_netlink_net_t *this;
enumerator_t *enumerator; enumerator_t *enumerator;
bool register_for_events = TRUE; uint32_t groups;
char *exclude; char *exclude;
INIT(this, INIT(this,
@@ -3168,11 +3121,6 @@ kernel_netlink_net_t *kernel_netlink_net_create()
return NULL; return NULL;
} }
if (streq(lib->ns, "starter"))
{ /* starter has no threads, so we do not register for kernel events */
register_for_events = FALSE;
}
exclude = lib->settings->get_str(lib->settings, exclude = lib->settings->get_str(lib->settings,
"%s.ignore_routing_tables", NULL, lib->ns); "%s.ignore_routing_tables", NULL, lib->ns);
if (exclude) if (exclude)
@@ -3194,45 +3142,25 @@ kernel_netlink_net_t *kernel_netlink_net_create()
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
} }
if (register_for_events) groups = nl_group(RTNLGRP_IPV4_IFADDR) |
nl_group(RTNLGRP_IPV6_IFADDR) |
nl_group(RTNLGRP_LINK);
if (this->process_route)
{ {
struct sockaddr_nl addr; groups |= nl_group(RTNLGRP_IPV4_ROUTE) |
nl_group(RTNLGRP_IPV6_ROUTE);
memset(&addr, 0, sizeof(addr)); }
addr.nl_family = AF_NETLINK; if (this->process_rules)
{
/* create and bind RT socket for events (address/interface/route changes) */ groups |= nl_group(RTNLGRP_IPV4_RULE) |
this->socket_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); nl_group(RTNLGRP_IPV6_RULE);
if (this->socket_events < 0) }
{ this->socket_events = netlink_event_socket_create(NETLINK_ROUTE, groups,
DBG1(DBG_KNL, "unable to create RT event socket: %s (%d)", receive_events, this);
strerror(errno), errno); if (!this->socket_events)
destroy(this); {
return NULL; destroy(this);
} return NULL;
addr.nl_groups = nl_group(RTNLGRP_IPV4_IFADDR) |
nl_group(RTNLGRP_IPV6_IFADDR) |
nl_group(RTNLGRP_LINK);
if (this->process_route)
{
addr.nl_groups |= nl_group(RTNLGRP_IPV4_ROUTE) |
nl_group(RTNLGRP_IPV6_ROUTE);
}
if (this->process_rules)
{
addr.nl_groups |= nl_group(RTNLGRP_IPV4_RULE) |
nl_group(RTNLGRP_IPV6_RULE);
}
if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr)))
{
DBG1(DBG_KNL, "unable to bind RT event socket: %s (%d)",
strerror(errno), errno);
destroy(this);
return NULL;
}
lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ,
(watcher_cb_t)receive_events, this);
} }
if (init_address_list(this) != SUCCESS) if (init_address_list(this) != SUCCESS)
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2008-2022 Tobias Brunner * Copyright (C) 2008-2023 Tobias Brunner
* Copyright (C) 2014 Martin Willi * Copyright (C) 2014 Martin Willi
* *
* Copyright (C) secunet Security Networks AG * Copyright (C) secunet Security Networks AG
@@ -58,6 +58,7 @@
#endif #endif
typedef struct private_netlink_socket_t private_netlink_socket_t; typedef struct private_netlink_socket_t private_netlink_socket_t;
typedef struct private_netlink_event_socket_t private_netlink_event_socket_t;
/** /**
* Private variables and functions of netlink_socket_t class. * Private variables and functions of netlink_socket_t class.
@@ -125,6 +126,37 @@ struct private_netlink_socket_t {
bool ignore_retransmit_errors; bool ignore_retransmit_errors;
}; };
/**
* Private data of netlink_event_socket_t class
*/
struct private_netlink_event_socket_t {
/**
* Public interface
*/
netlink_event_socket_t public;
/**
* Registered callback
*/
netlink_event_cb_t cb;
/**
* User data to pass to callback
*/
void *user;
/**
* Netlink socket
*/
int socket;
/**
* Buffer size for received Netlink messages
*/
u_int buflen;
};
/** /**
* #definable hook to simulate request message loss * #definable hook to simulate request message loss
*/ */
@@ -700,6 +732,92 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
return &this->public; return &this->public;
} }
CALLBACK(watch_event, bool,
private_netlink_event_socket_t *this, int fd, watcher_event_t event)
{
char buf[this->buflen];
struct nlmsghdr *hdr = (struct nlmsghdr*)buf;
struct sockaddr_nl addr;
socklen_t addr_len = sizeof(addr);
int len;
len = recvfrom(this->socket, buf, sizeof(buf), MSG_DONTWAIT,
(struct sockaddr*)&addr, &addr_len);
if (len < 0)
{
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
DBG1(DBG_KNL, "netlink event read error: %s", strerror(errno));
}
return TRUE;
}
else if (addr.nl_pid != 0)
{ /* ignore non-kernel messages */
return TRUE;
}
while (NLMSG_OK(hdr, len))
{
this->cb(this->user, hdr);
hdr = NLMSG_NEXT(hdr, len);
}
return TRUE;
}
METHOD(netlink_event_socket_t, destroy_event, void,
private_netlink_event_socket_t *this)
{
if (this->socket != -1)
{
lib->watcher->remove(lib->watcher, this->socket);
close(this->socket);
}
free(this);
}
/*
* Described in header
*/
netlink_event_socket_t *netlink_event_socket_create(int protocol, uint32_t groups,
netlink_event_cb_t cb, void *user)
{
private_netlink_event_socket_t *this;
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
.nl_groups = groups,
};
INIT(this,
.public = {
.destroy = _destroy_event,
},
.cb = cb,
.user = user,
.buflen = netlink_get_buflen(),
);
this->socket = socket(AF_NETLINK, SOCK_RAW, protocol);
if (this->socket == -1)
{
DBG1(DBG_KNL, "unable to create netlink event socket: %s (%d)",
strerror(errno), errno);
destroy_event(this);
return NULL;
}
if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr)))
{
DBG1(DBG_KNL, "unable to bind netlink event socket: %s (%d)",
strerror(errno), errno);
destroy_event(this);
return NULL;
}
lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch_event, this);
return &this->public;
}
/* /*
* Described in header * Described in header
*/ */
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2008-2022 Tobias Brunner * Copyright (C) 2008-2023 Tobias Brunner
* *
* Copyright (C) secunet Security Networks AG * Copyright (C) secunet Security Networks AG
* *
@@ -40,7 +40,16 @@ typedef union {
u_char bytes[KERNEL_NETLINK_BUFSIZE]; u_char bytes[KERNEL_NETLINK_BUFSIZE];
} netlink_buf_t __attribute__((aligned(RTA_ALIGNTO))); } netlink_buf_t __attribute__((aligned(RTA_ALIGNTO)));
/**
* Callback function for netlink events.
*
* @param user user data, as passed to constructor
* @param hdr received netlink message
*/
typedef void (*netlink_event_cb_t)(void *user, struct nlmsghdr *hdr);
typedef struct netlink_socket_t netlink_socket_t; typedef struct netlink_socket_t netlink_socket_t;
typedef struct netlink_event_socket_t netlink_event_socket_t;
/** /**
* Wrapper around a netlink socket. * Wrapper around a netlink socket.
@@ -80,6 +89,45 @@ struct netlink_socket_t {
netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
bool parallel); bool parallel);
/**
* Wrapper around a bound netlink event socket.
*/
struct netlink_event_socket_t {
/**
* Destroy the event socket.
*/
void (*destroy)(netlink_event_socket_t *this);
};
/**
* Create a netlink_event_socket_t object.
*
* @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
* @param groups event groups to bind (use nl_group())
* @param cb callback to invoke for each event
* @param user user data passed to callback
*/
netlink_event_socket_t *netlink_event_socket_create(int protocol, uint32_t groups,
netlink_event_cb_t cb, void *user);
/**
* Helper to create bitmask for Netlink multicast groups.
*
* For groups > 31, setsockopt() with NETLINK_ADD_MEMBERSHIP has to be used,
* which is currently not supported by the event socket.
*/
static inline uint32_t nl_group(uint32_t group)
{
if (group > 31)
{
DBG1(DBG_KNL, "netlink multicast group %d currently not supported",
group);
return 0;
}
return group ? (1 << (group - 1)) : 0;
}
/** /**
* Creates an rtattr and adds it to the given netlink message. * Creates an rtattr and adds it to the given netlink message.
* *
@@ -3303,7 +3303,6 @@ METHOD(kernel_ipsec_t, destroy, void,
kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
{ {
private_kernel_pfkey_ipsec_t *this; private_kernel_pfkey_ipsec_t *this;
bool register_for_events = TRUE;
int rcv_buffer; int rcv_buffer;
INIT(this, INIT(this,
@@ -3339,11 +3338,6 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
FALSE, lib->ns), FALSE, lib->ns),
); );
if (streq(lib->ns, "starter"))
{ /* starter has no threads, so we do not register for kernel events */
register_for_events = FALSE;
}
/* create a PF_KEY socket to communicate with the kernel */ /* create a PF_KEY socket to communicate with the kernel */
this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
if (this->socket <= 0) if (this->socket <= 0)
@@ -3353,41 +3347,38 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
return NULL; return NULL;
} }
if (register_for_events) /* create a PF_KEY socket for ACQUIRE & EXPIRE */
this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
if (this->socket_events <= 0)
{ {
/* create a PF_KEY socket for ACQUIRE & EXPIRE */ DBG1(DBG_KNL, "unable to create PF_KEY event socket");
this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); destroy(this);
if (this->socket_events <= 0) return NULL;
{
DBG1(DBG_KNL, "unable to create PF_KEY event socket");
destroy(this);
return NULL;
}
rcv_buffer = lib->settings->get_int(lib->settings,
"%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns);
if (rcv_buffer > 0)
{
if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF,
&rcv_buffer, sizeof(rcv_buffer)) == -1)
{
DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY "
"event socket: %s", strerror(errno));
}
}
/* register the event socket */
if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
{
DBG1(DBG_KNL, "unable to register PF_KEY event socket");
destroy(this);
return NULL;
}
lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ,
(watcher_cb_t)receive_events, this);
} }
rcv_buffer = lib->settings->get_int(lib->settings,
"%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns);
if (rcv_buffer > 0)
{
if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF,
&rcv_buffer, sizeof(rcv_buffer)) == -1)
{
DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY "
"event socket: %s", strerror(errno));
}
}
/* register the event socket */
if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
{
DBG1(DBG_KNL, "unable to register PF_KEY event socket");
destroy(this);
return NULL;
}
lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ,
(watcher_cb_t)receive_events, this);
return &this->public; return &this->public;
} }
@@ -2114,21 +2114,9 @@ kernel_pfroute_net_t *kernel_pfroute_net_create()
destroy(this); destroy(this);
return NULL; return NULL;
} }
lib->watcher->add(lib->watcher, this->socket, WATCHER_READ,
(watcher_cb_t)receive_events, this);
if (streq(lib->ns, "starter"))
{
/* starter has no threads, so we do not register for kernel events */
if (shutdown(this->socket, SHUT_RD) != 0)
{
DBG1(DBG_KNL, "closing read end of PF_ROUTE socket failed: %s",
strerror(errno));
}
}
else
{
lib->watcher->add(lib->watcher, this->socket, WATCHER_READ,
(watcher_cb_t)receive_events, this);
}
if (init_address_list(this) != SUCCESS) if (init_address_list(this) != SUCCESS)
{ {
DBG1(DBG_KNL, "unable to get interface list"); DBG1(DBG_KNL, "unable to get interface list");
+5 -3
View File
@@ -1040,9 +1040,11 @@ CALLBACK(parse_hw_offload, bool,
action_t *out, chunk_t v) action_t *out, chunk_t v)
{ {
enum_map_t map[] = { enum_map_t map[] = {
{ "no", HW_OFFLOAD_NO }, { "no", HW_OFFLOAD_NO },
{ "yes", HW_OFFLOAD_YES }, { "yes", HW_OFFLOAD_CRYPTO },
{ "auto", HW_OFFLOAD_AUTO }, { "crypto", HW_OFFLOAD_CRYPTO },
{ "packet", HW_OFFLOAD_PACKET },
{ "auto", HW_OFFLOAD_AUTO },
}; };
int d; int d;
+4
View File
@@ -1094,6 +1094,7 @@ static status_t install_policies_inbound(private_child_sa_t *this,
.type = type, .type = type,
.prio = priority, .prio = priority,
.manual_prio = manual_prio, .manual_prio = manual_prio,
.hw_offload = this->config->get_hw_offload(this->config),
.src = other_addr, .src = other_addr,
.dst = my_addr, .dst = my_addr,
.sa = my_sa, .sa = my_sa,
@@ -1131,6 +1132,7 @@ static status_t install_policies_outbound(private_child_sa_t *this,
.type = type, .type = type,
.prio = priority, .prio = priority,
.manual_prio = manual_prio, .manual_prio = manual_prio,
.hw_offload = this->config->get_hw_offload(this->config),
.src = my_addr, .src = my_addr,
.dst = other_addr, .dst = other_addr,
.sa = other_sa, .sa = other_sa,
@@ -1206,6 +1208,7 @@ static void del_policies_inbound(private_child_sa_t *this,
.type = type, .type = type,
.prio = priority, .prio = priority,
.manual_prio = manual_prio, .manual_prio = manual_prio,
.hw_offload = this->config->get_hw_offload(this->config),
.src = other_addr, .src = other_addr,
.dst = my_addr, .dst = my_addr,
.sa = my_sa, .sa = my_sa,
@@ -1242,6 +1245,7 @@ static void del_policies_outbound(private_child_sa_t *this,
.type = type, .type = type,
.prio = priority, .prio = priority,
.manual_prio = manual_prio, .manual_prio = manual_prio,
.hw_offload = this->config->get_hw_offload(this->config),
.src = my_addr, .src = my_addr,
.dst = other_addr, .dst = other_addr,
.sa = other_sa, .sa = other_sa,
+3
View File
@@ -95,6 +95,7 @@ static bool install_shunt_policy(child_cfg_t *child)
policy_type_t policy_type; policy_type_t policy_type;
policy_priority_t policy_prio; policy_priority_t policy_prio;
status_t status = SUCCESS; status_t status = SUCCESS;
hw_offload_t hw_offload;
uint32_t manual_prio; uint32_t manual_prio;
char *interface; char *interface;
bool fwd_out; bool fwd_out;
@@ -125,6 +126,7 @@ static bool install_shunt_policy(child_cfg_t *child)
hosts->destroy(hosts); hosts->destroy(hosts);
manual_prio = child->get_manual_prio(child); manual_prio = child->get_manual_prio(child);
hw_offload = child->get_hw_offload(child);
interface = child->get_interface(child); interface = child->get_interface(child);
fwd_out = child->has_option(child, OPT_FWD_OUT_POLICIES); fwd_out = child->has_option(child, OPT_FWD_OUT_POLICIES);
@@ -157,6 +159,7 @@ static bool install_shunt_policy(child_cfg_t *child)
.type = policy_type, .type = policy_type,
.prio = policy_prio, .prio = policy_prio,
.manual_prio = manual_prio, .manual_prio = manual_prio,
.hw_offload = hw_offload,
.src = host_any, .src = host_any,
.dst = host_any, .dst = host_any,
.sa = &sa, .sa = &sa,
+2 -1
View File
@@ -40,7 +40,8 @@ ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH,
ENUM(hw_offload_names, HW_OFFLOAD_NO, HW_OFFLOAD_AUTO, ENUM(hw_offload_names, HW_OFFLOAD_NO, HW_OFFLOAD_AUTO,
"no", "no",
"yes", "crypto",
"packet",
"auto", "auto",
); );
+3 -2
View File
@@ -125,8 +125,9 @@ extern enum_name_t *ipcomp_transform_names;
*/ */
enum hw_offload_t { enum hw_offload_t {
HW_OFFLOAD_NO = 0, HW_OFFLOAD_NO = 0,
HW_OFFLOAD_YES = 1, HW_OFFLOAD_CRYPTO = 1,
HW_OFFLOAD_AUTO = 2, HW_OFFLOAD_PACKET = 2,
HW_OFFLOAD_AUTO = 3,
}; };
/** /**
+1 -2
View File
@@ -18,8 +18,7 @@ LOCAL_C_INCLUDES += \
$(strongswan_PATH)/src/stroke $(strongswan_PATH)/src/stroke
LOCAL_CFLAGS := $(strongswan_CFLAGS) \ LOCAL_CFLAGS := $(strongswan_CFLAGS) \
-DIPSEC_SCRIPT='"ipsec"' \ -DIPSEC_SCRIPT='"ipsec"'
-DPLUGINS='"$(strongswan_STARTER_PLUGINS)"'
LOCAL_MODULE := starter LOCAL_MODULE := starter
-1
View File
@@ -24,7 +24,6 @@ AM_CPPFLAGS = \
-DIPSEC_SCRIPT=\"${ipsec_script}\" \ -DIPSEC_SCRIPT=\"${ipsec_script}\" \
-DDEV_RANDOM=\"${random_device}\" \ -DDEV_RANDOM=\"${random_device}\" \
-DDEV_URANDOM=\"${urandom_device}\" \ -DDEV_URANDOM=\"${urandom_device}\" \
-DPLUGINS=\""${starter_plugins}\"" \
-DDEBUG -DDEBUG
AM_CFLAGS = \ AM_CFLAGS = \
+6 -4
View File
@@ -1071,10 +1071,12 @@ connections.<conn>.children.<child>.hw_offload = no
implementation. implementation.
Enable hardware offload for this CHILD_SA, if supported by the IPsec Enable hardware offload for this CHILD_SA, if supported by the IPsec
implementation. The value _yes_ enforces offloading and the installation implementation. The values _crypto_ or _packet_ enforce crypto or full
will fail if it's not supported by either kernel or device. The value _auto_ packet offloading and the installation will fail if the selected mode is not
enables offloading, if it's supported, but the installation does not fail supported by either kernel or device. On Linux, _packet_ also offloads
otherwise. policies, including trap policies. The value _auto_ enables full packet
or crypto offloading, if either is supported, but the installation does not
fail otherwise.
connections.<conn>.children.<child>.copy_df = yes connections.<conn>.children.<child>.copy_df = yes
Whether to copy the DF bit to the outer IPv4 header in tunnel mode. Whether to copy the DF bit to the outer IPv4 header in tunnel mode.