mlx5 IPsec full offload part
Subsystems (6)
cover mlx5 IPsec full offload part
From: Leon Romanovsky <[email protected]>
Hi,
This is supplementary part of "Extend XFRM core to allow full offload configuration" series https://lore.kernel.org/all/[email protected]
The series starts from very basic cleanup, continues with code alignment and adds IPsec full offload logic to mlx5 driver.
Thanks
Leon Romanovsky (25):
net/mlx5: Delete esp_id field that is not used
net/mlx5: Add HW definitions for IPsec full offload net/mlx5: Remove from FPGA IFC file not-needed definitions net/mlx5e: Advertise IPsec full offload support net/mlx5e: Store replay window in XFRM attributes net/mlx5e: Remove extra layers of defines
net/mlx5e: Create symmetric IPsec RX and TX flow steering structs net/mlx5e: Use mlx5 print routines for low level IPsec code net/mlx5e: Remove accesses to priv for low level IPsec FS code net/mlx5e: Validate that IPsec full offload can handle packets net/mlx5e: Create Advanced Steering Operation object for IPsec net/mlx5e: Create hardware IPsec full offload objects net/mlx5e: Move IPsec flow table creation to separate function net/mlx5e: Refactor FTE setup code to be more clear net/mlx5e: Flatten the IPsec RX add rule path
net/mlx5e: Make clear what IPsec rx_err does
net/mlx5e: Group IPsec miss handles into separate struct net/mlx5e: Generalize creation of default IPsec miss group and rule net/mlx5e: Create IPsec policy offload tables
net/mlx5e: Add XFRM policy offload logic
net/mlx5e: Use same coding pattern for Rx and Tx flows net/mlx5e: Configure IPsec full offload flow steering net/mlx5e: Improve IPsec flow steering autogroup net/mlx5e: Skip IPsec encryption for TX path without matching policy net/mlx5e: Open mlx5 driver to accept IPsec full offload
Raed Salem (1):
net/mlx5e: Add statistics for Rx/Tx IPsec offloaded flows
.../net/ethernet/mellanox/mlx5/core/en/fs.h | 3 +- .../mellanox/mlx5/core/en_accel/ipsec.c | 209 +++- .../mellanox/mlx5/core/en_accel/ipsec.h | 93 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 1066 ++++++++++++----- .../mlx5/core/en_accel/ipsec_offload.c | 81 +- .../mellanox/mlx5/core/en_accel/ipsec_stats.c | 52 + .../ethernet/mellanox/mlx5/core/en_stats.c | 1 + .../ethernet/mellanox/mlx5/core/en_stats.h | 1 + .../net/ethernet/mellanox/mlx5/core/fs_core.c | 6 +- include/linux/mlx5/fs.h | 5 +- include/linux/mlx5/mlx5_ifc.h | 71 +- include/linux/mlx5/mlx5_ifc_fpga.h | 24 - 12 files changed, 1223 insertions(+), 389 deletions(-)
Signature · 1 line
2.37.2
PATCH 1/26 net/mlx5: Delete esp_id field that is not used
From: Leon Romanovsky <[email protected]>
The esp_id field is not used in mlx5 code, hence we can delete it.
--- include/linux/mlx5/fs.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
include/linux/mlx5/fs.h +1 -4
@@ -243,10 +243,7 @@ struct mlx5_flow_act {u32 action;struct mlx5_modify_hdr *modify_hdr;struct mlx5_pkt_reformat *pkt_reformat; -union { -u32 ipsec_obj_id; -uintptr_t esp_id; - }; +u32 ipsec_obj_id;u32 flags;struct mlx5_fs_vlan vlan[MLX5_FS_VLAN_DEPTH ];struct ib_counters *counters;
Signature · 1 line
2.37.2
PATCH 2/26 net/mlx5: Add HW definitions for IPsec full offload
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Add all needed bits to support IPsec full offload mode.
--- include/linux/mlx5/mlx5_ifc.h | 55 +++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-)
include/linux/mlx5/mlx5_ifc.h +52 -3
@@ -442,7 +442,10 @@ struct mlx5_ifc_flow_table_prop_layout_bits {u8 max_modify_header_actions[0x8 ];u8 max_ft_level[0x8 ]; -u8 reserved_at_40[0x6 ]; +u8 reformat_add_esp_trasport[0x1 ]; +u8 reserved_at_41[0x2 ]; +u8 reformat_del_esp_trasport[0x1 ]; +u8 reserved_at_44[0x2 ];u8 execute_aso[0x1 ];u8 reserved_at_47[0x19 ];
@@ -611,7 +614,11 @@ struct mlx5_ifc_fte_match_set_misc2_bits {u8 metadata_reg_a[0x20 ]; -u8 reserved_at_1a0[0x60 ]; +u8 reserved_at_1a0[0x10 ]; +u8 ipsec_syndrome[0x8 ]; +u8 ipsec_next_header[0x8 ]; + +u8 reserved_at_1c0[0x40 ]; };struct mlx5_ifc_fte_match_set_misc3_bits {
@@ -6314,6 +6321,9 @@ enum mlx5_reformat_ctx_type {MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL =0x2 ,MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2 =0x3 ,MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL =0x4 , +MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV4 =0x5 , +MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT =0x8 , +MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV6 =0xb ,MLX5_REFORMAT_TYPE_INSERT_HDR =0xf , MLX5_REFORMAT_TYPE_REMOVE_HDR = 0x10, };
@@ -11477,6 +11487,41 @@ enum { MLX5_IPSEC_OBJECT_ICV_LEN_16B, }; +enum { +MLX5_IPSEC_ASO_REG_C_0_1 =0x0 , +MLX5_IPSEC_ASO_REG_C_2_3 =0x1 , +MLX5_IPSEC_ASO_REG_C_4_5 =0x2 , +MLX5_IPSEC_ASO_REG_C_6_7 =0x3 , +}; + +enum { +MLX5_IPSEC_ASO_MODE =0x0 , +MLX5_IPSEC_ASO_REPLAY_PROTECTION =0x1 , +MLX5_IPSEC_ASO_INC_SN =0x2 , +}; + +struct mlx5_ifc_ipsec_aso_bits { +u8 valid[0x1 ]; +u8 reserved_at_201[0x1 ]; +u8 mode[0x2 ]; +u8 window_sz[0x2 ]; +u8 soft_lft_arm[0x1 ]; +u8 hard_lft_arm[0x1 ]; +u8 remove_flow_enable[0x1 ]; +u8 esn_event_arm[0x1 ]; +u8 reserved_at_20a[0x16 ]; + +u8 remove_flow_pkt_cnt[0x20 ]; + +u8 remove_flow_soft_lft[0x20 ]; + +u8 reserved_at_260[0x80 ]; + +u8 mode_parameter[0x20 ]; + +u8 replay_protection_window[0x100 ]; +}; +struct mlx5_ifc_ipsec_obj_bits {u8 modify_field_select[0x40 ];u8 full_offload[0x1 ];
@@ -11498,7 +11543,11 @@ struct mlx5_ifc_ipsec_obj_bits {u8 implicit_iv[0x40 ]; -u8 reserved_at_100[0x700 ]; +u8 reserved_at_100[0x8 ]; +u8 ipsec_aso_access_pd[0x18 ]; +u8 reserved_at_120[0xe0 ]; + +struct mlx5_ifc_ipsec_aso_bits ipsec_aso; };struct mlx5_ifc_create_ipsec_obj_in_bits {
Signature · 1 line
2.37.2
PATCH 3/26 net/mlx5: Remove from FPGA IFC file not-needed definitions
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Move IP layout bits definitions to be close to the place that actually uses it, together with removal extra defines that not in-use.
--- include/linux/mlx5/mlx5_ifc.h | 16 ++++++++++++++++ include/linux/mlx5/mlx5_ifc_fpga.h | 24 ------------------------ 2 files changed, 16 insertions(+), 24 deletions(-)
include/linux/mlx5/mlx5_ifc.h +16 -0
@@ -479,6 +479,22 @@ struct mlx5_ifc_odp_per_transport_service_cap_bits {u8 reserved_at_6[0x1a ]; }; +struct mlx5_ifc_ipv4_layout_bits { +u8 reserved_at_0[0x60 ]; + +u8 ipv4[0x20 ]; +}; + +struct mlx5_ifc_ipv6_layout_bits { +u8 ipv6[16 ][0x8 ]; +}; + +union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits { +struct mlx5_ifc_ipv6_layout_bits ipv6_layout; +struct mlx5_ifc_ipv4_layout_bits ipv4_layout; +u8 reserved_at_0[0x80 ]; +}; +struct mlx5_ifc_fte_match_set_lyr_2_4_bits {u8 smac_47_16[0x20 ];
include/linux/mlx5/mlx5_ifc_fpga.h +0 -24
@@ -32,30 +32,6 @@ #ifndef MLX5_IFC_FPGA_H #define MLX5_IFC_FPGA_H -struct mlx5_ifc_ipv4_layout_bits { - u8 reserved_at_0[0x60]; - - u8 ipv4[0x20]; -}; - -struct mlx5_ifc_ipv6_layout_bits { - u8 ipv6[16][0x8]; -}; - -union mlx5_ifc_ipv6_layout_ipv4_layout_auto_bits { - struct mlx5_ifc_ipv6_layout_bits ipv6_layout; - struct mlx5_ifc_ipv4_layout_bits ipv4_layout; - u8 reserved_at_0[0x80]; -}; - -enum { - MLX5_FPGA_CAP_SANDBOX_VENDOR_ID_MLNX = 0x2c9, -}; - -enum { - MLX5_FPGA_CAP_SANDBOX_PRODUCT_ID_IPSEC = 0x2, -}; - struct mlx5_ifc_fpga_shell_caps_bits { u8 max_num_qps[0x10]; u8 reserved_at_10[0x8];
Signature · 1 line
2.37.2
PATCH 4/26 net/mlx5e: Advertise IPsec full offload support
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Add needed capabilities check to determine if device supports IPsec full offload mode.
--- .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h | 1 + .../mellanox/mlx5/core/en_accel/ipsec_offload.c | 10 ++++++++++ 2 files changed, 11 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +1 -0
@@ -88,6 +88,7 @@ struct mlx5_accel_esp_xfrm_attrs {enum mlx5_ipsec_cap {MLX5_IPSEC_CAP_CRYPTO =1 <<0 ,MLX5_IPSEC_CAP_ESN =1 <<1 , +MLX5_IPSEC_CAP_FULL_OFFLOAD =1 <<2 , };struct mlx5e_priv ;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +10 -0
@@ -1,12 +1,14 @@// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* Copyright (c) 2017, Mellanox Technologies inc. All rights reserved. */ +#include <linux/mlx5/eswitch.h> #include "mlx5_core.h" #include "ipsec.h" #include "lib/mlx5.h" u32 mlx5_ipsec_device_caps (struct mlx5_core_dev *mdev) { +bool esw_encap;u32 caps =0 ;if (!MLX5_CAP_GEN (mdev, ipsec_offload))
@@ -31,6 +33,14 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) MLX5_CAP_ETH(mdev, insert_trailer) && MLX5_CAP_ETH(mdev, swp)) caps |=MLX5_IPSEC_CAP_CRYPTO ; + esw_encap =mlx5_eswitch_get_encap_mode (mdev) != +DEVLINK_ESWITCH_ENCAP_MODE_NONE ; +if (!esw_encap &&MLX5_CAP_IPSEC (mdev, ipsec_full_offload) && +MLX5_CAP_FLOWTABLE_NIC_TX (mdev, reformat_add_esp_trasport) && +MLX5_CAP_FLOWTABLE_NIC_RX (mdev, reformat_del_esp_trasport) && +MLX5_CAP_FLOWTABLE_NIC_RX (mdev, decap)) + caps |=MLX5_IPSEC_CAP_FULL_OFFLOAD ; +if (!caps)return 0 ;
Signature · 1 line
2.37.2
PATCH 5/26 net/mlx5e: Store replay window in XFRM attributes
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
As a preparation for future extension of IPsec hardware object to allow configuration of full offload mode, extend the XFRM validator to check replay window values.
--- .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 12 ++++++++++++ .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h | 1 + 2 files changed, 13 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +12 -0
@@ -169,6 +169,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, attrs->esn = sa_entry->esn_state.esn;if (sa_entry->esn_state.overlap) attrs->flags |=MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP ; + attrs->replay_window = x->replay_esn->replay_window; }/* action */
@@ -260,6 +261,17 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)netdev_info (netdev,"Unsupported xfrm offload type\n" );return -EINVAL ; } +if (x->xso.type ==XFRM_DEV_OFFLOAD_FULL ) { +if (x->replay_esn && x->replay_esn->replay_window !=32 && + x->replay_esn->replay_window !=64 && + x->replay_esn->replay_window !=128 && + x->replay_esn->replay_window !=256 ) { +netdev_info (netdev, +"Unsupported replay window size %u\n" , + x->replay_esn->replay_window); +return -EINVAL ; + } + }return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +1 -0
@@ -83,6 +83,7 @@ struct mlx5_accel_esp_xfrm_attrs { } daddr;u8 is_ipv6; +u32 replay_window; };enum mlx5_ipsec_cap {
Signature · 1 line
2.37.2
PATCH 6/26 net/mlx5e: Remove extra layers of defines
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Instead of performing redefinition of XFRM core defines to same values but with MLX5_* prefix, cache the input values as is by making sure that the proper storage objects are used.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 17 ++++----------- .../mellanox/mlx5/core/en_accel/ipsec.h | 18 ++++------------ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 21 ++++++++++--------- .../mlx5/core/en_accel/ipsec_offload.c | 10 ++++----- 4 files changed, 23 insertions(+), 43 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +4 -13
@@ -165,29 +165,20 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,/* esn */ if (sa_entry->esn_state.trigger) { - attrs->flags |=MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED ; + attrs->esn_trigger = true; attrs->esn = sa_entry->esn_state.esn; -if (sa_entry->esn_state.overlap) - attrs->flags |=MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP ; + attrs->esn_overlap = sa_entry->esn_state.overlap; attrs->replay_window = x->replay_esn->replay_window; } -/* action */ - attrs->action = (x->xso.dir ==XFRM_DEV_OFFLOAD_OUT ) ? -MLX5_ACCEL_ESP_ACTION_ENCRYPT : -MLX5_ACCEL_ESP_ACTION_DECRYPT ; -/* flags */ - attrs->flags |= (x->props.mode ==XFRM_MODE_TRANSPORT ) ? -MLX5_ACCEL_ESP_FLAGS_TRANSPORT : -MLX5_ACCEL_ESP_FLAGS_TUNNEL ; - + attrs->dir = x->xso.dir;/* spi */ attrs->spi =be32_to_cpu (x->id.spi);/* source , destination ips */ memcpy (&attrs->saddr, x->props.saddr.a6,sizeof (attrs->saddr));memcpy (&attrs->daddr, x->id.daddr.a6,sizeof (attrs->daddr)); - attrs->is_ipv6 = (x->props.family !=AF_INET ); + attrs->family = x->props.family; }static inline int mlx5e_xfrm_validate_state (struct xfrm_state *x)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +4 -14
@@ -43,18 +43,6 @@#define MLX5E_IPSEC_SADB_RX_BITS 10#define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L -enum mlx5_accel_esp_flags { -MLX5_ACCEL_ESP_FLAGS_TUNNEL =0 ,/* Default */ -MLX5_ACCEL_ESP_FLAGS_TRANSPORT =1UL <<0 , -MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED =1UL <<1 , -MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP =1UL <<2 , -}; - -enum mlx5_accel_esp_action { -MLX5_ACCEL_ESP_ACTION_DECRYPT , -MLX5_ACCEL_ESP_ACTION_ENCRYPT , -}; -struct aes_gcm_keymat {u64 seq_iv;
@@ -66,7 +54,6 @@ struct aes_gcm_keymat { };struct mlx5_accel_esp_xfrm_attrs { -enum mlx5_accel_esp_action action;u32 esn;u32 spi;u32 flags;
@@ -82,7 +69,10 @@ struct mlx5_accel_esp_xfrm_attrs {__be32 a6[4 ]; } daddr; -u8 is_ipv6; + u8 dir : 2; + u8 esn_overlap : 1; + u8 esn_trigger : 1; +u8 family;u32 replay_window; };
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +11 -10
@@ -338,7 +338,7 @@ static void setup_fte_common(struct mlx5_accel_esp_xfrm_attrs *attrs,struct mlx5_flow_spec *spec, struct mlx5_flow_act *flow_act) { - u8 ip_version = attrs->is_ipv6 ? 6 : 4; + u8 ip_version = (attrs->family == AF_INET) ? 4 : 6; spec->match_criteria_enable =MLX5_MATCH_OUTER_HEADERS |MLX5_MATCH_MISC_PARAMETERS ;
@@ -407,7 +407,7 @@ static int rx_add_rule(struct mlx5e_priv *priv,int err =0 ; accel_esp = priv->ipsec->rx_fs; - type = attrs->is_ipv6 ?ACCEL_FS_ESP6 :ACCEL_FS_ESP4 ; + type = (attrs->family ==AF_INET ) ?ACCEL_FS_ESP4 :ACCEL_FS_ESP6 ; fs_prot = &accel_esp->fs_prot[type]; err =rx_ft_get (priv, type);
@@ -449,8 +449,8 @@ static int rx_add_rule(struct mlx5e_priv *priv, rule =mlx5_add_flow_rules (fs_prot->ft, spec, &flow_act, &dest,1 );if (IS_ERR (rule)) { err =PTR_ERR (rule); -netdev_err (priv->netdev,"fail to add ipsec rule attrs->action=0x%x, err=%d\n" , - attrs->action, err); +netdev_err (priv->netdev,"fail to add RX ipsec rule err=%d\n" , + err); goto out_err; }
@@ -501,8 +501,8 @@ static int tx_add_rule(struct mlx5e_priv *priv, rule =mlx5_add_flow_rules (priv->ipsec->tx_fs->ft, spec, &flow_act,NULL ,0 );if (IS_ERR (rule)) { err =PTR_ERR (rule); -netdev_err (priv->netdev,"fail to add ipsec rule attrs->action=0x%x, err=%d\n" , - sa_entry->attrs.action, err); +netdev_err (priv->netdev,"fail to add TX ipsec rule err=%d\n" , + err); goto out; }
@@ -518,7 +518,7 @@ static int tx_add_rule(struct mlx5e_priv *priv,int mlx5e_accel_ipsec_fs_add_rule (struct mlx5e_priv *priv,struct mlx5e_ipsec_sa_entry *sa_entry) { -if (sa_entry->attrs.action ==MLX5_ACCEL_ESP_ACTION_ENCRYPT ) +if (sa_entry->attrs.dir ==XFRM_DEV_OFFLOAD_OUT )return tx_add_rule (priv, sa_entry);return rx_add_rule (priv, sa_entry);
@@ -529,17 +529,18 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_priv *priv, {struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry); +enum accel_fs_esp_type type;mlx5_del_flow_rules (ipsec_rule->rule); -if (sa_entry->attrs.action ==MLX5_ACCEL_ESP_ACTION_ENCRYPT ) { +if (sa_entry->attrs.dir ==XFRM_DEV_OFFLOAD_OUT ) {tx_ft_put (priv);return ; }mlx5_modify_header_dealloc (mdev, ipsec_rule->set_modify_hdr); -rx_ft_put (priv, - sa_entry->attrs.is_ipv6 ?ACCEL_FS_ESP6 :ACCEL_FS_ESP4 ); + type = (sa_entry->attrs.family ==AF_INET ) ?ACCEL_FS_ESP4 :ACCEL_FS_ESP6 ; +rx_ft_put (priv, type); }void mlx5e_accel_ipsec_fs_cleanup (struct mlx5e_ipsec *ipsec)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +4 -6
@@ -76,11 +76,10 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry) salt_iv_p =MLX5_ADDR_OF (ipsec_obj, obj, implicit_iv);memcpy (salt_iv_p, &aes_gcm->seq_iv,sizeof (aes_gcm->seq_iv));/* esn */ -if (attrs->flags &MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED ) { +if (attrs->esn_trigger) {MLX5_SET (ipsec_obj, obj, esn_en,1 );MLX5_SET (ipsec_obj, obj, esn_msb, attrs->esn); -if (attrs->flags &MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP ) -MLX5_SET (ipsec_obj, obj, esn_overlap,1 ); +MLX5_SET (ipsec_obj, obj, esn_overlap, attrs->esn_overlap); }MLX5_SET (ipsec_obj, obj, dekn, sa_entry->enc_key_id);
@@ -162,7 +161,7 @@ static int mlx5_modify_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry,void *obj;int err; -if (!(attrs->flags &MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED )) +if (!attrs->esn_trigger)return 0 ; general_obj_types =MLX5_CAP_GEN_64 (mdev, general_obj_types);
@@ -193,8 +192,7 @@ static int mlx5_modify_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry,MLX5_MODIFY_IPSEC_BITMASK_ESN_OVERLAP | MLX5_MODIFY_IPSEC_BITMASK_ESN_MSB);MLX5_SET (ipsec_obj, obj, esn_msb, attrs->esn); -if (attrs->flags &MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP ) -MLX5_SET (ipsec_obj, obj, esn_overlap,1 ); +MLX5_SET (ipsec_obj, obj, esn_overlap, attrs->esn_overlap);/* general object fields set */ MLX5_SET (general_obj_in_cmd_hdr, in, opcode,MLX5_CMD_OP_MODIFY_GENERAL_OBJECT );
Signature · 1 line
2.37.2
PATCH 7/26 net/mlx5e: Create symmetric IPsec RX and TX flow steering structs
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Remove AF family obfuscation by creating symmetric structs for RX and TX IPsec flow steering chains. This simplifies to us low level IPsec FS creation logic without need to dig into multiple levels of structs.
--- .../mellanox/mlx5/core/en_accel/ipsec.h | 7 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 280 ++++++++---------- 2 files changed, 132 insertions(+), 155 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +4 -3
@@ -94,7 +94,7 @@ struct mlx5e_ipsec_sw_stats {atomic64_t ipsec_tx_drop_trailer; }; -struct mlx5e_accel_fs_esp ; +struct mlx5e_ipsec_rx ;struct mlx5e_ipsec_tx ;struct mlx5e_ipsec {
@@ -103,8 +103,9 @@ struct mlx5e_ipsec {spinlock_t sadb_rx_lock;/* Protects sadb_rx */ struct mlx5e_ipsec_sw_stats sw_stats;struct workqueue_struct *wq; -struct mlx5e_accel_fs_esp *rx_fs; -struct mlx5e_ipsec_tx *tx_fs; +struct mlx5e_ipsec_rx *rx_ipv4; +struct mlx5e_ipsec_rx *rx_ipv6; +struct mlx5e_ipsec_tx *tx; };struct mlx5e_ipsec_esn_state {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +128 -152
505 lines not on this page · raw message
Signature · 1 line
2.37.2
PATCH 8/26 net/mlx5e: Use mlx5 print routines for low level IPsec code
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Low level mlx5 code needs to use mlx5_core print routines and not netdev ones, as the failures are relevant to the HW itself and not to its netdev.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +14 -12
@@ -70,8 +70,8 @@ static int rx_err_add_rule(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx *rx,if (IS_ERR (modify_hdr)) { err =PTR_ERR (modify_hdr); -netdev_err (priv->netdev, -"fail to alloc ipsec copy modify_header_id err=%d\n" , err); +mlx5_core_err (mdev, +"fail to alloc ipsec copy modify_header_id err=%d\n" , err); goto out_spec; }
@@ -83,7 +83,7 @@ static int rx_err_add_rule(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx *rx, &rx->default_dest, 1);if (IS_ERR (fte)) { err =PTR_ERR (fte); -netdev_err (priv->netdev,"fail to add ipsec rx err copy rule err=%d\n" , err); +mlx5_core_err (mdev,"fail to add ipsec rx err copy rule err=%d\n" , err); goto out; }
@@ -103,6 +103,7 @@ static int rx_fs_create(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx *rx) {int inlen =MLX5_ST_SZ_BYTES (create_flow_group_in);struct mlx5_flow_table *ft = rx->ft.sa; +struct mlx5_core_dev *mdev = priv->mdev;struct mlx5_flow_group *miss_group;struct mlx5_flow_handle *miss_rule;MLX5_DECLARE_FLOW_ACT (flow_act);
@@ -123,7 +124,7 @@ static int rx_fs_create(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx *rx) miss_group =mlx5_create_flow_group (ft, flow_group_in);if (IS_ERR (miss_group)) { err =PTR_ERR (miss_group); -netdev_err (priv->netdev,"fail to create ipsec rx miss_group err=%d\n" , err); +mlx5_core_err (mdev,"fail to create ipsec rx miss_group err=%d\n" , err); goto out; } rx->miss_group = miss_group;
@@ -134,7 +135,7 @@ static int rx_fs_create(struct mlx5e_priv *priv, struct mlx5e_ipsec_rx *rx)if (IS_ERR (miss_rule)) {mlx5_destroy_flow_group (rx->miss_group); err =PTR_ERR (miss_rule); -netdev_err (priv->netdev,"fail to create ipsec rx miss_rule err=%d\n" , err); +mlx5_core_err (mdev,"fail to create ipsec rx miss_rule err=%d\n" , err); goto out; } rx->miss_rule = miss_rule;
@@ -270,6 +271,7 @@ static int tx_create(struct mlx5e_priv *priv) {struct mlx5_flow_table_attr ft_attr = {};struct mlx5e_ipsec *ipsec = priv->ipsec; +struct mlx5_core_dev *mdev = priv->mdev;struct mlx5_flow_table *ft;int err;
@@ -278,7 +280,7 @@ static int tx_create(struct mlx5e_priv *priv) ft =mlx5_create_auto_grouped_flow_table (ipsec->tx->ns, &ft_attr);if (IS_ERR (ft)) { err =PTR_ERR (ft); -netdev_err (priv->netdev,"fail to create ipsec tx ft err=%d\n" , err); +mlx5_core_err (mdev,"fail to create ipsec tx ft err=%d\n" , err);return err; } ipsec->tx->ft.sa = ft;
@@ -382,6 +384,7 @@ static int rx_add_rule(struct mlx5e_priv *priv,u8 action[MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto)] = {};struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; +struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry);u32 ipsec_obj_id = sa_entry->ipsec_obj_id;struct mlx5_modify_hdr *modify_hdr =NULL ;struct mlx5_flow_destination dest = {};
@@ -415,8 +418,8 @@ static int rx_add_rule(struct mlx5e_priv *priv, 1, action);if (IS_ERR (modify_hdr)) { err =PTR_ERR (modify_hdr); -netdev_err (priv->netdev, -"fail to alloc ipsec set modify_header_id err=%d\n" , err); +mlx5_core_err (mdev, +"fail to alloc ipsec set modify_header_id err=%d\n" , err); modify_hdr =NULL ; goto out_err; }
@@ -430,8 +433,7 @@ static int rx_add_rule(struct mlx5e_priv *priv, rule =mlx5_add_flow_rules (rx->ft.sa, spec, &flow_act, &dest,1 );if (IS_ERR (rule)) { err =PTR_ERR (rule); -netdev_err (priv->netdev,"fail to add RX ipsec rule err=%d\n" , - err); +mlx5_core_err (mdev,"fail to add RX ipsec rule err=%d\n" , err); goto out_err; }
@@ -452,6 +454,7 @@ static int rx_add_rule(struct mlx5e_priv *priv,static int tx_add_rule (struct mlx5e_priv *priv,struct mlx5e_ipsec_sa_entry *sa_entry) { +struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry);struct mlx5_flow_act flow_act = {};struct mlx5_flow_handle *rule;struct mlx5_flow_spec *spec;
@@ -483,8 +486,7 @@ static int tx_add_rule(struct mlx5e_priv *priv, rule =mlx5_add_flow_rules (tx->ft.sa, spec, &flow_act,NULL ,0 );if (IS_ERR (rule)) { err =PTR_ERR (rule); -netdev_err (priv->netdev,"fail to add TX ipsec rule err=%d\n" , - err); +mlx5_core_err (mdev,"fail to add TX ipsec rule err=%d\n" , err); goto out; }
Signature · 1 line
2.37.2
PATCH 9/26 net/mlx5e: Remove accesses to priv for low level IPsec FS code
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
mlx5 priv structure is driver main structure that holds high level data. That information is not needed for IPsec flow steering logic and the pointer to mlx5e_priv was not supposed to be passed in the first place.
This change "cleans" the logic to rely on internal to IPsec structures without touching global mlx5e_priv.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 8 +- .../mellanox/mlx5/core/en_accel/ipsec.h | 7 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 102 +++++++++--------- 3 files changed, 57 insertions(+), 60 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +4 -4
@@ -309,7 +309,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)if (err) goto err_xfrm; - err =mlx5e_accel_ipsec_fs_add_rule (priv, sa_entry); + err =mlx5e_accel_ipsec_fs_add_rule (sa_entry);if (err) goto err_hw_ctx;
@@ -327,7 +327,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x) goto out; err_add_rule: -mlx5e_accel_ipsec_fs_del_rule (priv, sa_entry); +mlx5e_accel_ipsec_fs_del_rule (sa_entry); err_hw_ctx:mlx5_ipsec_free_sa_ctx (sa_entry); err_xfrm:
@@ -347,10 +347,9 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)static void mlx5e_xfrm_free_state (struct xfrm_state *x) {struct mlx5e_ipsec_sa_entry *sa_entry =to_ipsec_sa_entry (x); -struct mlx5e_priv *priv =netdev_priv (x->xso.dev);cancel_work_sync (&sa_entry->modify_work.work); -mlx5e_accel_ipsec_fs_del_rule (priv, sa_entry); +mlx5e_accel_ipsec_fs_del_rule (sa_entry);mlx5_ipsec_free_sa_ctx (sa_entry);kfree (sa_entry); }
@@ -383,6 +382,7 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv)if (ret) goto err_fs_init; + ipsec->fs = priv->fs; priv->ipsec = ipsec;netdev_dbg (priv->netdev,"IPSec attached to netdevice\n" );return 0 ;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +3 -4
@@ -103,6 +103,7 @@ struct mlx5e_ipsec {spinlock_t sadb_rx_lock;/* Protects sadb_rx */ struct mlx5e_ipsec_sw_stats sw_stats;struct workqueue_struct *wq; +struct mlx5e_flow_steering *fs;struct mlx5e_ipsec_rx *rx_ipv4;struct mlx5e_ipsec_rx *rx_ipv6;struct mlx5e_ipsec_tx *tx;
@@ -148,10 +149,8 @@ struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup(struct mlx5e_ipsec *dev,void mlx5e_accel_ipsec_fs_cleanup (struct mlx5e_ipsec *ipsec);int mlx5e_accel_ipsec_fs_init (struct mlx5e_ipsec *ipsec); -int mlx5e_accel_ipsec_fs_add_rule (struct mlx5e_priv *priv, -struct mlx5e_ipsec_sa_entry *sa_entry); -void mlx5e_accel_ipsec_fs_del_rule (struct mlx5e_priv *priv, -struct mlx5e_ipsec_sa_entry *sa_entry); +int mlx5e_accel_ipsec_fs_add_rule (struct mlx5e_ipsec_sa_entry *sa_entry); +void mlx5e_accel_ipsec_fs_del_rule (struct mlx5e_ipsec_sa_entry *sa_entry);int mlx5_ipsec_create_sa_ctx (struct mlx5e_ipsec_sa_entry *sa_entry);void mlx5_ipsec_free_sa_ctx (struct mlx5e_ipsec_sa_entry *sa_entry);
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +50 -52
313 lines not on this page · raw message
Signature · 1 line
2.37.2
PATCH 10/26 net/mlx5e: Validate that IPsec full offload can handle packets
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Add specific to IPsec full offload check to drop packets that are larger than MTU and such are going to be fragmented.
--- .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +13 -0
@@ -409,6 +409,8 @@ void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv)static bool mlx5e_ipsec_offload_ok (struct sk_buff *skb,struct xfrm_state *x) { +struct net_device *netdev = x->xso.real_dev; +if (x->props.family ==AF_INET ) {/* Offload with IPv4 options is not supported yet */ if (ip_hdr (skb)->ihl >5 )
@@ -419,6 +421,17 @@ static bool mlx5e_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *x)return false; } +if (x->xso.type ==XFRM_DEV_OFFLOAD_FULL ) { +/* Fragmented packets */ +if (skb_is_gso (skb)) { +if (!skb_gso_validate_network_len (skb, netdev->mtu)) +return false; + }else { +if (skb->len > netdev->mtu) +return false; + } + } +return true; }
Signature · 1 line
2.37.2
PATCH 11/26 net/mlx5e: Create Advanced Steering Operation object for IPsec
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Setup the ASO (Advanced Steering Operation) object that is needed for IPsec to interact with SW stack about various fast changing
events: replay window, lifetime limits, e.t.c
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 11 +++++++ .../mellanox/mlx5/core/en_accel/ipsec.h | 6 ++++ .../mlx5/core/en_accel/ipsec_offload.c | 30 +++++++++++++++++++ 3 files changed, 47 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +11 -0
@@ -378,6 +378,12 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv) goto err_wq; } +if (mlx5_ipsec_device_caps (priv->mdev) &MLX5_IPSEC_CAP_FULL_OFFLOAD ) { + ret =mlx5e_ipsec_aso_init (ipsec); +if (ret) + goto err_aso; + } + ret =mlx5e_accel_ipsec_fs_init (ipsec);if (ret) goto err_fs_init;
@@ -388,6 +394,9 @@ int mlx5e_ipsec_init(struct mlx5e_priv *priv)return 0 ; err_fs_init: +if (mlx5_ipsec_device_caps (priv->mdev) &MLX5_IPSEC_CAP_FULL_OFFLOAD ) +mlx5e_ipsec_aso_cleanup (ipsec); +err_aso:destroy_workqueue (ipsec->wq); err_wq:kfree (ipsec);
@@ -402,6 +411,8 @@ void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv)return ;mlx5e_accel_ipsec_fs_cleanup (ipsec); +if (mlx5_ipsec_device_caps (priv->mdev) &MLX5_IPSEC_CAP_FULL_OFFLOAD ) +mlx5e_ipsec_aso_cleanup (ipsec);destroy_workqueue (ipsec->wq);kfree (ipsec); priv->ipsec =NULL ;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +6 -0
@@ -39,6 +39,7 @@#include <linux/mlx5/device.h> #include <net/xfrm.h> #include <linux/idr.h> +#include "lib/aso.h" #define MLX5E_IPSEC_SADB_RX_BITS 10#define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L
@@ -107,6 +108,8 @@ struct mlx5e_ipsec {struct mlx5e_ipsec_rx *rx_ipv4;struct mlx5e_ipsec_rx *rx_ipv6;struct mlx5e_ipsec_tx *tx; +struct mlx5_aso *aso; +u32 pdn; };struct mlx5e_ipsec_esn_state {
@@ -160,6 +163,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev);void mlx5_accel_esp_modify_xfrm (struct mlx5e_ipsec_sa_entry *sa_entry,const struct mlx5_accel_esp_xfrm_attrs *attrs); +int mlx5e_ipsec_aso_init (struct mlx5e_ipsec *ipsec); +void mlx5e_ipsec_aso_cleanup (struct mlx5e_ipsec *ipsec); +static inline struct mlx5_core_dev *mlx5e_ipsec_sa2dev (struct mlx5e_ipsec_sa_entry *sa_entry) {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +30 -0
@@ -211,3 +211,33 @@ void mlx5_accel_esp_modify_xfrm(struct mlx5e_ipsec_sa_entry *sa_entry,memcpy (&sa_entry->attrs, attrs,sizeof (sa_entry->attrs)); } + +int mlx5e_ipsec_aso_init (struct mlx5e_ipsec *ipsec) +{ +struct mlx5_core_dev *mdev = ipsec->mdev; +int err; + + err =mlx5_core_alloc_pd (mdev, &ipsec->pdn); +if (err) +return err; + + ipsec->aso =mlx5_aso_create (mdev, ipsec->pdn); +if (IS_ERR (ipsec->aso)) { + err =PTR_ERR (ipsec->aso); + goto err_aso_create; + } + +return 0 ; + +err_aso_create: +mlx5_core_dealloc_pd (mdev, ipsec->pdn); +return err; +} + +void mlx5e_ipsec_aso_cleanup (struct mlx5e_ipsec *ipsec) +{ +struct mlx5_core_dev *mdev = ipsec->mdev; + +mlx5_aso_destroy (ipsec->aso); +mlx5_core_dealloc_pd (mdev, ipsec->pdn); +}
Signature · 1 line
2.37.2
PATCH 12/26 net/mlx5e: Create hardware IPsec full offload objects
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Create initial hardware IPsec full offload object and connect it to advanced steering operation (ASO) context and queue, so the data path can communicate with the stack.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 1 + .../mellanox/mlx5/core/en_accel/ipsec.h | 1 + .../mlx5/core/en_accel/ipsec_offload.c | 31 ++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +1 -0
@@ -179,6 +179,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,memcpy (&attrs->saddr, x->props.saddr.a6,sizeof (attrs->saddr));memcpy (&attrs->daddr, x->id.daddr.a6,sizeof (attrs->daddr)); attrs->family = x->props.family; + attrs->type = x->xso.type; }static inline int mlx5e_xfrm_validate_state (struct xfrm_state *x)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +1 -0
@@ -73,6 +73,7 @@ struct mlx5_accel_esp_xfrm_attrs { u8 dir : 2; u8 esn_overlap : 1; u8 esn_trigger : 1; + u8 type : 2;u8 family;u32 replay_window; };
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +30 -1
@@ -63,10 +63,12 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)struct aes_gcm_keymat *aes_gcm = &attrs->aes_gcm;u32 out[MLX5_ST_SZ_DW (general_obj_out_cmd_hdr)];u32 in[MLX5_ST_SZ_DW (create_ipsec_obj_in)] = {}; -void *obj, *salt_p, *salt_iv_p; +void *obj, *salt_p, *salt_iv_p, *aso_ctx; +u32 pdn = sa_entry->ipsec->pdn;int err; obj =MLX5_ADDR_OF (create_ipsec_obj_in, in, ipsec_object); + aso_ctx =MLX5_ADDR_OF (ipsec_obj, obj, ipsec_aso);/* salt and seq_iv */ salt_p =MLX5_ADDR_OF (ipsec_obj, obj, salt);
@@ -80,6 +82,17 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)MLX5_SET (ipsec_obj, obj, esn_en,1 );MLX5_SET (ipsec_obj, obj, esn_msb, attrs->esn);MLX5_SET (ipsec_obj, obj, esn_overlap, attrs->esn_overlap); + +if (attrs->type ==XFRM_DEV_OFFLOAD_FULL ) { +MLX5_SET (ipsec_aso, aso_ctx, esn_event_arm,1 ); + +if (attrs->dir ==XFRM_DEV_OFFLOAD_IN ) { +MLX5_SET (ipsec_aso, aso_ctx, window_sz, + attrs->replay_window /64 ); +MLX5_SET (ipsec_aso, aso_ctx, mode, +MLX5_IPSEC_ASO_REPLAY_PROTECTION ); + } + } }MLX5_SET (ipsec_obj, obj, dekn, sa_entry->enc_key_id);
@@ -90,6 +103,22 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)MLX5_SET (general_obj_in_cmd_hdr, in, obj_type,MLX5_GENERAL_OBJECT_TYPES_IPSEC ); +/* ASO context */ +if (attrs->type ==XFRM_DEV_OFFLOAD_FULL ) { +MLX5_SET (ipsec_obj, obj, ipsec_aso_access_pd, pdn); +MLX5_SET (ipsec_obj, obj, full_offload,1 ); +MLX5_SET (ipsec_aso, aso_ctx, valid,1 ); +/* MLX5_IPSEC_ASO_REG_C_4_5 is type C register that is used +* in flow steering to perform matching against. Please be +* aware that this register was chosen arbitrary and can't +* be used in other places as long as IPsec full offload +* active. +*/ +MLX5_SET (ipsec_obj, obj, aso_return_reg,MLX5_IPSEC_ASO_REG_C_4_5 ); +if (attrs->dir ==XFRM_DEV_OFFLOAD_OUT ) +MLX5_SET (ipsec_aso, aso_ctx, mode,MLX5_IPSEC_ASO_INC_SN ); + } + err =mlx5_cmd_exec (mdev, in,sizeof (in), out,sizeof (out));if (!err) sa_entry->ipsec_obj_id =
Signature · 1 line
2.37.2
PATCH 13/26 net/mlx5e: Move IPsec flow table creation to separate function
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Even now, to support IPsec crypto, the RX and TX paths use same logic to create flow tables. In the following patches, we will add more tables to support IPsec full offload. So reuse existing code and rewrite it to support IPsec full offload from the beginning.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +31 -22
@@ -42,6 +42,28 @@ static enum mlx5_traffic_types family2tt(u32 family)return MLX5_TT_IPV6_IPSEC_ESP ; } +static struct mlx5_flow_table *ipsec_ft_create (struct mlx5_core_dev *mdev, +struct mlx5_flow_namespace *ns, +int level,int prio, +int max_num_groups,u8 dir) +{ +struct mlx5_flow_table_attr ft_attr = {}; + + ft_attr.autogroup.num_reserved_entries =1 ; + ft_attr.autogroup.max_num_groups = max_num_groups; + ft_attr.max_fte =NUM_IPSEC_FTE ; + ft_attr.level = level; + ft_attr.prio = prio; +if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_FULL_OFFLOAD ) { + ft_attr.flags =MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT ; + +if (dir ==XFRM_DEV_OFFLOAD_IN ) + ft_attr.flags |=MLX5_FLOW_TABLE_TUNNEL_EN_DECAP ; + } + +return mlx5_create_auto_grouped_flow_table (ns, &ft_attr); +} +static int rx_err_add_rule (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_rx *rx,struct mlx5e_ipsec_rx_err *rx_err)
@@ -158,18 +180,15 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)static int rx_create (struct mlx5_core_dev *mdev,struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx,u32 family) { -struct mlx5_flow_table_attr ft_attr = {};struct mlx5_flow_table *ft;int err; rx->default_dest =mlx5_ttc_get_default_dest (ipsec->fs->ttc,family2tt (family)); - ft_attr.max_fte =1 ; - ft_attr.autogroup.max_num_groups =1 ; - ft_attr.level =MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL ; - ft_attr.prio =MLX5E_NIC_PRIO ; - ft =mlx5_create_auto_grouped_flow_table (ipsec->fs->ns, &ft_attr); + ft =ipsec_ft_create (mdev, ipsec->fs->ns, +MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL ,MLX5E_NIC_PRIO ,1 , +XFRM_DEV_OFFLOAD_IN );if (IS_ERR (ft))return PTR_ERR (ft);
@@ -179,12 +198,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec, goto err_add;/* Create FT */ - ft_attr.max_fte =NUM_IPSEC_FTE ; - ft_attr.level =MLX5E_ACCEL_FS_ESP_FT_LEVEL ; - ft_attr.prio =MLX5E_NIC_PRIO ; - ft_attr.autogroup.num_reserved_entries =1 ; - ft_attr.autogroup.max_num_groups =1 ; - ft =mlx5_create_auto_grouped_flow_table (ipsec->fs->ns, &ft_attr); + ft =ipsec_ft_create (mdev, ipsec->fs->ns,MLX5E_ACCEL_FS_ESP_FT_LEVEL , +MLX5E_NIC_PRIO ,1 ,XFRM_DEV_OFFLOAD_IN );if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_fs_ft;
@@ -270,18 +285,12 @@ static void rx_ft_put(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,/* IPsec TX flow steering */ static int tx_create (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_tx *tx) { -struct mlx5_flow_table_attr ft_attr = {};struct mlx5_flow_table *ft; -int err; - ft_attr.max_fte =NUM_IPSEC_FTE ; - ft_attr.autogroup.max_num_groups =1 ; - ft =mlx5_create_auto_grouped_flow_table (tx->ns, &ft_attr); -if (IS_ERR (ft)) { - err =PTR_ERR (ft); -mlx5_core_err (mdev,"fail to create ipsec tx ft err=%d\n" , err); -return err; - } + ft =ipsec_ft_create (mdev, tx->ns,0 ,0 ,1 ,XFRM_DEV_OFFLOAD_OUT ); +if (IS_ERR (ft)) +return PTR_ERR (ft); + tx->ft.sa = ft;return 0 ; }
Signature · 1 line
2.37.2
PATCH 14/26 net/mlx5e: Refactor FTE setup code to be more clear
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
The policy offload logic needs to set flow steering rule that match on saddr and daddr too, so factor out this code to separate functions, together with code alignment to netdev coding pattern of relying on family type.
As part of this change, let's separate more logic from setup_fte_common to make sure that the function names describe that is done in the function better than general *common* name.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 136 +++++++++++------- 1 file changed, 83 insertions(+), 53 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +83 -53
@@ -331,60 +331,78 @@ static void tx_ft_put(struct mlx5e_ipsec *ipsec)mutex_unlock (&tx->ft.mutex); } -static void setup_fte_common (struct mlx5_accel_esp_xfrm_attrs *attrs, -u32 ipsec_obj_id, -struct mlx5_flow_spec *spec, -struct mlx5_flow_act *flow_act) +static void setup_fte_addr4 (struct mlx5_flow_spec *spec,__be32 *saddr, +__be32 *daddr) { -u8 ip_version = (attrs->family ==AF_INET ) ?4 :6 ; + spec->match_criteria_enable |=MLX5_MATCH_OUTER_HEADERS ; - spec->match_criteria_enable =MLX5_MATCH_OUTER_HEADERS |MLX5_MATCH_MISC_PARAMETERS ; - -/* ip_version */ MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, outer_headers.ip_version); -MLX5_SET (fte_match_param, spec->match_value, outer_headers.ip_version, ip_version); +MLX5_SET (fte_match_param, spec->match_value, outer_headers.ip_version,4 ); + +memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, + outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4), saddr,4 ); +memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, + outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4), daddr,4 ); +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, + outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4); +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, + outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4); +} -/* Non fragmented */ -MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, outer_headers.frag); -MLX5_SET (fte_match_param, spec->match_value, outer_headers.frag,0 ); +static void setup_fte_addr6 (struct mlx5_flow_spec *spec,__be32 *saddr, +__be32 *daddr) +{ + spec->match_criteria_enable |=MLX5_MATCH_OUTER_HEADERS ; + +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, outer_headers.ip_version); +MLX5_SET (fte_match_param, spec->match_value, outer_headers.ip_version,6 ); + +memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, + outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), saddr,16 ); +memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, + outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), daddr,16 ); +memset (MLX5_ADDR_OF (fte_match_param, spec->match_criteria, + outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6),0xff ,16 ); +memset (MLX5_ADDR_OF (fte_match_param, spec->match_criteria, + outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6),0xff ,16 ); +} +static void setup_fte_esp (struct mlx5_flow_spec *spec) +{/* ESP header */ + spec->match_criteria_enable |=MLX5_MATCH_MISC_PARAMETERS ; +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, outer_headers.ip_protocol);MLX5_SET (fte_match_param, spec->match_value, outer_headers.ip_protocol,IPPROTO_ESP ); +} +static void setup_fte_spi (struct mlx5_flow_spec *spec,u32 spi) +{/* SPI number */ + spec->match_criteria_enable |=MLX5_MATCH_MISC_PARAMETERS ; +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, misc_parameters.outer_esp_spi); -MLX5_SET (fte_match_param, spec->match_value, - misc_parameters.outer_esp_spi, attrs->spi); - -if (ip_version ==4 ) { -memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, - outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4), - &attrs->saddr.a4,4 ); -memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, - outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4), - &attrs->daddr.a4,4 ); -MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, - outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4); -MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, - outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4); - }else { -memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, - outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), - &attrs->saddr.a6,16 ); -memcpy (MLX5_ADDR_OF (fte_match_param, spec->match_value, - outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), - &attrs->daddr.a6,16 ); -memset (MLX5_ADDR_OF (fte_match_param, spec->match_criteria, - outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), -0xff ,16 ); -memset (MLX5_ADDR_OF (fte_match_param, spec->match_criteria, - outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), -0xff ,16 ); - } +MLX5_SET (fte_match_param, spec->match_value, misc_parameters.outer_esp_spi, spi); +} - flow_act->ipsec_obj_id = ipsec_obj_id; - flow_act->flags |=FLOW_ACT_NO_APPEND ; +static void setup_fte_no_frags (struct mlx5_flow_spec *spec) +{ +/* Non fragmented */ + spec->match_criteria_enable |=MLX5_MATCH_OUTER_HEADERS ; + +MLX5_SET_TO_ONES (fte_match_param, spec->match_criteria, outer_headers.frag); +MLX5_SET (fte_match_param, spec->match_value, outer_headers.frag,0 ); +} + +static void setup_fte_reg_a (struct mlx5_flow_spec *spec) +{ +/* Add IPsec indicator in metadata_reg_a */ + spec->match_criteria_enable |=MLX5_MATCH_MISC_PARAMETERS_2 ; + +MLX5_SET (fte_match_param, spec->match_criteria, + misc_parameters_2.metadata_reg_a,MLX5_ETH_WQE_FT_META_IPSEC ); +MLX5_SET (fte_match_param, spec->match_value, + misc_parameters_2.metadata_reg_a,MLX5_ETH_WQE_FT_META_IPSEC ); }static int rx_add_rule (struct mlx5e_ipsec_sa_entry *sa_entry)
@@ -394,7 +412,6 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry);struct mlx5e_ipsec *ipsec = sa_entry->ipsec; -u32 ipsec_obj_id = sa_entry->ipsec_obj_id;struct mlx5_modify_hdr *modify_hdr =NULL ;struct mlx5_flow_destination dest = {};struct mlx5_flow_act flow_act = {};
@@ -413,13 +430,21 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) goto out_err; } -setup_fte_common (attrs, ipsec_obj_id, spec, &flow_act); +if (attrs->family ==AF_INET ) +setup_fte_addr4 (spec, &attrs->saddr.a4, &attrs->daddr.a4); +else +setup_fte_addr6 (spec, attrs->saddr.a6, attrs->daddr.a6); + +setup_fte_spi (spec, attrs->spi); +setup_fte_esp (spec); +setup_fte_no_frags (spec);/* Set bit[31] ipsec marker */ /* Set bit[23-0] ipsec_obj_id */ MLX5_SET (set_action_in, action, action_type,MLX5_ACTION_TYPE_SET );MLX5_SET (set_action_in, action, field,MLX5_ACTION_IN_FIELD_METADATA_REG_B ); -MLX5_SET (set_action_in, action, data, (ipsec_obj_id |BIT (31 ))); +MLX5_SET (set_action_in, action, data, + (sa_entry->ipsec_obj_id |BIT (31 )));MLX5_SET (set_action_in, action, offset,0 );MLX5_SET (set_action_in, action, length,32 );
@@ -433,6 +458,8 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) goto out_err; } + flow_act.ipsec_obj_id = sa_entry->ipsec_obj_id; + flow_act.flags |=FLOW_ACT_NO_APPEND ; flow_act.action =MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |MLX5_FLOW_CONTEXT_ACTION_IPSEC_DECRYPT |MLX5_FLOW_CONTEXT_ACTION_MOD_HDR ;
@@ -462,6 +489,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)static int tx_add_rule (struct mlx5e_ipsec_sa_entry *sa_entry) { +struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry);struct mlx5e_ipsec *ipsec = sa_entry->ipsec;struct mlx5_flow_act flow_act = {};
@@ -480,16 +508,18 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) goto out; } -setup_fte_common (&sa_entry->attrs, sa_entry->ipsec_obj_id, spec, - &flow_act); +if (attrs->family ==AF_INET ) +setup_fte_addr4 (spec, &attrs->saddr.a4, &attrs->daddr.a4); +else +setup_fte_addr6 (spec, attrs->saddr.a6, attrs->daddr.a6); -/* Add IPsec indicator in metadata_reg_a */ - spec->match_criteria_enable |=MLX5_MATCH_MISC_PARAMETERS_2 ; -MLX5_SET (fte_match_param, spec->match_criteria, misc_parameters_2.metadata_reg_a, -MLX5_ETH_WQE_FT_META_IPSEC ); -MLX5_SET (fte_match_param, spec->match_value, misc_parameters_2.metadata_reg_a, -MLX5_ETH_WQE_FT_META_IPSEC ); +setup_fte_spi (spec, attrs->spi); +setup_fte_esp (spec); +setup_fte_no_frags (spec); +setup_fte_reg_a (spec); + flow_act.ipsec_obj_id = sa_entry->ipsec_obj_id; + flow_act.flags |=FLOW_ACT_NO_APPEND ; flow_act.action =MLX5_FLOW_CONTEXT_ACTION_ALLOW |MLX5_FLOW_CONTEXT_ACTION_IPSEC_ENCRYPT ; rule =mlx5_add_flow_rules (tx->ft.sa, spec, &flow_act,NULL ,0 );
Signature · 1 line
2.37.2
PATCH 15/26 net/mlx5e: Flatten the IPsec RX add rule path
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Rewrote the IPsec RX add rule path to be less convoluted and don't rely on pre-initialized variables. The code now has clean linear flow with clean separation between error and success paths.
--- .../mellanox/mlx5/core/en_accel/ipsec.h | 2 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 88 +++++++++++-------- 2 files changed, 53 insertions(+), 37 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +1 -1
@@ -121,7 +121,7 @@ struct mlx5e_ipsec_esn_state {struct mlx5e_ipsec_rule {struct mlx5_flow_handle *rule; -struct mlx5_modify_hdr *set_modify_hdr; +struct mlx5_modify_hdr *modify_hdr; };struct mlx5e_ipsec_modify_state_work {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +52 -36
137 lines not on this page · raw message
Signature · 1 line
2.37.2
PATCH 16/26 net/mlx5e: Make clear what IPsec rx_err does
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Reuse existing struct what holds all information about modify header pointer and rule. This helps to reduce ambiguity from the name _err_ that doesn't describe the real purpose of that flow table, rule and function - to copy status result from HW to the stack.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +16 -22
@@ -9,15 +9,10 @@#define NUM_IPSEC_FTE BIT(15) -struct mlx5e_ipsec_rx_err { -struct mlx5_flow_table *ft; -struct mlx5_flow_handle *rule; -struct mlx5_modify_hdr *copy_modify_hdr; -}; -struct mlx5e_ipsec_ft {struct mutex mutex;/* Protect changes to this struct */ struct mlx5_flow_table *sa; +struct mlx5_flow_table *status;u32 refcnt; };
@@ -26,7 +21,7 @@ struct mlx5e_ipsec_rx {struct mlx5_flow_group *miss_group;struct mlx5_flow_handle *miss_rule;struct mlx5_flow_destination default_dest; -struct mlx5e_ipsec_rx_err rx_err; +struct mlx5e_ipsec_rule status; };struct mlx5e_ipsec_tx {
@@ -64,9 +59,8 @@ static struct mlx5_flow_table *ipsec_ft_create(struct mlx5_core_dev *mdev,return mlx5_create_auto_grouped_flow_table (ns, &ft_attr); } -static int rx_err_add_rule (struct mlx5_core_dev *mdev, -struct mlx5e_ipsec_rx *rx, -struct mlx5e_ipsec_rx_err *rx_err) +static int ipsec_status_rule (struct mlx5_core_dev *mdev, +struct mlx5e_ipsec_rx *rx) {u8 action[MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto)] = {};struct mlx5_flow_act flow_act = {};
@@ -101,7 +95,7 @@ static int rx_err_add_rule(struct mlx5_core_dev *mdev, flow_act.action =MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ; flow_act.modify_hdr = modify_hdr; - fte =mlx5_add_flow_rules (rx_err->ft, spec, &flow_act, + fte =mlx5_add_flow_rules (rx->ft.status, spec, &flow_act, &rx->default_dest,1 );if (IS_ERR (fte)) { err =PTR_ERR (fte);
@@ -110,8 +104,8 @@ static int rx_err_add_rule(struct mlx5_core_dev *mdev, }kvfree (spec); - rx_err->rule = fte; - rx_err->copy_modify_hdr = modify_hdr; + rx->status.rule = fte; + rx->status.modify_hdr = modify_hdr;return 0 ; out:
@@ -172,9 +166,9 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)mlx5_destroy_flow_group (rx->miss_group);mlx5_destroy_flow_table (rx->ft.sa); -mlx5_del_flow_rules (rx->rx_err.rule); -mlx5_modify_header_dealloc (mdev, rx->rx_err.copy_modify_hdr); -mlx5_destroy_flow_table (rx->rx_err.ft); +mlx5_del_flow_rules (rx->status.rule); +mlx5_modify_header_dealloc (mdev, rx->status.modify_hdr); +mlx5_destroy_flow_table (rx->ft.status); } static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
@@ -192,8 +186,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,if (IS_ERR (ft))return PTR_ERR (ft); - rx->rx_err.ft = ft; - err =rx_err_add_rule (mdev, rx, &rx->rx_err); + rx->ft.status = ft; + err =ipsec_status_rule (mdev, rx);if (err) goto err_add;
@@ -215,10 +209,10 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec, err_fs:mlx5_destroy_flow_table (rx->ft.sa); err_fs_ft: -mlx5_del_flow_rules (rx->rx_err.rule); -mlx5_modify_header_dealloc (mdev, rx->rx_err.copy_modify_hdr); +mlx5_del_flow_rules (rx->status.rule); +mlx5_modify_header_dealloc (mdev, rx->status.modify_hdr); err_add: -mlx5_destroy_flow_table (rx->rx_err.ft); +mlx5_destroy_flow_table (rx->ft.status);return err; }
@@ -481,7 +475,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |MLX5_FLOW_CONTEXT_ACTION_IPSEC_DECRYPT ; dest.type =MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ; - dest.ft = rx->rx_err.ft; + dest.ft = rx->ft.status; rule =mlx5_add_flow_rules (rx->ft.sa, spec, &flow_act, &dest,1 );if (IS_ERR (rule)) { err =PTR_ERR (rule);
Signature · 1 line
2.37.2
PATCH 17/26 net/mlx5e: Group IPsec miss handles into separate struct
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Move miss handles into dedicated struct, so we can reuse it in next patch when creating IPsec policy flow table.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +11 -7
@@ -16,10 +16,14 @@ struct mlx5e_ipsec_ft {u32 refcnt; }; +struct mlx5e_ipsec_miss { +struct mlx5_flow_group *group; +struct mlx5_flow_handle *rule; +}; +struct mlx5e_ipsec_rx {struct mlx5e_ipsec_ft ft; -struct mlx5_flow_group *miss_group; -struct mlx5_flow_handle *miss_rule; +struct mlx5e_ipsec_miss sa;struct mlx5_flow_destination default_dest;struct mlx5e_ipsec_rule status; };
@@ -142,18 +146,18 @@ static int rx_fs_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)mlx5_core_err (mdev,"fail to create ipsec rx miss_group err=%d\n" , err); goto out; } - rx->miss_group = miss_group; + rx->sa.group = miss_group;/* Create miss rule */ miss_rule =mlx5_add_flow_rules (ft, spec, &flow_act, &rx->default_dest,1 );if (IS_ERR (miss_rule)) { -mlx5_destroy_flow_group (rx->miss_group); +mlx5_destroy_flow_group (rx->sa.group); err =PTR_ERR (miss_rule);mlx5_core_err (mdev,"fail to create ipsec rx miss_rule err=%d\n" , err); goto out; } - rx->miss_rule = miss_rule; + rx->sa.rule = miss_rule; out:kvfree (flow_group_in);kvfree (spec);
@@ -162,8 +166,8 @@ static int rx_fs_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)static void rx_destroy (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_rx *rx) { -mlx5_del_flow_rules (rx->miss_rule); -mlx5_destroy_flow_group (rx->miss_group); +mlx5_del_flow_rules (rx->sa.rule); +mlx5_destroy_flow_group (rx->sa.group);mlx5_destroy_flow_table (rx->ft.sa);mlx5_del_flow_rules (rx->status.rule);
Signature · 1 line
2.37.2
PATCH 18/26 net/mlx5e: Generalize creation of default IPsec miss group and rule
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Create general function that sets miss group and rule to forward all not-matched traffic to the next table.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +23 -25
@@ -24,7 +24,6 @@ struct mlx5e_ipsec_miss {struct mlx5e_ipsec_rx {struct mlx5e_ipsec_ft ft;struct mlx5e_ipsec_miss sa; -struct mlx5_flow_destination default_dest;struct mlx5e_ipsec_rule status; };
@@ -64,7 +63,8 @@ static struct mlx5_flow_table *ipsec_ft_create(struct mlx5_core_dev *mdev, }static int ipsec_status_rule (struct mlx5_core_dev *mdev, -struct mlx5e_ipsec_rx *rx) +struct mlx5e_ipsec_rx *rx, +struct mlx5_flow_destination *dest) {u8 action[MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto)] = {};struct mlx5_flow_act flow_act = {};
@@ -99,8 +99,7 @@ static int ipsec_status_rule(struct mlx5_core_dev *mdev, flow_act.action =MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ; flow_act.modify_hdr = modify_hdr; - fte =mlx5_add_flow_rules (rx->ft.status, spec, &flow_act, - &rx->default_dest,1 ); + fte =mlx5_add_flow_rules (rx->ft.status, spec, &flow_act, dest,1 );if (IS_ERR (fte)) { err =PTR_ERR (fte);mlx5_core_err (mdev,"fail to add ipsec rx err copy rule err=%d\n" , err);
@@ -119,12 +118,12 @@ static int ipsec_status_rule(struct mlx5_core_dev *mdev,return err; } -static int rx_fs_create (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_rx *rx) +static int ipsec_miss_create (struct mlx5_core_dev *mdev, +struct mlx5_flow_table *ft, +struct mlx5e_ipsec_miss *miss, +struct mlx5_flow_destination *dest) {int inlen =MLX5_ST_SZ_BYTES (create_flow_group_in); -struct mlx5_flow_table *ft = rx->ft.sa; -struct mlx5_flow_group *miss_group; -struct mlx5_flow_handle *miss_rule;MLX5_DECLARE_FLOW_ACT (flow_act);struct mlx5_flow_spec *spec;u32 *flow_group_in;
@@ -140,24 +139,23 @@ static int rx_fs_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)/* Create miss_group */ MLX5_SET (create_flow_group_in, flow_group_in, start_flow_index, ft->max_fte -1 );MLX5_SET (create_flow_group_in, flow_group_in, end_flow_index, ft->max_fte -1 ); - miss_group =mlx5_create_flow_group (ft, flow_group_in); -if (IS_ERR (miss_group)) { - err =PTR_ERR (miss_group); -mlx5_core_err (mdev,"fail to create ipsec rx miss_group err=%d\n" , err); + miss->group =mlx5_create_flow_group (ft, flow_group_in); +if (IS_ERR (miss->group)) { + err =PTR_ERR (miss->group); +mlx5_core_err (mdev,"fail to create IPsec miss_group err=%d\n" , + err); goto out; } - rx->sa.group = miss_group;/* Create miss rule */ - miss_rule = -mlx5_add_flow_rules (ft, spec, &flow_act, &rx->default_dest,1 ); -if (IS_ERR (miss_rule)) { -mlx5_destroy_flow_group (rx->sa.group); - err =PTR_ERR (miss_rule); -mlx5_core_err (mdev,"fail to create ipsec rx miss_rule err=%d\n" , err); + miss->rule =mlx5_add_flow_rules (ft, spec, &flow_act, dest,1 ); +if (IS_ERR (miss->rule)) { +mlx5_destroy_flow_group (miss->group); + err =PTR_ERR (miss->rule); +mlx5_core_err (mdev,"fail to create IPsec miss_rule err=%d\n" , + err); goto out; } - rx->sa.rule = miss_rule; out:kvfree (flow_group_in);kvfree (spec);
@@ -178,12 +176,10 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_rx *rx)static int rx_create (struct mlx5_core_dev *mdev,struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx,u32 family) { +struct mlx5_flow_destination dest;struct mlx5_flow_table *ft;int err; - rx->default_dest = -mlx5_ttc_get_default_dest (ipsec->fs->ttc,family2tt (family)); - ft =ipsec_ft_create (mdev, ipsec->fs->ns,MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL ,MLX5E_NIC_PRIO ,1 ,XFRM_DEV_OFFLOAD_IN );
@@ -191,7 +187,9 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,return PTR_ERR (ft); rx->ft.status = ft; - err =ipsec_status_rule (mdev, rx); + + dest =mlx5_ttc_get_default_dest (ipsec->fs->ttc,family2tt (family)); + err =ipsec_status_rule (mdev, rx, &dest);if (err) goto err_add;
@@ -204,7 +202,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec, } rx->ft.sa = ft; - err =rx_fs_create (mdev, rx); + err =ipsec_miss_create (mdev, rx->ft.sa, &rx->sa, &dest);if (err) goto err_fs;
Signature · 1 line
2.37.2
PATCH 19/26 net/mlx5e: Create IPsec policy offload tables
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Add empty table to be used for IPsec policy offload.
--- .../net/ethernet/mellanox/mlx5/core/en/fs.h | 3 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 53 ++++++++++++++++++- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 6 +-- 3 files changed, 56 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +2 -1
@@ -78,7 +78,8 @@ enum { MLX5E_ARFS_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,#endif #ifdef CONFIG_MLX5_EN_IPSEC - MLX5E_ACCEL_FS_ESP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1, +MLX5E_ACCEL_FS_POL_FT_LEVEL =MLX5E_INNER_TTC_FT_LEVEL +1 , +MLX5E_ACCEL_FS_ESP_FT_LEVEL , MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL, #endif };
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +51 -2
110 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +3 -3
@@ -107,8 +107,8 @@#define ETHTOOL_PRIO_NUM_LEVELS 1#define ETHTOOL_NUM_PRIOS 11#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS) -/* Promiscuous, Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}} */ -#define KERNEL_NIC_PRIO_NUM_LEVELS 7 +/* Promiscuous, Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}}, IPsec policy */ +#define KERNEL_NIC_PRIO_NUM_LEVELS 8#define KERNEL_NIC_NUM_PRIOS 1/* One more level for tc */ #define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1)
@@ -129,7 +129,7 @@#define LAG_MIN_LEVEL (OFFLOADS_MIN_LEVEL + 1)#define KERNEL_TX_IPSEC_NUM_PRIOS 1 -#define KERNEL_TX_IPSEC_NUM_LEVELS 1 +#define KERNEL_TX_IPSEC_NUM_LEVELS 2#define KERNEL_TX_MIN_LEVEL (KERNEL_TX_IPSEC_NUM_LEVELS)struct node_caps {
Signature · 1 line
2.37.2
PATCH 20/26 net/mlx5e: Add XFRM policy offload logic
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Implement mlx5 flow steering logic and mlx5 IPsec code support XFRM policy offload.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 103 ++++++++++++ .../mellanox/mlx5/core/en_accel/ipsec.h | 32 ++++ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 146 ++++++++++++++++++ 3 files changed, 281 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +103 -0
@@ -45,6 +45,11 @@ static struct mlx5e_ipsec_sa_entry *to_ipsec_sa_entry(struct xfrm_state *x)return (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle; } +static struct mlx5e_ipsec_pol_entry *to_ipsec_pol_entry (struct xfrm_policy *x) +{ +return (struct mlx5e_ipsec_pol_entry *)x->xdo.offload_handle; +} +struct xfrm_state *mlx5e_ipsec_sadb_rx_lookup (struct mlx5e_ipsec *ipsec,unsigned int handle) {
@@ -462,12 +467,110 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)queue_work (sa_entry->ipsec->wq, &modify_work->work); } +static int mlx5e_xfrm_validate_policy (struct xfrm_policy *x) +{ +struct net_device *netdev = x->xdo.real_dev; + +if (x->type !=XFRM_POLICY_TYPE_MAIN ) { +netdev_info (netdev,"Cannot offload non-main policy types\n" ); +return -EINVAL ; + } + +/* Please pay attention that we support only one template */ +if (x->xfrm_nr >1 ) { +netdev_info (netdev,"Cannot offload more than one template\n" ); +return -EINVAL ; + } + +if (x->xdo.dir !=XFRM_DEV_OFFLOAD_IN && + x->xdo.dir !=XFRM_DEV_OFFLOAD_OUT ) { +netdev_info (netdev,"Cannot offload forward policy\n" ); +return -EINVAL ; + } + +if (!x->xfrm_vec[0 ].reqid) { +netdev_info (netdev,"Cannot offload policy without reqid\n" ); +return -EINVAL ; + } + +if (x->xdo.type !=XFRM_DEV_OFFLOAD_FULL ) { +netdev_info (netdev,"Unsupported xfrm offload type\n" ); +return -EINVAL ; + } + +return 0 ; +} + +static void +mlx5e_ipsec_build_accel_pol_attrs (struct mlx5e_ipsec_pol_entry *pol_entry, +struct mlx5_accel_pol_xfrm_attrs *attrs) +{ +struct xfrm_policy *x = pol_entry->x; +struct xfrm_selector *sel; + + sel = &x->selector; +memset (attrs,0 ,sizeof (*attrs)); + +memcpy (&attrs->saddr, sel->saddr.a6,sizeof (attrs->saddr)); +memcpy (&attrs->daddr, sel->daddr.a6,sizeof (attrs->daddr)); + attrs->family = sel->family; + attrs->dir = x->xdo.dir; + attrs->action = x->action; + attrs->type =XFRM_DEV_OFFLOAD_FULL ; +} + +static int mlx5e_xfrm_add_policy (struct xfrm_policy *x) +{ +struct net_device *netdev = x->xdo.real_dev; +struct mlx5e_ipsec_pol_entry *pol_entry; +struct mlx5e_priv *priv; +int err; + + priv =netdev_priv (netdev); +if (!priv->ipsec) +return -EOPNOTSUPP ; + + err =mlx5e_xfrm_validate_policy (x); +if (err) +return err; + + pol_entry =kzalloc (sizeof (*pol_entry),GFP_KERNEL ); +if (!pol_entry) +return -ENOMEM ; + + pol_entry->x = x; + pol_entry->ipsec = priv->ipsec; + +mlx5e_ipsec_build_accel_pol_attrs (pol_entry, &pol_entry->attrs); + err =mlx5e_accel_ipsec_fs_add_pol (pol_entry); +if (err) + goto err_fs; + + x->xdo.offload_handle = (unsigned long )pol_entry; +return 0 ; + +err_fs: +kfree (pol_entry); +return err; +} + +static void mlx5e_xfrm_free_policy (struct xfrm_policy *x) +{ +struct mlx5e_ipsec_pol_entry *pol_entry =to_ipsec_pol_entry (x); + +mlx5e_accel_ipsec_fs_del_pol (pol_entry); +kfree (pol_entry); +} +static const struct xfrmdev_ops mlx5e_ipsec_xfrmdev_ops = { .xdo_dev_state_add = mlx5e_xfrm_add_state, .xdo_dev_state_delete = mlx5e_xfrm_del_state, .xdo_dev_state_free = mlx5e_xfrm_free_state, .xdo_dev_offload_ok = mlx5e_ipsec_offload_ok, .xdo_dev_state_advance_esn = mlx5e_xfrm_advance_esn_state, + + .xdo_dev_policy_add = mlx5e_xfrm_add_policy, + .xdo_dev_policy_free = mlx5e_xfrm_free_policy, };void mlx5e_ipsec_build_netdev (struct mlx5e_priv *priv)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +32 -0
@@ -144,6 +144,30 @@ struct mlx5e_ipsec_sa_entry {struct mlx5e_ipsec_modify_state_work modify_work; }; +struct mlx5_accel_pol_xfrm_attrs { +union { +__be32 a4; +__be32 a6[4 ]; + } saddr; + +union { +__be32 a4; +__be32 a6[4 ]; + } daddr; + +u8 family; +u8 action; +u8 type :2 ; +u8 dir :2 ; +}; + +struct mlx5e_ipsec_pol_entry { +struct xfrm_policy *x; +struct mlx5e_ipsec *ipsec; +struct mlx5_flow_handle *rule; +struct mlx5_accel_pol_xfrm_attrs attrs; +}; +int mlx5e_ipsec_init (struct mlx5e_priv *priv);void mlx5e_ipsec_cleanup (struct mlx5e_priv *priv);void mlx5e_ipsec_build_netdev (struct mlx5e_priv *priv);
@@ -155,6 +179,8 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec);int mlx5e_accel_ipsec_fs_init (struct mlx5e_ipsec *ipsec);int mlx5e_accel_ipsec_fs_add_rule (struct mlx5e_ipsec_sa_entry *sa_entry);void mlx5e_accel_ipsec_fs_del_rule (struct mlx5e_ipsec_sa_entry *sa_entry); +int mlx5e_accel_ipsec_fs_add_pol (struct mlx5e_ipsec_pol_entry *pol_entry); +void mlx5e_accel_ipsec_fs_del_pol (struct mlx5e_ipsec_pol_entry *pol_entry);int mlx5_ipsec_create_sa_ctx (struct mlx5e_ipsec_sa_entry *sa_entry);void mlx5_ipsec_free_sa_ctx (struct mlx5e_ipsec_sa_entry *sa_entry);
@@ -172,6 +198,12 @@ mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry) {return sa_entry->ipsec->mdev; } + +static inline struct mlx5_core_dev * +mlx5e_ipsec_pol2dev (struct mlx5e_ipsec_pol_entry *pol_entry) +{ +return pol_entry->ipsec->mdev; +}#else static inline int mlx5e_ipsec_init (struct mlx5e_priv *priv) {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +146 -0
158 lines not on this page · raw message
Signature · 1 line
2.37.2
PATCH 21/26 net/mlx5e: Use same coding pattern for Rx and Tx flows
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Remove intermediate variable in favour of having similar coding style for Rx and Tx add rule functions.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +2 -3
@@ -486,7 +486,6 @@ static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,static int rx_add_rule (struct mlx5e_ipsec_sa_entry *sa_entry) { -struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;struct mlx5_core_dev *mdev =mlx5e_ipsec_sa2dev (sa_entry);struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
@@ -535,8 +534,8 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) }kvfree (spec); - ipsec_rule->rule = rule; - ipsec_rule->modify_hdr = flow_act.modify_hdr; + sa_entry->ipsec_rule.rule = rule; + sa_entry->ipsec_rule.modify_hdr = flow_act.modify_hdr;return 0 ; err_add_flow:
Signature · 1 line
2.37.2
PATCH 22/26 net/mlx5e: Configure IPsec full offload flow steering
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
In full offload mode, the HW is responsible to handle ESP headers, SPI numbers and trailers (ICV) together with different logic for RX and TX paths.
In order to support full offload mode, special logic is added to flow steering rules.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 2 + .../mellanox/mlx5/core/en_accel/ipsec.h | 2 + .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 95 +++++++++++++++++-- 3 files changed, 89 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +2 -0
@@ -165,6 +165,8 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,memcpy (&aes_gcm->salt, x->aead->alg_key + key_len,sizeof (aes_gcm->salt)); + attrs->authsize =crypto_aead_authsize (aead) /4 ;/* in dwords */ +/* iv len */ aes_gcm->icv_len = x->aead->alg_icv_len;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +2 -0
@@ -76,6 +76,7 @@ struct mlx5_accel_esp_xfrm_attrs { u8 type : 2;u8 family;u32 replay_window; +u32 authsize; };enum mlx5_ipsec_cap {
@@ -122,6 +123,7 @@ struct mlx5e_ipsec_esn_state {struct mlx5e_ipsec_rule {struct mlx5_flow_handle *rule;struct mlx5_modify_hdr *modify_hdr; +struct mlx5_pkt_reformat *pkt_reformat; };struct mlx5e_ipsec_modify_state_work {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +85 -10
141 lines not on this page · raw message
Signature · 1 line
2.37.2
PATCH 23/26 net/mlx5e: Improve IPsec flow steering autogroup
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Flow steering API separates newly created rules based on their match criteria. Right now, all IPsec tables are created with one group and suffers from not-optimal FS performance.
Count number of different match criteria for relevant tables, and set proper value at the table creation.
--- .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +4 -4
@@ -202,7 +202,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,/* Create FT */ ft =ipsec_ft_create (mdev, ipsec->fs->ns,MLX5E_ACCEL_FS_ESP_FT_LEVEL , -MLX5E_NIC_PRIO ,1 ,XFRM_DEV_OFFLOAD_IN ); +MLX5E_NIC_PRIO ,2 ,XFRM_DEV_OFFLOAD_IN );if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_fs_ft;
@@ -214,7 +214,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec, goto err_fs; ft =ipsec_ft_create (mdev, ipsec->fs->ns,MLX5E_ACCEL_FS_POL_FT_LEVEL , -MLX5E_NIC_PRIO ,1 ,XFRM_DEV_OFFLOAD_IN ); +MLX5E_NIC_PRIO ,2 ,XFRM_DEV_OFFLOAD_IN );if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_pol_ft;
@@ -311,13 +311,13 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx)struct mlx5_flow_table *ft;int err; - ft =ipsec_ft_create (mdev, tx->ns,1 ,0 ,1 ,XFRM_DEV_OFFLOAD_OUT ); + ft =ipsec_ft_create (mdev, tx->ns,1 ,0 ,4 ,XFRM_DEV_OFFLOAD_OUT );if (IS_ERR (ft))return PTR_ERR (ft); tx->ft.sa = ft; - ft =ipsec_ft_create (mdev, tx->ns,0 ,0 ,1 ,XFRM_DEV_OFFLOAD_OUT ); + ft =ipsec_ft_create (mdev, tx->ns,0 ,0 ,2 ,XFRM_DEV_OFFLOAD_OUT );if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_pol_ft;
Signature · 1 line
2.37.2
PATCH 24/26 net/mlx5e: Add statistics for Rx/Tx IPsec offloaded flows
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Add the following statistics:
RX successfully IPsec flows:ipsec_rx_pkts : Number of packets passed Rx IPsec flow ipsec_rx_bytes : Number of bytes passed Rx IPsec flow
Rx dropped IPsec policy packets:ipsec_rx_drop_pkts: Number of packets dropped in Rx datapath due to IPsec drop policyipsec_rx_drop_bytes: Number of bytes dropped in Rx datapath due to IPsec drop policy
TX successfully encrypted and encapsulated IPsec packets:ipsec_tx_pkts : Number of packets encrypted and encapsulated successfully ipsec_tx_bytes : Number of bytes encrypted and encapsulated successfully
Tx dropped IPsec policy packets:ipsec_tx_drop_pkts: Number of packets dropped in Tx datapath due to IPsec drop policyipsec_tx_drop_bytes: Number of bytes dropped in Tx datapath due to IPsec drop policy
The above can be seen using:
ethtool -S <ifc> |grep ipsec
--- .../mellanox/mlx5/core/en_accel/ipsec.h | 14 ++ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 188 +++++++++++++++--- .../mellanox/mlx5/core/en_accel/ipsec_stats.c | 52 +++++ .../ethernet/mellanox/mlx5/core/en_stats.c | 1 + .../ethernet/mellanox/mlx5/core/en_stats.h | 1 + 5 files changed, 232 insertions(+), 24 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +14 -0
@@ -87,6 +87,17 @@ enum mlx5_ipsec_cap {struct mlx5e_priv ; +struct mlx5e_ipsec_hw_stats { +u64 ipsec_rx_pkts; +u64 ipsec_rx_bytes; +u64 ipsec_rx_drop_pkts; +u64 ipsec_rx_drop_bytes; +u64 ipsec_tx_pkts; +u64 ipsec_tx_bytes; +u64 ipsec_tx_drop_pkts; +u64 ipsec_tx_drop_bytes; +}; +struct mlx5e_ipsec_sw_stats {atomic64_t ipsec_rx_drop_sp_alloc;atomic64_t ipsec_rx_drop_sadb_miss;
@@ -105,6 +116,7 @@ struct mlx5e_ipsec {DECLARE_HASHTABLE (sadb_rx,MLX5E_IPSEC_SADB_RX_BITS );spinlock_t sadb_rx_lock;/* Protects sadb_rx */ struct mlx5e_ipsec_sw_stats sw_stats; +struct mlx5e_ipsec_hw_stats hw_stats;struct workqueue_struct *wq;struct mlx5e_flow_steering *fs;struct mlx5e_ipsec_rx *rx_ipv4;
@@ -195,6 +207,8 @@ void mlx5_accel_esp_modify_xfrm(struct mlx5e_ipsec_sa_entry *sa_entry,int mlx5e_ipsec_aso_init (struct mlx5e_ipsec *ipsec);void mlx5e_ipsec_aso_cleanup (struct mlx5e_ipsec *ipsec); +void mlx5e_accel_ipsec_fs_read_full_stats (struct mlx5e_priv *priv,void *ipsec_stats); +static inline struct mlx5_core_dev *mlx5e_ipsec_sa2dev (struct mlx5e_ipsec_sa_entry *sa_entry) {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +164 -24
317 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_stats.c +52 -0
70 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +1 -0
@@ -2444,6 +2444,7 @@ mlx5e_stats_grp_t mlx5e_nic_stats_grps[] = { &MLX5E_STATS_GRP (per_prio), &MLX5E_STATS_GRP (pme), #ifdef CONFIG_MLX5_EN_IPSEC + &MLX5E_STATS_GRP (ipsec_hw), &MLX5E_STATS_GRP (ipsec_sw), #endif &MLX5E_STATS_GRP(tls),
drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +1 -0
@@ -484,6 +484,7 @@ extern MLX5E_DECLARE_STATS_GRP(per_prio);extern MLX5E_DECLARE_STATS_GRP (pme);extern MLX5E_DECLARE_STATS_GRP (channels);extern MLX5E_DECLARE_STATS_GRP (per_port_buff_congest); +extern MLX5E_DECLARE_STATS_GRP (ipsec_hw);extern MLX5E_DECLARE_STATS_GRP (ipsec_sw);extern MLX5E_DECLARE_STATS_GRP (ptp);
Signature · 1 line
2.37.2
PATCH 25/26 net/mlx5e: Skip IPsec encryption for TX path without matching policy
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Software implementation of IPsec skips encryption of packets in TX path if no matching policy is found. So align HW implementation to this behavior, by requiring matching reqid for offloaded policy and SA.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 2 + .../mellanox/mlx5/core/en_accel/ipsec.h | 4 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 39 ++++++++++++++++--- 3 files changed, 38 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +2 -0
@@ -187,6 +187,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,memcpy (&attrs->daddr, x->id.daddr.a6,sizeof (attrs->daddr)); attrs->family = x->props.family; attrs->type = x->xso.type; + attrs->reqid = x->props.reqid; }static inline int mlx5e_xfrm_validate_state (struct xfrm_state *x)
@@ -519,6 +520,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry, attrs->dir = x->xdo.dir; attrs->action = x->action; attrs->type =XFRM_DEV_OFFLOAD_FULL ; + attrs->reqid = x->xfrm_vec[0 ].reqid; }static int mlx5e_xfrm_add_policy (struct xfrm_policy *x)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +3 -1
@@ -77,6 +77,7 @@ struct mlx5_accel_esp_xfrm_attrs {u8 family;u32 replay_window;u32 authsize; +u32 reqid; };enum mlx5_ipsec_cap {
@@ -173,12 +174,13 @@ struct mlx5_accel_pol_xfrm_attrs {u8 action; u8 type : 2; u8 dir : 2; +u32 reqid; };struct mlx5e_ipsec_pol_entry {struct xfrm_policy *x;struct mlx5e_ipsec *ipsec; -struct mlx5_flow_handle *rule; +struct mlx5e_ipsec_rule ipsec_rule;struct mlx5_accel_pol_xfrm_attrs attrs; };
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +33 -6
@@ -460,6 +460,17 @@ static void setup_fte_reg_a(struct mlx5_flow_spec *spec) misc_parameters_2.metadata_reg_a, MLX5_ETH_WQE_FT_META_IPSEC); } +static void setup_fte_reg_c0 (struct mlx5_flow_spec *spec,u32 reqid) +{ +/* Pass policy check before choosing this SA */ + spec->match_criteria_enable |=MLX5_MATCH_MISC_PARAMETERS_2 ; + +MLX5_SET (fte_match_param, spec->match_criteria, + misc_parameters_2.metadata_reg_c_0, reqid); +MLX5_SET (fte_match_param, spec->match_value, + misc_parameters_2.metadata_reg_c_0, reqid); +} +static int setup_modify_header (struct mlx5_core_dev *mdev,u32 val,u8 dir,struct mlx5_flow_act *flow_act) {
@@ -474,6 +485,11 @@ static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir, MLX5_ACTION_IN_FIELD_METADATA_REG_B); ns_type =MLX5_FLOW_NAMESPACE_KERNEL ;break ; +case XFRM_DEV_OFFLOAD_OUT : +MLX5_SET (set_action_in, action, field, +MLX5_ACTION_IN_FIELD_METADATA_REG_C_0 ); + ns_type =MLX5_FLOW_NAMESPACE_EGRESS_KERNEL ; +break ;default :return -EINVAL ; }
@@ -650,6 +666,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)setup_fte_reg_a (spec);break ;case XFRM_DEV_OFFLOAD_FULL : +setup_fte_reg_c0 (spec, attrs->reqid); err =setup_pkt_reformat (mdev, attrs, &flow_act);if (err) goto err_pkt_reformat;
@@ -715,6 +732,11 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)setup_fte_no_frags (spec); + err =setup_modify_header (mdev, attrs->reqid,XFRM_DEV_OFFLOAD_OUT , + &flow_act); +if (err) + goto err_mod_header; +switch (attrs->action) {case XFRM_POLICY_ALLOW : flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
@@ -744,10 +766,13 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) }kvfree (spec); - pol_entry->rule = rule; + pol_entry->ipsec_rule.rule = rule; + pol_entry->ipsec_rule.modify_hdr = flow_act.modify_hdr;return 0 ; err_action: +mlx5_modify_header_dealloc (mdev, flow_act.modify_hdr); +err_mod_header:kvfree (spec); err_alloc:tx_ft_put (pol_entry->ipsec);
@@ -810,7 +835,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) }kvfree (spec); - pol_entry->rule = rule; + pol_entry->ipsec_rule.rule = rule;return 0 ; err_action:
@@ -964,16 +989,18 @@ int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)void mlx5e_accel_ipsec_fs_del_pol (struct mlx5e_ipsec_pol_entry *pol_entry) { +struct mlx5e_ipsec_rule *ipsec_rule = &pol_entry->ipsec_rule;struct mlx5_core_dev *mdev =mlx5e_ipsec_pol2dev (pol_entry); -mlx5_del_flow_rules (pol_entry->rule); +mlx5_del_flow_rules (ipsec_rule->rule); -if (pol_entry->attrs.dir ==XFRM_DEV_OFFLOAD_OUT ) { -tx_ft_put (pol_entry->ipsec); +if (pol_entry->attrs.dir ==XFRM_DEV_OFFLOAD_IN ) { +rx_ft_put (mdev, pol_entry->ipsec, pol_entry->attrs.family);return ; } -rx_ft_put (mdev, pol_entry->ipsec, pol_entry->attrs.family); +mlx5_modify_header_dealloc (mdev, ipsec_rule->modify_hdr); +tx_ft_put (pol_entry->ipsec); }void mlx5e_accel_ipsec_fs_cleanup (struct mlx5e_ipsec *ipsec)
Signature · 1 line
2.37.2
PATCH 26/26 net/mlx5e: Open mlx5 driver to accept IPsec full offload
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Enable configuration of IPsec full offload through XFRM state add interface together with moving specific to IPsec full mode limitations to specific switch-case section.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +36 -10
@@ -219,11 +219,6 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)netdev_info (netdev,"Only IPv4/6 xfrm states may be offloaded\n" );return -EINVAL ; } -if (x->props.mode !=XFRM_MODE_TRANSPORT && - x->props.mode !=XFRM_MODE_TUNNEL ) { -dev_info (&netdev->dev,"Only transport and tunnel xfrm states may be offloaded\n" ); -return -EINVAL ; - }if (x->id.proto !=IPPROTO_ESP ) {netdev_info (netdev,"Only ESP xfrm state may be offloaded\n" );return -EINVAL ;
@@ -257,11 +252,32 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)netdev_info (netdev,"Cannot offload xfrm states with geniv other than seqiv\n" );return -EINVAL ; } -if (x->xso.type !=XFRM_DEV_OFFLOAD_CRYPTO ) { -netdev_info (netdev,"Unsupported xfrm offload type\n" ); -return -EINVAL ; - } -if (x->xso.type ==XFRM_DEV_OFFLOAD_FULL ) { +switch (x->xso.type) { +case XFRM_DEV_OFFLOAD_CRYPTO : +if (!(mlx5_ipsec_device_caps (priv->mdev) & +MLX5_IPSEC_CAP_CRYPTO )) { +netdev_info (netdev,"Crypto offload is not supported\n" ); +return -EINVAL ; + } + +if (x->props.mode !=XFRM_MODE_TRANSPORT && + x->props.mode !=XFRM_MODE_TUNNEL ) { +netdev_info (netdev,"Only transport and tunnel xfrm states may be offloaded\n" ); +return -EINVAL ; + } +break ; +case XFRM_DEV_OFFLOAD_FULL : +if (!(mlx5_ipsec_device_caps (priv->mdev) & +MLX5_IPSEC_CAP_FULL_OFFLOAD )) { +netdev_info (netdev,"Full offload is not supported\n" ); +return -EINVAL ; + } + +if (x->props.mode !=XFRM_MODE_TRANSPORT ) { +netdev_info (netdev,"Only transport xfrm states may be offloaded in full mode\n" ); +return -EINVAL ; + } + if (x->replay_esn && x->replay_esn->replay_window != 32 && x->replay_esn->replay_window != 64 && x->replay_esn->replay_window != 128 &&
@@ -271,6 +287,16 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x) x->replay_esn->replay_window);return -EINVAL ; } + +if (!x->props.reqid) { +netdev_info (netdev,"Cannot ofload without reqid\n" ); +return -EINVAL ; + } +break ; +default : +netdev_info (netdev,"Unsupported xfrm offload type %d\n" , + x->xso.type); +return -EINVAL ; }return 0 ; }
Signature · 1 line
2.37.2