Add new IPsec offload type
Subsystems (3)
cover Add new IPsec offload type
From: Leon Romanovsky <[email protected]>
Extend ip tool to support new IPsec offload mode. Followup of the recently accepted series to netdev.
https://lore.kernel.org/r/[email protected]
--------------------------------------------------------------------------------
Changelog:
v1:
* Changed "full offload" to "packet offload" to be aligned with kernel names.
* Rebase to latest iproute2-next
v0: https://lore.kernel.org/all/[email protected]
Thanks
Leon Romanovsky (4):
Update XFRM kernel header
xfrm: prepare state offload logic to set mode
xfrm: add packet offload mode to xfrm state
xfrm: add an interface to offload policy
include/uapi/linux/xfrm.h | 8 +++++++ ip/ipxfrm.c | 15 ++++++++---- ip/xfrm.h | 4 ++-- ip/xfrm_monitor.c | 2 +- ip/xfrm_policy.c | 26 +++++++++++++++++++++ ip/xfrm_state.c | 49 +++++++++++++++++++++++++-------------- man/man8/ip-xfrm.8 | 14 +++++++++++ 7 files changed, 93 insertions(+), 25 deletions(-)
Signature · 1 line
2.38.1
PATCH 1/4 Update XFRM kernel header
From: Leon Romanovsky <[email protected]>
Sync XFRM header upto kernel commit d14f28b8c1de
("xfrm: add new packet offload flag")
--- include/uapi/linux/xfrm.h | 8 ++++++++ 1 file changed, 8 insertions(+)
include/uapi/linux/xfrm.h +8 -0
@@ -519,6 +519,12 @@ struct xfrm_user_offload {*/ #define XFRM_OFFLOAD_IPV6 1#define XFRM_OFFLOAD_INBOUND 2 +/* Two bits above are relevant for state path only, while +* offload is used for both policy and state flows. +* +* In policy offload mode, they are free and can be safely reused. +*/ +#define XFRM_OFFLOAD_PACKET 4struct xfrm_userpolicy_default {#define XFRM_USERPOLICY_UNSPEC 0
@@ -529,12 +535,14 @@ struct xfrm_userpolicy_default {__u8 out; }; +#ifndef __KERNEL__/* backwards compatibility for userspace */ #define XFRMGRP_ACQUIRE 1#define XFRMGRP_EXPIRE 2#define XFRMGRP_SA 4#define XFRMGRP_POLICY 8#define XFRMGRP_REPORT 0x20 +#endif enum xfrm_nlgroups {XFRMNLGRP_NONE ,
Signature · 1 line
2.38.1
PATCH 2/4 xfrm: prepare state offload logic to set mode
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
The offload in xfrm state requires to provide device and direction in order to activate it. However, in the help section, device and direction were displayed as an optional.
As a preparation to addition of packet offload, let's fix the help section and refactor the code to be more clear.
--- ip/xfrm_state.c | 35 +++++++++++++++++++---------------- man/man8/ip-xfrm.8 | 5 +++++ 2 files changed, 24 insertions(+), 16 deletions(-)
ip/xfrm_state.c +19 -16
@@ -61,7 +61,7 @@ static void usage(void)" [ replay-seq-hi SEQ ] [ replay-oseq-hi SEQ ]\n" " [ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [ encap ENCAP ]\n" " [ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag EXTRA-FLAG-LIST ]\n" -" [ offload [dev DEV] dir DIR ]\n" +" [ offload dev DEV dir DIR ]\n" " [ output-mark OUTPUT-MARK [ mask MASK ] ]\n" " [ if_id IF_ID ] [ tfcpad LENGTH ]\n" "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n"
@@ -267,7 +267,7 @@ static int xfrm_state_extra_flag_parse(__u32 *extra_flags, int *argcp, char ***areturn 0 ; } -static int xfrm_offload_dir_parse (__u8 *dir,int *argcp,char ***argvp) +static bool xfrm_offload_dir_parse (__u8 *dir,int *argcp,char ***argvp) {int argc = *argcp;char **argv = *argvp;
@@ -277,12 +277,12 @@ static int xfrm_offload_dir_parse(__u8 *dir, int *argcp, char ***argvp)else if (strcmp (*argv,"out" ) ==0 ) *dir =0 ;else -invarg ("DIR value is invalid" , *argv); +return false; *argcp = argc; *argvp = argv; -return 0 ; +return true; }static int xfrm_state_modify (int cmd,unsigned int flags,int argc,char **argv)
@@ -424,24 +424,27 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)addattr_l (&req.n,sizeof (req.buf),XFRMA_SEC_CTX , (void *)&ctx, ctx.sctx.len); }else if (strcmp (*argv,"offload" ) ==0 ) { - is_offload = true;NEXT_ARG ();if (strcmp (*argv,"dev" ) ==0 ) {NEXT_ARG (); ifindex =ll_name_to_index (*argv); -if (!ifindex) { -invarg ("value after \"offload dev\" is invalid" , *argv); - is_offload = false; - } -NEXT_ARG (); - } +if (!ifindex) +invarg ("Invalid device name" , *argv); + }else +invarg ("Missing dev keyword" , *argv); + +NEXT_ARG ();if (strcmp (*argv,"dir" ) ==0 ) { +bool is_dir; +NEXT_ARG (); -xfrm_offload_dir_parse (&dir, &argc, &argv); - }else { -invarg ("value after \"offload dir\" is invalid" , *argv); - is_offload = false; - } + is_dir =xfrm_offload_dir_parse (&dir, &argc, + &argv); +if (!is_dir) +invarg ("DIR value is invalid" , *argv); + }else +invarg ("Missing DIR keyword" , *argv); + is_offload = true; }else if (strcmp (*argv,"output-mark" ) ==0 ) {NEXT_ARG ();if (get_u32 (&output_mark.v, *argv,0 ))
man/man8/ip-xfrm.8 +5 -0
@@ -65,6 +65,11 @@ ip-xfrm \- transform configuration .IR MASK " ] ]" .RB "[ " if_id .IR IF-ID " ]" +.RB "[ " offload +.RB dev +.IR DEV " +.RB dir +.IR DIR " ]" .RB "[ " tfcpad .IR LENGTH " ]"
Signature · 1 line
2.38.1
PATCH 3/4 xfrm: add packet offload mode to xfrm state
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Allow users to configure xfrm states with packet offload type.
Packet offload mode:
ip xfrm state offload packet dev <if-name> dir <in|out>
Crypto offload mode:
ip xfrm state offload crypto dev <if-name> dir <in|out> ip xfrm state offload dev <if-name> dir <in|out>
The latter variant configures crypto offload mode and is needed to provide backward compatibility.
--- ip/ipxfrm.c | 6 ++++-- ip/xfrm_state.c | 16 ++++++++++++++-- man/man8/ip-xfrm.8 | 1 + 3 files changed, 19 insertions(+), 4 deletions(-)
ip/ipxfrm.c +4 -2
@@ -895,8 +895,10 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, xuo = (struct xfrm_user_offload *)RTA_DATA (tb[XFRMA_OFFLOAD_DEV ]); -fprintf (fp,"dev %s dir %s" ,ll_index_to_name (xuo->ifindex), - (xuo->flags &XFRM_OFFLOAD_INBOUND ) ?"in" :"out" ); +fprintf (fp,"dev %s dir %s mode %s" , +ll_index_to_name (xuo->ifindex), + (xuo->flags &XFRM_OFFLOAD_INBOUND ) ?"in" :"out" , + (xuo->flags &XFRM_OFFLOAD_PACKET ) ?"packet" :"crypto" );fprintf (fp,"%s" , _SL_); }if (tb[XFRMA_IF_ID ]) {
ip/xfrm_state.c +14 -2
@@ -61,7 +61,7 @@ static void usage(void)" [ replay-seq-hi SEQ ] [ replay-oseq-hi SEQ ]\n" " [ flag FLAG-LIST ] [ sel SELECTOR ] [ LIMIT-LIST ] [ encap ENCAP ]\n" " [ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag EXTRA-FLAG-LIST ]\n" -" [ offload dev DEV dir DIR ]\n" +" [ offload [ crypto | packet ] dev DEV dir DIR ]\n" " [ output-mark OUTPUT-MARK [ mask MASK ] ]\n" " [ if_id IF_ID ] [ tfcpad LENGTH ]\n" "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n"
@@ -307,7 +307,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)struct xfrm_user_offload xuo = {};unsigned int ifindex =0 ;__u8 dir =0 ; -bool is_offload = false; +bool is_offload = false, is_packet_offload = false;__u32 replay_window =0 ;__u32 seq =0 , oseq =0 , seq_hi =0 , oseq_hi =0 ;char *idp =NULL ;
@@ -425,6 +425,16 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv) (void *)&ctx, ctx.sctx.len); }else if (strcmp (*argv,"offload" ) ==0 ) {NEXT_ARG (); +/* If user doesn't provide offload mode, treat it as +* crypto one for the backward compatibility. +*/ +if (strcmp (*argv,"crypto" ) ==0 ) +NEXT_ARG (); +else if (strcmp (*argv,"packet" ) ==0 ) { + is_packet_offload = true; +NEXT_ARG (); + } +if (strcmp (*argv,"dev" ) ==0 ) {NEXT_ARG (); ifindex =ll_name_to_index (*argv);
@@ -608,6 +618,8 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv)if (is_offload) { xuo.ifindex = ifindex; xuo.flags = dir; +if (is_packet_offload) + xuo.flags |=XFRM_OFFLOAD_PACKET ;addattr_l (&req.n,sizeof (req.buf),XFRMA_OFFLOAD_DEV , &xuo,sizeof (xuo)); }
man/man8/ip-xfrm.8 +1 -0
@@ -66,6 +66,7 @@ ip-xfrm \- transform configuration .RB "[ " if_id .IR IF-ID " ]" .RB "[ " offload +.RB "[ " crypto | packet " ]" .RB dev .IR DEV " .RB dir
Signature · 1 line
2.38.1
PATCH 4/4 xfrm: add an interface to offload policy
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Extend at "ip xfrm policy" to allow policy offload to specific device. The syntax and the code follow already established pattern from the state offload.
The only difference between them is that direction was already mandatory argument in policy configuration commands, so don't need to add direction handling logic like it was done for the state offload.
The syntax is as follows:
$ ip xfrm policy .... offload packet dev <if-name>
--- ip/ipxfrm.c | 17 ++++++++++------- ip/xfrm.h | 4 ++-- ip/xfrm_monitor.c | 2 +- ip/xfrm_policy.c | 26 ++++++++++++++++++++++++++ man/man8/ip-xfrm.8 | 8 ++++++++ 5 files changed, 47 insertions(+), 10 deletions(-)
ip/ipxfrm.c +10 -7
@@ -688,8 +688,8 @@ done:return 0 ; } -void xfrm_xfrma_print (struct rtattr *tb[],__u16 family, -FILE *fp,const char *prefix,bool nokeys) +void xfrm_xfrma_print (struct rtattr *tb[],__u16 family,FILE *fp, +const char *prefix,bool nokeys,bool dir) {if (tb[XFRMA_MARK ]) {struct rtattr *rta = tb[XFRMA_MARK ];
@@ -895,9 +895,12 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, xuo = (struct xfrm_user_offload *)RTA_DATA (tb[XFRMA_OFFLOAD_DEV ]); -fprintf (fp,"dev %s dir %s mode %s" , -ll_index_to_name (xuo->ifindex), - (xuo->flags &XFRM_OFFLOAD_INBOUND ) ?"in" :"out" , +fprintf (fp,"dev %s " , +ll_index_to_name (xuo->ifindex)); +if (dir) +fprintf (fp,"dir %s " , + (xuo->flags &XFRM_OFFLOAD_INBOUND ) ?"in" :"out" ); +fprintf (fp,"mode %s" , (xuo->flags &XFRM_OFFLOAD_PACKET ) ?"packet" :"crypto" );fprintf (fp,"%s" , _SL_); }
@@ -990,7 +993,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,fprintf (fp," (0x%s)" ,strxf_mask8 (xsinfo->flags));fprintf (fp,"%s" , _SL_); -xfrm_xfrma_print (tb, xsinfo->family, fp, buf, nokeys); +xfrm_xfrma_print (tb, xsinfo->family, fp, buf, nokeys, true);if (!xfrm_selector_iszero (&xsinfo->sel)) {char sbuf[STRBUF_SIZE ];
@@ -1096,7 +1099,7 @@ void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,if (show_stats >0 )xfrm_lifetime_print (&xpinfo->lft, &xpinfo->curlft, fp, buf); -xfrm_xfrma_print (tb, xpinfo->sel.family, fp, buf, false); +xfrm_xfrma_print (tb, xpinfo->sel.family, fp, buf, false, false); } int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
ip/xfrm.h +2 -2
@@ -124,8 +124,8 @@ const char *strxf_proto(__u8 proto);const char *strxf_ptype (__u8 ptype);void xfrm_selector_print (struct xfrm_selector *sel,__u16 family,FILE *fp,const char *prefix); -void xfrm_xfrma_print (struct rtattr *tb[],__u16 family, -FILE *fp,const char *prefix,bool nokeys); +void xfrm_xfrma_print (struct rtattr *tb[],__u16 family,FILE *fp, +const char *prefix,bool nokeys,bool dir);void xfrm_state_info_print (struct xfrm_usersa_info *xsinfo,struct rtattr *tb[],FILE *fp,const char *prefix,const char *title,bool nokeys);
ip/xfrm_monitor.c +1 -1
@@ -199,7 +199,7 @@ static int xfrm_report_print(struct nlmsghdr *n, void *arg)parse_rtattr (tb,XFRMA_MAX ,XFRMREP_RTA (xrep), len); -xfrm_xfrma_print (tb, family, fp," " , nokeys); +xfrm_xfrma_print (tb, family, fp," " , nokeys, true);if (oneline)fprintf (fp,"\n" );
ip/xfrm_policy.c +26 -0
@@ -57,6 +57,7 @@ static void usage(void)" [ mark MARK [ mask MASK ] ] [ index INDEX ] [ ptype PTYPE ]\n" " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n" " [ if_id IF_ID ] [ LIMIT-LIST ] [ TMPL-LIST ]\n" +" [ offload packet dev DEV] } ]\n" "Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n" " [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n" " [ if_id IF_ID ]\n"
@@ -260,6 +261,7 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argvchar *ptypep =NULL ;char *sctxp =NULL ;struct xfrm_userpolicy_type upt = {}; +struct xfrm_user_offload xuo = {};char tmpls_buf[XFRM_TMPLS_BUF_SIZE ] = {};int tmpls_len =0 ;struct xfrm_mark mark = {0 ,0 };
@@ -268,6 +270,8 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argvchar str[CTX_BUF_SIZE ]; } ctx = {};bool is_if_id_set = false; +unsigned int ifindex =0 ; +bool is_offload = false;__u32 if_id =0 ;while (argc >0 ) {
@@ -342,6 +346,21 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argvif (get_u32 (&if_id, *argv,0 ))invarg ("IF_ID value is invalid" , *argv); is_if_id_set = true; + }else if (strcmp (*argv,"offload" ) ==0 ) { +NEXT_ARG (); +if (strcmp (*argv,"packet" ) ==0 ) +NEXT_ARG (); +else +invarg ("Invalid offload mode" , *argv); + +if (strcmp (*argv,"dev" ) ==0 ) { +NEXT_ARG (); + ifindex =ll_name_to_index (*argv); +if (!ifindex) +invarg ("Invalid device name" , *argv); + }else +invarg ("Missing dev keyword" , *argv); + is_offload = true; }else {if (selp)duparg ("unknown" , *argv);
@@ -387,6 +406,13 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argvif (is_if_id_set)addattr32 (&req.n,sizeof (req.buf),XFRMA_IF_ID , if_id); +if (is_offload) { + xuo.ifindex = ifindex; + xuo.flags |=XFRM_OFFLOAD_PACKET ; +addattr_l (&req.n,sizeof (req.buf),XFRMA_OFFLOAD_DEV , &xuo, +sizeof (xuo)); + } +if (rtnl_open_byproto (&rth,0 ,NETLINK_XFRM ) <0 )exit (1 );
man/man8/ip-xfrm.8 +8 -0
@@ -252,6 +252,10 @@ ip-xfrm \- transform configuration .IR FLAG-LIST " ]" .RB "[ " if_id .IR IF-ID " ]" +.RB "[ " offload +.RB packet +.RB dev +.IR DEV " ]" .RI "[ " LIMIT-LIST " ] [ " TMPL-LIST " ]" .ti -8
@@ -593,6 +597,10 @@ of the packets emitted by the state .I IF-ID xfrm interface identifier used to in both xfrm policies and states +.TP +.I DEV +Network interface name used to offload policies and states + .sp .PP .TS
Signature · 1 line
2.38.1
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Hello:
This series was applied to iproute2/iproute2-next.git (main) by David Ahern <[email protected]>:
Quoted 8 lines · On Mon, 12 Dec 2022 09:54:02 +0200 you wrote:
From: Leon Romanovsky <[email protected]>
Extend ip tool to support new IPsec offload mode. Followup of the recently accepted series to netdev.
https://lore.kernel.org/r/[email protected]
--------------------------------------------------------------------------------[...]
Here is the summary with links:
- [iproute2-next,v1,1/4] Update XFRM kernel header
(no matching commit)
- [iproute2-next,v1,2/4] xfrm: prepare state offload logic to set mode
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=bdd19b1edec4
- [iproute2-next,v1,3/4] xfrm: add packet offload mode to xfrm state
https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=a6e740ff406c - [iproute2-next,v1,4/4] xfrm: add an interface to offload policy https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=3422c62d581d
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html