From: Ilan Tayari <[email protected]> Add per-connection configuration flag to enable HW offload.
For kernel_netlink, if flag is set and connection is oriented, attempt to offload on the interface's device by adding the new XFRMA_OFFLOAD_DEV netlink attribute. Signed-off-by: Ilan Tayari <[email protected]> --- include/ipsecconf/keywords.h | 1 + include/whack.h | 1 + lib/libipsecconf/confread.c | 1 + lib/libipsecconf/keywords.c | 1 + lib/libipsecconf/starterwhack.c | 1 + programs/pluto/connections.c | 1 + programs/pluto/connections.h | 1 + programs/pluto/kernel.c | 4 ++++ programs/pluto/kernel.h | 2 ++ programs/pluto/kernel_netlink.c | 16 ++++++++++++++++ programs/pluto/linux26/xfrm.h | 12 ++++++++++++ programs/whack/whack.c | 1 + 12 files changed, 42 insertions(+) diff --git a/include/ipsecconf/keywords.h b/include/ipsecconf/keywords.h index 36bf53529..0b00dcb25 100644 --- a/include/ipsecconf/keywords.h +++ b/include/ipsecconf/keywords.h @@ -156,6 +156,7 @@ enum keyword_numeric_config_field { KBF_SECCOMP, /* set SECCOMP mode */ KBF_VTI_ROUTING, /* let updown do routing into VTI device */ KBF_VTI_SHARED, /* VTI device is shared - enable checks and disable cleanup */ + KBF_HW_OFFLOAD, /* HW offload on network device */ KBF_MAX }; diff --git a/include/whack.h b/include/whack.h index 077a05370..fd96053a0 100644 --- a/include/whack.h +++ b/include/whack.h @@ -155,6 +155,7 @@ struct whack_message { unsigned long sa_replay_window; deltatime_t r_timeout; /* in secs */ unsigned long r_interval; /* in msec */ + bool hw_offload; /* For IKEv1 RFC 3706 - Dead Peer Detection */ deltatime_t dpd_delay; diff --git a/lib/libipsecconf/confread.c b/lib/libipsecconf/confread.c index bd4171c06..71ce2993c 100644 --- a/lib/libipsecconf/confread.c +++ b/lib/libipsecconf/confread.c @@ -147,6 +147,7 @@ void ipsecconf_default_values(struct starter_config *cfg) POLICY_IKE_FRAG_ALLOW | /* ike_frag=yes */ POLICY_ESN_NO; /* esn=no */ + cfg->conn_default.options[KBF_HW_OFFLOAD] = FALSE; cfg->conn_default.options[KBF_IKELIFETIME] = IKE_SA_LIFETIME_DEFAULT; cfg->conn_default.options[KBF_REPLAY_WINDOW] = IPSEC_SA_DEFAULT_REPLAY_WINDOW; diff --git a/lib/libipsecconf/keywords.c b/lib/libipsecconf/keywords.c index 09b7b04b5..9db752ccc 100644 --- a/lib/libipsecconf/keywords.c +++ b/lib/libipsecconf/keywords.c @@ -603,6 +603,7 @@ const struct keyword_def ipsec_conf_keywords_v2[] = { { "modecfgwins1", kv_conn, kt_obsolete, KBF_WARNIGNORE, NOT_ENUM }, { "modecfgwins2", kv_conn, kt_obsolete, KBF_WARNIGNORE, NOT_ENUM }, + { "hw_offload", kv_conn, kt_bool, KBF_HW_OFFLOAD, NOT_ENUM }, { "encapsulation", kv_conn, kt_enum, KBF_ENCAPS, &kw_encaps_list }, { "forceencaps", kv_conn, kt_obsolete, KBF_WARNIGNORE, NOT_ENUM }, diff --git a/lib/libipsecconf/starterwhack.c b/lib/libipsecconf/starterwhack.c index f244f9ce6..c667cec7f 100644 --- a/lib/libipsecconf/starterwhack.c +++ b/lib/libipsecconf/starterwhack.c @@ -530,6 +530,7 @@ static int starter_whack_basic_add_conn(struct starter_config *cfg, if (conn->right.addrtype == KH_IPHOSTNAME) msg.dnshostname = conn->right.strings[KSCF_IP]; + msg.hw_offload = conn->options[KBF_HW_OFFLOAD]; msg.sa_ike_life_seconds = deltatime(conn->options[KBF_IKELIFETIME]); msg.sa_ipsec_life_seconds = deltatime(conn->options[KBF_SALIFETIME]); msg.sa_rekey_margin = deltatime(conn->options[KBF_REKEYMARGIN]); diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c index 9d03f0f03..c47533353 100644 --- a/programs/pluto/connections.c +++ b/programs/pluto/connections.c @@ -1569,6 +1569,7 @@ void add_connection(const struct whack_message *wm) } } + c->hw_offload = wm->hw_offload; c->sa_ike_life_seconds = wm->sa_ike_life_seconds; c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds; c->sa_rekey_margin = wm->sa_rekey_margin; diff --git a/programs/pluto/connections.h b/programs/pluto/connections.h index b07539324..491f11434 100644 --- a/programs/pluto/connections.h +++ b/programs/pluto/connections.h @@ -242,6 +242,7 @@ struct connection { deltatime_t r_timeout; /* max time (in secs) for one packet exchange attempt */ reqid_t sa_reqid; int encapsulation; + bool hw_offload; /* RFC 3706 DPD */ deltatime_t dpd_delay; /* time between checks */ diff --git a/programs/pluto/kernel.c b/programs/pluto/kernel.c index b400da7bf..c924e8181 100644 --- a/programs/pluto/kernel.c +++ b/programs/pluto/kernel.c @@ -1796,6 +1796,10 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound) said_boilerplate.transport_proto = c->spd.this.protocol; said_boilerplate.sa_lifetime = c->sa_ipsec_life_seconds; said_boilerplate.outif = -1; + said_boilerplate.hw_offload = c->hw_offload; + if (c->hw_offload && c->interface) + said_boilerplate.hw_offload_ifindex = if_nametoindex(c->interface->ip_dev->id_rname); + #ifdef HAVE_LABELED_IPSEC said_boilerplate.sec_ctx = st->sec_ctx; #endif diff --git a/programs/pluto/kernel.h b/programs/pluto/kernel.h index 05ac8bf29..003b1d9b1 100644 --- a/programs/pluto/kernel.h +++ b/programs/pluto/kernel.h @@ -117,6 +117,8 @@ struct kernel_sa { #ifdef HAVE_LABELED_IPSEC struct xfrm_user_sec_ctx_ike *sec_ctx; #endif + bool hw_offload; + int hw_offload_ifindex; deltatime_t sa_lifetime; /* number of seconds until SA expires */ /* below two need to enabled and used, instead of getting passed */ diff --git a/programs/pluto/kernel_netlink.c b/programs/pluto/kernel_netlink.c index 77b6010c0..bd16c2900 100644 --- a/programs/pluto/kernel_netlink.c +++ b/programs/pluto/kernel_netlink.c @@ -1235,6 +1235,22 @@ static bool netlink_add_sa(const struct kernel_sa *sa, bool replace) attr = (struct rtattr *)((char *)attr + attr->rta_len); } + if (sa->hw_offload) { + struct xfrm_user_offload xuo; + + xuo.flags |= sa->inbound ? XFRM_OFFLOAD_INBOUND : 0; + if (sa->src->u.v4.sin_family == AF_INET6) + xuo.flags |= XFRM_OFFLOAD_IPV6; + xuo.ifindex = sa->hw_offload_ifindex; + + attr->rta_type = XFRMA_OFFLOAD_DEV; + attr->rta_len = RTA_LENGTH(sizeof(xuo)); + + memcpy(RTA_DATA(attr), &xuo, sizeof(xuo)); + + req.n.nlmsg_len += attr->rta_len; + attr = (struct rtattr *)((char *)attr + attr->rta_len); + } #ifdef HAVE_LABELED_IPSEC if (sa->sec_ctx != NULL) { diff --git a/programs/pluto/linux26/xfrm.h b/programs/pluto/linux26/xfrm.h index 22e61fdf7..104b770ea 100644 --- a/programs/pluto/linux26/xfrm.h +++ b/programs/pluto/linux26/xfrm.h @@ -295,6 +295,11 @@ enum xfrm_attr_type_t { XFRMA_MARK, /* struct xfrm_mark */ XFRMA_TFCPAD, /* __u32 */ XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_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) @@ -469,6 +474,13 @@ struct xfrm_user_mapping { __be16 new_sport; }; +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 diff --git a/programs/whack/whack.c b/programs/whack/whack.c index e2ede966e..8158b27d3 100644 --- a/programs/whack/whack.c +++ b/programs/whack/whack.c @@ -940,6 +940,7 @@ int main(int argc, char **argv) msg.modecfg_domain = NULL; msg.modecfg_banner = NULL; + msg.hw_offload = FALSE; msg.sa_ike_life_seconds = deltatime(IKE_SA_LIFETIME_DEFAULT); msg.sa_ipsec_life_seconds = deltatime(IPSEC_SA_LIFETIME_DEFAULT); msg.sa_rekey_margin = deltatime(SA_REPLACEMENT_MARGIN_DEFAULT); -- 2.11.0 _______________________________________________ Swan-dev mailing list [email protected] https://lists.libreswan.org/mailman/listinfo/swan-dev
