mlx5 IPsec packet offload support in eswitch mode
Subsystems (6)
cover mlx5 IPsec packet offload support in eswitch mode
From: Leon Romanovsky <[email protected]>
Hi,
This series from Jianbo adds mlx5 IPsec packet offload support in eswitch offloaded mode.
Thanks
Jianbo Liu (12):
net/mlx5e: Add function to get IPsec offload namespace net/mlx5e: Change the parameter of IPsec RX skb handle function net/mlx5e: Prepare IPsec packet offload for switchdev mode net/mlx5e: Refactor IPsec RX tables creation and destruction net/mlx5e: Support IPsec packet offload for RX in switchdev mode net/mlx5e: Handle IPsec offload for RX datapath in switchdev mode net/mlx5e: Refactor IPsec TX tables creation net/mlx5e: Support IPsec packet offload for TX in switchdev mode net/mlx5: Compare with old_dest param to modify rule destination net/mlx5e: Make IPsec offload work together with eswitch and TC net/mlx5e: Modify and restore TC rules for IPSec TX rules net/mlx5e: Add get IPsec offload stats for uplink representor
.../net/ethernet/mellanox/mlx5/core/Makefile | 4 + .../ethernet/mellanox/mlx5/core/en/rep/tc.c | 17 +- .../mellanox/mlx5/core/en_accel/ipsec.c | 2 + .../mellanox/mlx5/core/en_accel/ipsec.h | 65 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 626 ++++++++++++------ .../mlx5/core/en_accel/ipsec_offload.c | 3 +- .../mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 25 +- .../mellanox/mlx5/core/en_accel/ipsec_rxtx.h | 6 +- .../net/ethernet/mellanox/mlx5/core/en_rep.c | 1 + .../net/ethernet/mellanox/mlx5/core/en_rx.c | 3 +- .../mellanox/mlx5/core/esw/ipsec_fs.c | 325 +++++++++ .../mellanox/mlx5/core/esw/ipsec_fs.h | 67 ++ .../net/ethernet/mellanox/mlx5/core/eswitch.h | 17 + .../mellanox/mlx5/core/eswitch_offloads.c | 174 ++++- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 14 +- include/linux/mlx5/eswitch.h | 3 + include/linux/mlx5/fs.h | 2 + 17 files changed, 1141 insertions(+), 213 deletions(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h
Signature · 1 line
2.41.0
PATCH 1/12 net/mlx5e: Add function to get IPsec offload namespace
From: Jianbo Liu <[email protected]>
Add function to get namespace in different directions. It will be extended for switchdev mode in later patch, but no functionality change for now.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +22 -24
@@ -814,11 +814,20 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp } } -static int setup_modify_header (struct mlx5_core_dev *mdev,u32 val,u8 dir, +static enum mlx5_flow_namespace_type ipsec_fs_get_ns (struct mlx5e_ipsec *ipsec,u8 dir) +{ +if (dir ==XFRM_DEV_OFFLOAD_IN ) +return MLX5_FLOW_NAMESPACE_KERNEL ; + +return MLX5_FLOW_NAMESPACE_EGRESS ; +} + +static int setup_modify_header (struct mlx5e_ipsec *ipsec,u32 val,u8 dir,struct mlx5_flow_act *flow_act) { +enum mlx5_flow_namespace_type ns_type =ipsec_fs_get_ns (ipsec, dir);u8 action[MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto)] = {}; -enum mlx5_flow_namespace_type ns_type; +struct mlx5_core_dev *mdev = ipsec->mdev;struct mlx5_modify_hdr *modify_hdr;MLX5_SET (set_action_in, action, action_type,MLX5_ACTION_TYPE_SET );
@@ -826,12 +835,10 @@ static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,case XFRM_DEV_OFFLOAD_IN :MLX5_SET (set_action_in, action, field,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 ;break ;default :return -EINVAL ;
@@ -991,26 +998,16 @@ setup_pkt_transport_reformat(struct mlx5_accel_esp_xfrm_attrs *attrs,return 0 ; } -static int setup_pkt_reformat (struct mlx5_core_dev *mdev, +static int setup_pkt_reformat (struct mlx5e_ipsec *ipsec,struct mlx5_accel_esp_xfrm_attrs *attrs,struct mlx5_flow_act *flow_act) { +enum mlx5_flow_namespace_type ns_type =ipsec_fs_get_ns (ipsec, attrs->dir);struct mlx5_pkt_reformat_params reformat_params = {}; +struct mlx5_core_dev *mdev = ipsec->mdev;struct mlx5_pkt_reformat *pkt_reformat; -enum mlx5_flow_namespace_type ns_type;int ret; -switch (attrs->dir) { -case XFRM_DEV_OFFLOAD_IN : - ns_type =MLX5_FLOW_NAMESPACE_KERNEL ; -break ; -case XFRM_DEV_OFFLOAD_OUT : - ns_type =MLX5_FLOW_NAMESPACE_EGRESS ; -break ; -default : -return -EINVAL ; - } -switch (attrs->mode) {case XFRM_MODE_TRANSPORT : ret =setup_pkt_transport_reformat (attrs, &reformat_params);
@@ -1068,14 +1065,14 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)setup_fte_esp (spec);setup_fte_no_frags (spec); - err =setup_modify_header (mdev, sa_entry->ipsec_obj_id |BIT (31 ), + err =setup_modify_header (ipsec, sa_entry->ipsec_obj_id |BIT (31 ),XFRM_DEV_OFFLOAD_IN , &flow_act);if (err) goto err_mod_header;switch (attrs->type) {case XFRM_DEV_OFFLOAD_PACKET : - err =setup_pkt_reformat (mdev, attrs, &flow_act); + err =setup_pkt_reformat (ipsec, attrs, &flow_act);if (err) goto err_pkt_reformat;break ;
@@ -1169,7 +1166,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)case XFRM_DEV_OFFLOAD_PACKET :if (attrs->reqid)setup_fte_reg_c0 (spec, attrs->reqid); - err =setup_pkt_reformat (mdev, attrs, &flow_act); + err =setup_pkt_reformat (ipsec, attrs, &flow_act);if (err) goto err_pkt_reformat;break ;
@@ -1226,15 +1223,16 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) {struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;struct mlx5_core_dev *mdev =mlx5e_ipsec_pol2dev (pol_entry); -struct mlx5e_ipsec_tx *tx = pol_entry->ipsec->tx; +struct mlx5e_ipsec *ipsec = pol_entry->ipsec;struct mlx5_flow_destination dest[2 ] = {}; +struct mlx5e_ipsec_tx *tx = ipsec->tx;struct mlx5_flow_act flow_act = {};struct mlx5_flow_handle *rule;struct mlx5_flow_spec *spec;struct mlx5_flow_table *ft;int err, dstn =0 ; - ft =tx_ft_get_policy (mdev, pol_entry->ipsec, attrs->prio); + ft =tx_ft_get_policy (mdev, ipsec, attrs->prio);if (IS_ERR (ft))return PTR_ERR (ft);
@@ -1258,7 +1256,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)if (!attrs->reqid)break ; - err =setup_modify_header (mdev, attrs->reqid, + err =setup_modify_header (ipsec, attrs->reqid,XFRM_DEV_OFFLOAD_OUT , &flow_act);if (err) goto err_mod_header;
@@ -1298,7 +1296,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) err_mod_header:kvfree (spec); err_alloc: -tx_ft_put_policy (pol_entry->ipsec, attrs->prio); +tx_ft_put_policy (ipsec, attrs->prio);return err; }
Signature · 1 line
2.41.0
PATCH 2/12 net/mlx5e: Change the parameter of IPsec RX skb handle function
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
Refactor the function to pass in reg B value only.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 3 +-- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +1 -2
@@ -309,9 +309,8 @@ enum {void mlx5e_ipsec_offload_handle_rx_skb (struct net_device *netdev,struct sk_buff *skb, -struct mlx5_cqe64 *cqe) +u32 ipsec_meta_data) { -u32 ipsec_meta_data =be32_to_cpu (cqe->ft_metadata);struct mlx5e_priv *priv =netdev_priv (netdev);struct mlx5e_ipsec *ipsec = priv->ipsec;struct mlx5e_ipsec_sa_entry *sa_entry;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h +2 -2
@@ -66,7 +66,7 @@ void mlx5e_ipsec_handle_tx_wqe(struct mlx5e_tx_wqe *wqe, struct mlx5_wqe_inline_seg *inlseg);void mlx5e_ipsec_offload_handle_rx_skb (struct net_device *netdev,struct sk_buff *skb, -struct mlx5_cqe64 *cqe); +u32 ipsec_meta_data);static inline unsigned int mlx5e_ipsec_tx_ids_len (struct mlx5e_accel_tx_ipsec_state *ipsec_st) {return ipsec_st->tailen;
@@ -145,7 +145,7 @@ mlx5e_ipsec_txwqe_build_eseg_csum(struct mlx5e_txqsq *sq, struct sk_buff *skb,static inline void mlx5e_ipsec_offload_handle_rx_skb (struct net_device *netdev,struct sk_buff *skb, -struct mlx5_cqe64 *cqe) +u32 ipsec_meta_data) {}static inline bool mlx5e_ipsec_eseg_meta (struct mlx5_wqe_eth_seg *eseg)
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +2 -1
@@ -1535,7 +1535,8 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,mlx5e_ktls_handle_rx_skb (rq, skb, cqe, &cqe_bcnt);if (unlikely (mlx5_ipsec_is_rx_flow (cqe))) -mlx5e_ipsec_offload_handle_rx_skb (netdev, skb, cqe); +mlx5e_ipsec_offload_handle_rx_skb (netdev, skb, +be32_to_cpu (cqe->ft_metadata));if (unlikely (mlx5e_macsec_is_rx_flow (cqe)))mlx5e_macsec_offload_handle_rx_skb (netdev, skb, cqe);
Signature · 1 line
2.41.0
PATCH 3/12 net/mlx5e: Prepare IPsec packet offload for switchdev mode
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
As the uplink representor is created only in switchdev mode, add a local variable for IPsec to indicate the device is in this mode.
In this mode, the tables for packet offload are created in FDB, ipsec->rx_esw and ipsec->tx_esw are added.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 2 + .../mellanox/mlx5/core/en_accel/ipsec.h | 3 + .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 262 ++++++++++++------ 3 files changed, 184 insertions(+), 83 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +2 -0
@@ -40,6 +40,7 @@#include "en.h" #include "ipsec.h" #include "ipsec_rxtx.h" +#include "en_rep.h" #define MLX5_IPSEC_RESCHED msecs_to_jiffies(1000)#define MLX5E_IPSEC_TUNNEL_SA XA_MARK_1
@@ -835,6 +836,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv) goto clear_aso; } + ipsec->is_uplink_rep =mlx5e_is_uplink_rep (priv); ret =mlx5e_accel_ipsec_fs_init (ipsec);if (ret) goto err_fs_init;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +3 -0
@@ -170,11 +170,14 @@ struct mlx5e_ipsec {struct mlx5e_flow_steering *fs;struct mlx5e_ipsec_rx *rx_ipv4;struct mlx5e_ipsec_rx *rx_ipv6; +struct mlx5e_ipsec_rx *rx_esw;struct mlx5e_ipsec_tx *tx; +struct mlx5e_ipsec_tx *tx_esw;struct mlx5e_ipsec_aso *aso;struct notifier_block nb;struct notifier_block netevent_nb;struct mlx5_ipsec_fs *roce; + u8 is_uplink_rep: 1; };struct mlx5e_ipsec_esn_state {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +179 -83
509 lines not on this page · raw message
Signature · 1 line
2.41.0
PATCH 4/12 net/mlx5e: Refactor IPsec RX tables creation and destruction
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
Add attribute for IPsec RX creation, so rx_create() can be used by eswitch in later patch. And move the code for TTC dest connect/disconnect, which are needed only in NIC mode, to individual functions.
--- .../mellanox/mlx5/core/en_accel/ipsec.h | 11 ++ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 100 ++++++++++++------ 2 files changed, 80 insertions(+), 31 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +11 -0
@@ -161,6 +161,17 @@ struct mlx5e_ipsec_aso {spinlock_t lock; }; +struct mlx5e_ipsec_rx_create_attr { +struct mlx5_flow_namespace *ns; +struct mlx5_ttc_table *ttc; +u32 family; +int prio; +int pol_level; +int sa_level; +int status_level; +enum mlx5_flow_namespace_type chains_ns; +}; +struct mlx5e_ipsec {struct mlx5_core_dev *mdev;struct xarray sadb;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +69 -31
158 lines not on this page · raw message
Signature · 1 line
2.41.0
PATCH 5/12 net/mlx5e: Support IPsec packet offload for RX in switchdev mode
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
As decryption must be done first, add new prio for IPsec offload in FDB, and put it just lower than BYPASS prio and higher than TC prio. Three levels are added for RX. The first one is for ip xfrm policy. SA table is created in the second level for ip xfrm state. The status table is created in the last to check the decryption result. If success, packets continue with the next process, or dropped otherwise. For now, the set of reg c1 is removed for swtichdev mode, and the datapath process will be added in the next patch.
--- .../net/ethernet/mellanox/mlx5/core/Makefile | 4 + .../mellanox/mlx5/core/en_accel/ipsec.h | 41 +++- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 80 ++++---- .../mlx5/core/en_accel/ipsec_offload.c | 3 +- .../mellanox/mlx5/core/esw/ipsec_fs.c | 184 ++++++++++++++++++ .../mellanox/mlx5/core/esw/ipsec_fs.h | 39 ++++ .../net/ethernet/mellanox/mlx5/core/fs_core.c | 6 + include/linux/mlx5/fs.h | 1 + 8 files changed, 312 insertions(+), 46 deletions(-) create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h
drivers/net/ethernet/mellanox/mlx5/core/Makefile +4 -0
@@ -75,6 +75,10 @@ mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \ esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \ esw/acl/ingress_lgcy.o esw/acl/ingress_ofld.o +ifneq ($(CONFIG_MLX5_EN_IPSEC),) + mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/ipsec_fs.o +endif + mlx5_core-$(CONFIG_MLX5_BRIDGE) += esw/bridge.o esw/bridge_mcast.o esw/bridge_debugfs.o \ en/rep/bridge.o
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +33 -8
59 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +43 -37
180 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +2 -1
@@ -46,7 +46,8 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) caps |=MLX5_IPSEC_CAP_PACKET_OFFLOAD ;if (MLX5_CAP_FLOWTABLE_NIC_TX (mdev, ignore_flow_level) && -MLX5_CAP_FLOWTABLE_NIC_RX (mdev, ignore_flow_level)) +MLX5_CAP_FLOWTABLE_NIC_RX (mdev, ignore_flow_level) && +MLX5_CAP_ESW_FLOWTABLE_FDB (mdev, ignore_flow_level)) caps |=MLX5_IPSEC_CAP_PRIO ; if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c new file +184 -0
184 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h new file +39 -0
@@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef __MLX5_ESW_IPSEC_FS_H__ +#define __MLX5_ESW_IPSEC_FS_H__ + +struct mlx5e_ipsec ; + +#ifdef CONFIG_MLX5_ESWITCH +void mlx5_esw_ipsec_rx_status_destroy (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx *rx); +int mlx5_esw_ipsec_rx_status_create (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx *rx, +struct mlx5_flow_destination *dest); +void mlx5_esw_ipsec_rx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx_create_attr *attr); +int mlx5_esw_ipsec_rx_status_pass_dest_get (struct mlx5e_ipsec *ipsec, +struct mlx5_flow_destination *dest); +#else +static inline void mlx5_esw_ipsec_rx_status_destroy (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx *rx) {} + +static inline int mlx5_esw_ipsec_rx_status_create (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx *rx, +struct mlx5_flow_destination *dest) +{ +return -EINVAL ; +} + +static inline void mlx5_esw_ipsec_rx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_rx_create_attr *attr) {} + +static inline int mlx5_esw_ipsec_rx_status_pass_dest_get (struct mlx5e_ipsec *ipsec, +struct mlx5_flow_destination *dest) +{ +return -EINVAL ; +} +#endif /* CONFIG_MLX5_ESWITCH */ +#endif /* __MLX5_ESW_IPSEC_FS_H__ */
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +6 -0
@@ -2987,6 +2987,12 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering)if (err) goto out_err; + maj_prio =fs_create_prio (&steering->fdb_root_ns->ns,FDB_CRYPTO_INGRESS ,3 ); +if (IS_ERR (maj_prio)) { + err =PTR_ERR (maj_prio); + goto out_err; + } + err =create_fdb_fast_path (steering);if (err) goto out_err;
include/linux/mlx5/fs.h +1 -0
@@ -109,6 +109,7 @@ enum mlx5_flow_namespace_type {enum {FDB_BYPASS_PATH , +FDB_CRYPTO_INGRESS ,FDB_TC_OFFLOAD ,FDB_FT_OFFLOAD ,FDB_TC_MISS ,
Signature · 1 line
2.41.0
PATCH 6/12 net/mlx5e: Handle IPsec offload for RX datapath in switchdev mode
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
Reuse tun opts bits in reg c1, to pass IPsec obj id to datapath. As this is only for RX SA and there are only 11 bits, xarray is used to map IPsec obj id to an index, which is between 1 and 0x7ff, and replace obj id to write to reg c1.
--- .../ethernet/mellanox/mlx5/core/en/rep/tc.c | 17 ++++- .../mellanox/mlx5/core/en_accel/ipsec.h | 2 + .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 7 ++ .../mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 22 ++++++ .../mellanox/mlx5/core/en_accel/ipsec_rxtx.h | 2 + .../mellanox/mlx5/core/esw/ipsec_fs.c | 69 +++++++++++++++++++ .../mellanox/mlx5/core/esw/ipsec_fs.h | 20 ++++++ include/linux/mlx5/eswitch.h | 3 + 8 files changed, 139 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c +14 -3
@@ -715,9 +715,20 @@ void mlx5e_rep_tc_receive(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq, uplink_priv = &uplink_rpriv->uplink_priv; ct_priv = uplink_priv->ct_priv; -if (!mlx5_ipsec_is_rx_flow (cqe) && - !mlx5e_tc_update_skb (cqe, skb, mapping_ctx, reg_c0, ct_priv, zone_restore_id, tunnel_id, - &tc_priv)) +#ifdef CONFIG_MLX5_EN_IPSEC +if (!(tunnel_id >>ESW_TUN_OPTS_BITS )) { +u32 mapped_id; +u32 metadata; + + mapped_id = tunnel_id &ESW_IPSEC_RX_MAPPED_ID_MASK ; +if (mapped_id && + !mlx5_esw_ipsec_rx_make_metadata (priv, mapped_id, &metadata)) +mlx5e_ipsec_offload_handle_rx_skb (priv->netdev, skb, metadata); + } +#endif + +if (!mlx5e_tc_update_skb (cqe, skb, mapping_ctx, reg_c0, ct_priv, + zone_restore_id, tunnel_id, &tc_priv)) goto free_skb; forward:
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +2 -0
@@ -202,6 +202,7 @@ struct mlx5e_ipsec_rx {struct mlx5e_ipsec_fc *fc;struct mlx5_fs_chains *chains; u8 allow_tunnel_mode : 1; +struct xarray ipsec_obj_id_map; };struct mlx5e_ipsec {
@@ -248,6 +249,7 @@ struct mlx5e_ipsec_sa_entry {struct mlx5e_ipsec_work *work;struct mlx5e_ipsec_dwork *dwork;struct mlx5e_ipsec_limits limits; +u32 rx_mapped_id; };struct mlx5_accel_pol_xfrm_attrs {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +7 -0
@@ -1120,6 +1120,9 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) err =setup_modify_header (ipsec, attrs->type, sa_entry->ipsec_obj_id |BIT (31 ),XFRM_DEV_OFFLOAD_IN , &flow_act); + else + err =mlx5_esw_ipsec_rx_setup_modify_header (sa_entry, &flow_act); +if (err) goto err_mod_header;
@@ -1608,6 +1611,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry) }mlx5_modify_header_dealloc (mdev, ipsec_rule->modify_hdr); +mlx5_esw_ipsec_rx_id_mapping_remove (sa_entry);rx_ft_put (sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type); }
@@ -1660,6 +1664,8 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)kfree (ipsec->rx_ipv6);if (ipsec->is_uplink_rep) { +xa_destroy (&ipsec->rx_esw->ipsec_obj_id_map); +mutex_destroy (&ipsec->tx_esw->ft.mutex);WARN_ON (ipsec->tx_esw->ft.refcnt);kfree (ipsec->tx_esw);
@@ -1720,6 +1726,7 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)mutex_init (&ipsec->tx_esw->ft.mutex);mutex_init (&ipsec->rx_esw->ft.mutex); ipsec->tx_esw->ns = ns_esw; +xa_init_flags (&ipsec->rx_esw->ipsec_obj_id_map,XA_FLAGS_ALLOC1 ); }else if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_ROCE ) { ipsec->roce =mlx5_ipsec_fs_roce_init (mdev); }
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +22 -0
@@ -37,6 +37,7 @@#include "ipsec.h" #include "ipsec_rxtx.h" #include "en.h" +#include "esw/ipsec_fs.h" enum {MLX5E_IPSEC_TX_SYNDROME_OFFLOAD =0x8 ,
@@ -355,3 +356,24 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,atomic64_inc (&ipsec->sw_stats.ipsec_rx_drop_syndrome); } } + +int mlx5_esw_ipsec_rx_make_metadata (struct mlx5e_priv *priv,u32 id,u32 *metadata) +{ +struct mlx5e_ipsec *ipsec = priv->ipsec; +u32 ipsec_obj_id; +int err; + +if (!ipsec || !ipsec->is_uplink_rep) +return -EINVAL ; + + err =mlx5_esw_ipsec_rx_ipsec_obj_id_search (priv, id, &ipsec_obj_id); +if (err) { +atomic64_inc (&ipsec->sw_stats.ipsec_rx_drop_sadb_miss); +return err; + } + + *metadata =MLX5_IPSEC_METADATA_CREATE (ipsec_obj_id, +MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED ); + +return 0 ; +}
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h +2 -0
@@ -43,6 +43,7 @@#define MLX5_IPSEC_METADATA_MARKER (metadata) (((metadata) >> 31) & 0x1)#define MLX5_IPSEC_METADATA_SYNDROM (metadata) (((metadata) >> 24) & GENMASK(5, 0))#define MLX5_IPSEC_METADATA_HANDLE (metadata) ((metadata) & GENMASK(23, 0)) +#define MLX5_IPSEC_METADATA_CREATE (id, syndrome) ((id) | ((syndrome) << 24))struct mlx5e_accel_tx_ipsec_state {struct xfrm_offload *xo;
@@ -67,6 +68,7 @@ void mlx5e_ipsec_handle_tx_wqe(struct mlx5e_tx_wqe *wqe,void mlx5e_ipsec_offload_handle_rx_skb (struct net_device *netdev,struct sk_buff *skb,u32 ipsec_meta_data); +int mlx5_esw_ipsec_rx_make_metadata (struct mlx5e_priv *priv,u32 id,u32 *metadata);static inline unsigned int mlx5e_ipsec_tx_ids_len (struct mlx5e_accel_tx_ipsec_state *ipsec_st) {return ipsec_st->tailen;
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +69 -0
72 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h +20 -0
@@ -5,6 +5,7 @@#define __MLX5_ESW_IPSEC_FS_H__struct mlx5e_ipsec ; +struct mlx5e_ipsec_sa_entry ;#ifdef CONFIG_MLX5_ESWITCH void mlx5_esw_ipsec_rx_status_destroy(struct mlx5e_ipsec *ipsec,
@@ -16,6 +17,11 @@ void mlx5_esw_ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx_create_attr *attr);int mlx5_esw_ipsec_rx_status_pass_dest_get (struct mlx5e_ipsec *ipsec,struct mlx5_flow_destination *dest); +int mlx5_esw_ipsec_rx_setup_modify_header (struct mlx5e_ipsec_sa_entry *sa_entry, +struct mlx5_flow_act *flow_act); +void mlx5_esw_ipsec_rx_id_mapping_remove (struct mlx5e_ipsec_sa_entry *sa_entry); +int mlx5_esw_ipsec_rx_ipsec_obj_id_search (struct mlx5e_priv *priv,u32 id, +u32 *ipsec_obj_id);#else static inline void mlx5_esw_ipsec_rx_status_destroy (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx) {}
@@ -35,5 +41,19 @@ static inline int mlx5_esw_ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ips {return -EINVAL ; } + +static inline int mlx5_esw_ipsec_rx_setup_modify_header (struct mlx5e_ipsec_sa_entry *sa_entry, +struct mlx5_flow_act *flow_act) +{ +return -EINVAL ; +} + +static inline void mlx5_esw_ipsec_rx_id_mapping_remove (struct mlx5e_ipsec_sa_entry *sa_entry) {} + +static inline int mlx5_esw_ipsec_rx_ipsec_obj_id_search (struct mlx5e_priv *priv,u32 id, +u32 *ipsec_obj_id) +{ +return -EINVAL ; +}#endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESW_IPSEC_FS_H__ */
include/linux/mlx5/eswitch.h +3 -0
@@ -144,6 +144,9 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw,GENMASK (31 -ESW_TUN_ID_BITS -ESW_RESERVED_BITS , \ESW_TUN_OPTS_OFFSET +1 ) +/* reuse tun_opts for the mapped ipsec obj id when tun_id is 0 (invalid) */ +#define ESW_IPSEC_RX_MAPPED_ID_MASK GENMASK(ESW_TUN_OPTS_BITS - 1, 0) +u8 mlx5_eswitch_mode (const struct mlx5_core_dev *dev);u16 mlx5_eswitch_get_total_vports (const struct mlx5_core_dev *dev);struct mlx5_core_dev *mlx5_eswitch_get_core_dev (struct mlx5_eswitch *esw);
Signature · 1 line
2.41.0
PATCH 7/12 net/mlx5e: Refactor IPsec TX tables creation
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
Add attribute for IPsec TX creation, pass all needed parameters in it, so tx_create() can be used by eswitch.
--- .../mellanox/mlx5/core/en_accel/ipsec.h | 8 ++++++ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 26 ++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +8 -0
@@ -205,6 +205,14 @@ struct mlx5e_ipsec_rx {struct xarray ipsec_obj_id_map; }; +struct mlx5e_ipsec_tx_create_attr { +int prio; +int pol_level; +int sa_level; +int cnt_level; +enum mlx5_flow_namespace_type chains_ns; +}; +struct mlx5e_ipsec {struct mlx5_core_dev *mdev;struct xarray sadb;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +20 -6
@@ -569,15 +569,29 @@ static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,mlx5_destroy_flow_table (tx->ft.status); } -static int tx_create (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_tx *tx, +static void ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_tx *tx, +struct mlx5e_ipsec_tx_create_attr *attr) +{ + attr->prio =0 ; + attr->pol_level =0 ; + attr->sa_level =1 ; + attr->cnt_level =2 ; + attr->chains_ns =MLX5_FLOW_NAMESPACE_EGRESS_IPSEC ; +} + +static int tx_create (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx *tx,struct mlx5_ipsec_fs *roce) { +struct mlx5_core_dev *mdev = ipsec->mdev; +struct mlx5e_ipsec_tx_create_attr attr;struct mlx5_flow_destination dest = {};struct mlx5_flow_table *ft;u32 flags =0 ;int err; - ft =ipsec_ft_create (tx->ns,2 ,0 ,1 ,0 ); +ipsec_tx_create_attr_set (ipsec, tx, &attr); + ft =ipsec_ft_create (tx->ns, attr.cnt_level, attr.prio,1 ,0 );if (IS_ERR (ft))return PTR_ERR (ft); tx->ft.status = ft;
@@ -590,7 +604,7 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx, tx->allow_tunnel_mode =mlx5_eswitch_block_encap (mdev);if (tx->allow_tunnel_mode) flags =MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT ; - ft =ipsec_ft_create (tx->ns,1 ,0 ,4 , flags); + ft =ipsec_ft_create (tx->ns, attr.sa_level, attr.prio,4 , flags);if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_sa_ft;
@@ -599,7 +613,7 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_PRIO ) { tx->chains =ipsec_chains_create ( - mdev, tx->ft.sa,MLX5_FLOW_NAMESPACE_EGRESS_IPSEC ,0 ,0 , + mdev, tx->ft.sa, attr.chains_ns, attr.prio, attr.pol_level, &tx->ft.pol);if (IS_ERR (tx->chains)) { err =PTR_ERR (tx->chains);
@@ -609,7 +623,7 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx, goto connect_roce; } - ft =ipsec_ft_create (tx->ns,0 ,0 ,2 ,0 ); + ft =ipsec_ft_create (tx->ns, attr.pol_level, attr.prio,2 ,0 );if (IS_ERR (ft)) { err =PTR_ERR (ft); goto err_pol_ft;
@@ -656,7 +670,7 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,if (tx->ft.refcnt) goto skip; - err =tx_create (mdev, tx, ipsec->roce); + err =tx_create (ipsec, tx, ipsec->roce);if (err)return err;
Signature · 1 line
2.41.0
PATCH 8/12 net/mlx5e: Support IPsec packet offload for TX in switchdev mode
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
The IPsec encryption is done at the last, so add new prio for IPsec offload in FDB, and put it just lower than the slow path prio and higher than the per-vport prio.
Three levels are added for TX. The first one is for ip xfrm policy. The sa table is created in the second level for ip xfrm state. The status table is created at the last to count the number of packets encrypted.
The rules, which forward packets to uplink, are changed to forward them to IPsec TX tables first. These rules are restored after those tables are destroyed, which is done immediately when there is no reference to them, just as what does in legacy mode. The support for slow path is added here, by refreshing uplink's channels. But, the handling for TC fast path, which is more complicated, will be added later. Besides, reg c4 is used instead to match reqid.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 70 ++++++++++++++++--- .../mellanox/mlx5/core/esw/ipsec_fs.c | 16 +++++ .../mellanox/mlx5/core/esw/ipsec_fs.h | 5 ++ .../net/ethernet/mellanox/mlx5/core/eswitch.h | 1 + .../mellanox/mlx5/core/eswitch_offloads.c | 11 +++ .../net/ethernet/mellanox/mlx5/core/fs_core.c | 6 ++ include/linux/mlx5/fs.h | 1 + 7 files changed, 101 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +61 -9
@@ -10,6 +10,7 @@#include "lib/ipsec_fs_roce.h" #include "lib/fs_chains.h" #include "esw/ipsec_fs.h" +#include "en_rep.h" #define NUM_IPSEC_FTE BIT(15)#define MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE 16
@@ -23,6 +24,7 @@ struct mlx5e_ipsec_fc {struct mlx5e_ipsec_tx {struct mlx5e_ipsec_ft ft;struct mlx5e_ipsec_miss pol; +struct mlx5e_ipsec_miss sa;struct mlx5e_ipsec_rule status;struct mlx5_flow_namespace *ns;struct mlx5e_ipsec_fc *fc;
@@ -550,7 +552,7 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_ }/* IPsec TX flow steering */ -static void tx_destroy (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_tx *tx, +static void tx_destroy (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx *tx,struct mlx5_ipsec_fs *roce) {mlx5_ipsec_fs_roce_tx_destroy (roce);
@@ -562,9 +564,13 @@ static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,mlx5_destroy_flow_table (tx->ft.pol); } +if (tx == ipsec->tx_esw) { +mlx5_del_flow_rules (tx->sa.rule); +mlx5_destroy_flow_group (tx->sa.group); + }mlx5_destroy_flow_table (tx->ft.sa);if (tx->allow_tunnel_mode) -mlx5_eswitch_unblock_encap (mdev); +mlx5_eswitch_unblock_encap (ipsec->mdev);mlx5_del_flow_rules (tx->status.rule);mlx5_destroy_flow_table (tx->ft.status); }
@@ -573,6 +579,11 @@ static void ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx, struct mlx5e_ipsec_tx_create_attr *attr) { +if (tx == ipsec->tx_esw) { +mlx5_esw_ipsec_tx_create_attr_set (ipsec, attr); +return ; + } + attr->prio =0 ; attr->pol_level =0 ; attr->sa_level =1 ;
@@ -611,6 +622,15 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx, } tx->ft.sa = ft; +if (tx == ipsec->tx_esw) { + dest.type =MLX5_FLOW_DESTINATION_TYPE_VPORT ; + dest.vport.num =MLX5_VPORT_UPLINK ; + err =ipsec_miss_create (mdev, tx->ft.sa, &tx->sa, &dest); +if (err) + goto err_sa_miss; +memset (&dest,0 ,sizeof (dest)); + } +if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_PRIO ) { tx->chains = ipsec_chains_create( mdev, tx->ft.sa, attr.chains_ns, attr.prio, attr.pol_level,
@@ -652,6 +672,11 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,mlx5_destroy_flow_table (tx->ft.pol); } err_pol_ft: +if (tx == ipsec->tx_esw) { +mlx5_del_flow_rules (tx->sa.rule); +mlx5_destroy_flow_group (tx->sa.group); + } +err_sa_miss:mlx5_destroy_flow_table (tx->ft.sa); err_sa_ft:if (tx->allow_tunnel_mode)
@@ -662,6 +687,25 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,return err; } +static void ipsec_esw_tx_ft_policy_set (struct mlx5_core_dev *mdev, +struct mlx5_flow_table *ft) +{ +#ifdef CONFIG_MLX5_ESWITCH +struct mlx5_eswitch *esw = mdev->priv.eswitch; +struct mlx5e_rep_priv *uplink_rpriv; +struct mlx5e_priv *priv; + + esw->offloads.ft_ipsec_tx_pol = ft; + uplink_rpriv =mlx5_eswitch_get_uplink_priv (esw,REP_ETH ); + priv =netdev_priv (uplink_rpriv->netdev); +if (!priv->channels.num) +return ; + +mlx5e_rep_deactivate_channels (priv); +mlx5e_rep_activate_channels (priv); +#endif +} +static int tx_get (struct mlx5_core_dev *mdev,struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx *tx) {
@@ -674,6 +718,9 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,if (err)return err; +if (tx == ipsec->tx_esw) +ipsec_esw_tx_ft_policy_set (mdev, tx->ft.pol); + skip: tx->ft.refcnt++;return 0 ;
@@ -684,7 +731,10 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)if (--tx->ft.refcnt)return ; -tx_destroy (ipsec->mdev, tx, ipsec->roce); +if (tx == ipsec->tx_esw) +ipsec_esw_tx_ft_policy_set (ipsec->mdev,NULL ); + +tx_destroy (ipsec, tx, ipsec->roce); } static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,
@@ -842,15 +892,15 @@ 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) +static void setup_fte_reg_c4 (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_TO_ONES (fte_match_param, spec->match_criteria, + misc_parameters_2.metadata_reg_c_4);MLX5_SET (fte_match_param, spec->match_value, - misc_parameters_2.metadata_reg_c_0, reqid); + misc_parameters_2.metadata_reg_c_4, reqid); }static void setup_fte_upper_proto_match (struct mlx5_flow_spec *spec,struct upspec *upspec)
@@ -902,7 +952,7 @@ static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8break ;case XFRM_DEV_OFFLOAD_OUT :MLX5_SET (set_action_in, action, field, -MLX5_ACTION_IN_FIELD_METADATA_REG_C_0 ); +MLX5_ACTION_IN_FIELD_METADATA_REG_C_4 );break ;default :return -EINVAL ;
@@ -1235,7 +1285,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)break ;case XFRM_DEV_OFFLOAD_PACKET :if (attrs->reqid) -setup_fte_reg_c0 (spec, attrs->reqid); +setup_fte_reg_c4 (spec, attrs->reqid); err =setup_pkt_reformat (ipsec, attrs, &flow_act);if (err) goto err_pkt_reformat;
@@ -1346,6 +1396,8 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) } flow_act.flags |=FLOW_ACT_NO_APPEND ; +if (tx == ipsec->tx_esw && tx->chains) + flow_act.flags |=FLOW_ACT_IGNORE_FLOW_LEVEL ; dest[dstn].ft = tx->ft.sa; dest[dstn].type =MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ; dstn++;
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +16 -0
@@ -12,6 +12,12 @@ enum { MLX5_ESW_IPSEC_RX_ESP_FT_CHK_LEVEL, }; +enum { +MLX5_ESW_IPSEC_TX_POL_FT_LEVEL , +MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL , +MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL , +}; +static void esw_ipsec_rx_status_drop_destroy (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx) {
@@ -251,3 +257,13 @@ int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,return 0 ; } + +void mlx5_esw_ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_tx_create_attr *attr) +{ + attr->prio =FDB_CRYPTO_EGRESS ; + attr->pol_level =MLX5_ESW_IPSEC_TX_POL_FT_LEVEL ; + attr->sa_level =MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL ; + attr->cnt_level =MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL ; + attr->chains_ns =MLX5_FLOW_NAMESPACE_FDB ; +}
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h +5 -0
@@ -22,6 +22,8 @@ int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry,void mlx5_esw_ipsec_rx_id_mapping_remove (struct mlx5e_ipsec_sa_entry *sa_entry);int mlx5_esw_ipsec_rx_ipsec_obj_id_search (struct mlx5e_priv *priv,u32 id,u32 *ipsec_obj_id); +void mlx5_esw_ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_tx_create_attr *attr);#else static inline void mlx5_esw_ipsec_rx_status_destroy (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx) {}
@@ -55,5 +57,8 @@ static inline int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, {return -EINVAL ; } + +static inline void mlx5_esw_ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec, +struct mlx5e_ipsec_tx_create_attr *attr) {}#endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESW_IPSEC_FS_H__ */
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +1 -0
@@ -254,6 +254,7 @@ struct mlx5_esw_offload {struct mlx5_flow_group *vport_rx_group;struct mlx5_flow_group *vport_rx_drop_group;struct mlx5_flow_handle *vport_rx_drop_rule; +struct mlx5_flow_table *ft_ipsec_tx_pol;struct xarray vport_reps;struct list_head peer_flows[MLX5_MAX_PORTS ];struct mutex peer_mutex;
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +11 -0
@@ -884,6 +884,17 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw, dest.vport.flags |=MLX5_FLOW_DEST_VPORT_VHCA_ID ; flow_act.action =MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ; +if (rep->vport ==MLX5_VPORT_UPLINK && on_esw->offloads.ft_ipsec_tx_pol) { + dest.ft = on_esw->offloads.ft_ipsec_tx_pol; + flow_act.flags =FLOW_ACT_IGNORE_FLOW_LEVEL ; + dest.type =MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ; + }else { + dest.type =MLX5_FLOW_DESTINATION_TYPE_VPORT ; + dest.vport.num = rep->vport; + dest.vport.vhca_id =MLX5_CAP_GEN (rep->esw->dev, vhca_id); + dest.vport.flags |=MLX5_FLOW_DEST_VPORT_VHCA_ID ; + } +if (MLX5_CAP_ESW_FLOWTABLE (on_esw->dev, flow_source) && rep->vport ==MLX5_VPORT_UPLINK ) spec->flow_context.flow_source =MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT ;
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +6 -0
@@ -3015,6 +3015,12 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering) goto out_err; } + maj_prio =fs_create_prio (&steering->fdb_root_ns->ns,FDB_CRYPTO_EGRESS ,3 ); +if (IS_ERR (maj_prio)) { + err =PTR_ERR (maj_prio); + goto out_err; + } +/* We put this priority last, knowing that nothing will get here * unless explicitly forwarded to. This is possible because the * slow path tables have catch all rules and nothing gets passed
include/linux/mlx5/fs.h +1 -0
@@ -115,6 +115,7 @@ enum {FDB_TC_MISS ,FDB_BR_OFFLOAD ,FDB_SLOW_PATH , +FDB_CRYPTO_EGRESS , FDB_PER_VPORT, };
Signature · 1 line
2.41.0
PATCH 9/12 net/mlx5: Compare with old_dest param to modify rule destination
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
The rule destination must be comprared with the old_dest passed in.
--- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +1 -1
@@ -1066,7 +1066,7 @@ int mlx5_modify_rule_destination(struct mlx5_flow_handle *handle, }for (i =0 ; i < handle->num_rules; i++) { -if (mlx5_flow_dests_cmp (new_dest, &handle->rule[i]->dest_attr)) +if (mlx5_flow_dests_cmp (old_dest, &handle->rule[i]->dest_attr))return _mlx5_modify_rule_destination (handle->rule[i], new_dest); }
Signature · 1 line
2.41.0
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 5 lines · On Tue, 11 Jul 2023 12:29:07 +0300 Leon Romanovsky wrote:
From: Jianbo Liu <[email protected]>
The rule destination must be comprared with the
old_destpassed in.Fixes 74491de93712 ("net/mlx5: Add multi dest support")
This says Fixes, should I quickly toss it into net so it makes tomorrow's PR? The commit message is pretty useless :(
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 9 lines · Jakub Kicinski
Quoted 5 lines · On Tue, 11 Jul 2023 12:29:07 +0300 Leon Romanovsky wrote:
From: Jianbo Liu <[email protected]>
The rule destination must be comprared with the
old_destpassed in.Fixes 74491de93712 ("net/mlx5: Add multi dest support")This says Fixes, should I quickly toss it into net so it makes tomorrow's PR?
This is a fix, but it useful for this series only, which actually needs to modify flow steering rule destinations on the fly.
There is no other code in mlx5 which needs this fix.
Thanks
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 7 lines · On Thu, 13 Jul 2023 09:33:45 +0300 Leon Romanovsky wrote:
Quoted 2 lines
This says Fixes, should I quickly toss it into net so it makes tomorrow's PR?
This is a fix, but it useful for this series only, which actually needs to modify flow steering rule destinations on the fly.
There is no other code in mlx5 which needs this fix.
Reads like "can't be triggered with current code", in which case the right thing to do is to add "can't be triggered with current code" to the commit message, rather than the Fixes tag.
I had a look thru the series yesterday, and it looks good to me (tho I'm no ipsec expert). Thanks for putting in the work!
Could you add some info about how the code in the series can be exercised / example configurations? And please CC Simon, it'd be great to get him / someone at Corigine to review.
And obviously Steffen, why did you not CC Steffen?! :o
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 4 lines · Jakub Kicinski
Quoted 3 lines · On Thu, 13 Jul 2023 09:33:45 +0300 Leon Romanovsky wrote:
Quoted 2 lines
This says Fixes, should I quickly toss it into net so it makes tomorrow's PR?
Quoted 8 lines
Quoted 4 lines
This is a fix, but it useful for this series only, which actually needs to modify flow steering rule destinations on the fly.
There is no other code in mlx5 which needs this fix.
Reads like "can't be triggered with current code", in which case the right thing to do is to add "can't be triggered with current code" to the commit message, rather than the Fixes tag.
The code is wrong, so comes Fixes line, but I can remove it.
Quoted 9 lines
I had a look thru the series yesterday, and it looks good to me (tho I'm no ipsec expert). Thanks for putting in the work!
Could you add some info about how the code in the series can be exercised / example configurations? And please CC Simon, it'd be great to get him / someone at Corigine to review.
And obviously Steffen, why did you not CC Steffen?! :o
It works exactly like "regular" IPsec, nothing special, except now users can switch to switchdev before adding IPsec rules.
devlink dev eswitch set pci/0000:06:00.0 mode switchdev
Same configurations as here:
https://lore.kernel.org/netdev/[email protected]/
Packet offload mode:
ip xfrm state offload packet dev <if-name> dir <in|out> ip xfrm policy .... offload packet dev <if-name>
Crypto offload mode:
ip xfrm state offload crypto dev <if-name> dir <in|out>
or (backward compatibility)
ip xfrm state offload dev <if-name> dir <in|out>
I didn't add Steffen as it is more flow steering magic series and not IPsec :).
I'll resubmit on Sunday.
Thanks
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 5 lines · On Thu, 13 Jul 2023 20:43:17 +0300 Leon Romanovsky wrote:
Quoted 3 lines
Reads like "can't be triggered with current code", in which case the right thing to do is to add "can't be triggered with current code" to the commit message, rather than the Fixes tag.
The code is wrong, so comes Fixes line, but I can remove it.
Yes, perhaps after death we will inhabit a world with clear, non-conflicting rules, where law can be followed to the letter and "truth" and "good" are clearly and objectively defined.
Until the sweat release, tho, let's apply common sense, and not add Fixes tags to patches which can't possibly be of interest to backporters.
Please and thank you...
Quoted 14 lines
Quoted 8 lines
I had a look thru the series yesterday, and it looks good to me (tho I'm no ipsec expert). Thanks for putting in the work!
Could you add some info about how the code in the series can be exercised / example configurations? And please CC Simon, it'd be great to get him / someone at Corigine to review.
And obviously Steffen, why did you not CC Steffen?! :o
It works exactly like "regular" IPsec, nothing special, except now users can switch to switchdev before adding IPsec rules.
devlink dev eswitch set pci/0000:06:00.0 mode switchdev
Quoted 9 lines
Same configurations as here:
https://lore.kernel.org/netdev/[email protected]/
Packet offload mode:
ip xfrm state offload packet dev <if-name> dir <in|out> ip xfrm policy .... offload packet dev <if-name>
Crypto offload mode:
ip xfrm state offload crypto dev <if-name> dir <in|out>
or (backward compatibility)
ip xfrm state offload dev <if-name> dir <in|out>
I see, so all policy based IPsec?
Does the order of processing in the device match the kernel? TC packet rewrites or IPsec comes first?
Quoted 4 lines
I didn't add Steffen as it is more flow steering magic series and not IPsec :).
I'll resubmit on Sunday.
Thanks!
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 11 lines · Jakub Kicinski
Quoted 5 lines · On Thu, 13 Jul 2023 20:43:17 +0300 Leon Romanovsky wrote:
Quoted 3 lines
Reads like "can't be triggered with current code", in which case the right thing to do is to add "can't be triggered with current code" to the commit message, rather than the Fixes tag.
The code is wrong, so comes Fixes line, but I can remove it.
Yes, perhaps after death we will inhabit a world with clear, non-conflicting rules, where law can be followed to the letter and "truth" and "good" are clearly and objectively defined.
Quoted 5 lines
Until the sweat release, tho, let's apply common sense, and not add Fixes tags to patches which can't possibly be of interest to backporters.
Please and thank you...
Sure
Quoted 25 lines
Quoted 15 lines
Quoted 9 lines
I had a look thru the series yesterday, and it looks good to me (tho I'm no ipsec expert). Thanks for putting in the work!
Could you add some info about how the code in the series can be exercised / example configurations? And please CC Simon, it'd be great to get him / someone at Corigine to review.
And obviously Steffen, why did you not CC Steffen?! :o
It works exactly like "regular" IPsec, nothing special, except now users can switch to switchdev before adding IPsec rules.
devlink dev eswitch set pci/0000:06:00.0 mode switchdev
Quoted 9 lines
Same configurations as here:
https://lore.kernel.org/netdev/[email protected]/
Packet offload mode:
ip xfrm state offload packet dev <if-name> dir <in|out> ip xfrm policy .... offload packet dev <if-name>
Crypto offload mode:
ip xfrm state offload crypto dev <if-name> dir <in|out>
or (backward compatibility)
ip xfrm state offload dev <if-name> dir <in|out>
Quoted 1 line
I see, so all policy based IPsec?
Yes, it is.
Quoted 1 line
Does the order of processing in the device match the kernel?
Yes and this it why this fix was needed to make sure that we update destinations properly.
Quoted 1 line
TC packet rewrites or IPsec comes first?
In theory, we support any order, but in real life I don't think that TC before IPsec is really valuable.
Quoted 7 lines
Quoted 5 lines
I didn't add Steffen as it is more flow steering magic series and not IPsec :).
I'll resubmit on Sunday.
Thanks!
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 4 lines · On Thu, 13 Jul 2023 21:58:33 +0300 Leon Romanovsky wrote:
Quoted 1 line
TC packet rewrites or IPsec comes first?
In theory, we support any order, but in real life I don't think that TC before IPsec is really valuable.
I asked the question poorly. To clearer, you're saying that:
a) host <-> TC <-> IPsec <-> "wire"/switch
or
b) host <-> IPsec <-> TC <-> "wire"/switch
?
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 6 lines · Jakub Kicinski
Quoted 4 lines · On Thu, 13 Jul 2023 21:58:33 +0300 Leon Romanovsky wrote:
Quoted 1 line
TC packet rewrites or IPsec comes first?
In theory, we support any order, but in real life I don't think that TC before IPsec is really valuable.
Quoted 7 lines
I asked the question poorly. To clearer, you're saying that:
a) host <-> TC <-> IPsec <-> "wire"/switch
or
b) host <-> IPsec <-> TC <-> "wire"/switch?
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
Thanks
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 9 lines · On Fri, 14 Jul 2023 21:40:13 +0300 Leon Romanovsky wrote:
Quoted 9 lines
Quoted 2 lines
In theory, we support any order, but in real life I don't think that TC before IPsec is really valuable.
I asked the question poorly. To clearer, you're saying that:
a) host <-> TC <-> IPsec <-> "wire"/switch
or
b) host <-> IPsec <-> TC <-> "wire"/switch
Quoted 6 lines
Quoted 1 line
?
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
And only b) matches what happens in the kernel with policy based IPsec, right? So can we reject a) from happening? IIUC what you're saying - the result depending on order of configuration may be a major source of surprises / hard to debug problems for the user.
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 12 lines · Jakub Kicinski
Quoted 11 lines · On Fri, 14 Jul 2023 21:40:13 +0300 Leon Romanovsky wrote:
Quoted 10 lines
Quoted 2 lines
In theory, we support any order, but in real life I don't think that TC before IPsec is really valuable.
I asked the question poorly. To clearer, you're saying that:
a) host <-> TC <-> IPsec <-> "wire"/switch
or
b) host <-> IPsec <-> TC <-> "wire"/switch?
Quoted 7 lines
Quoted 4 lines
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
And only b) matches what happens in the kernel with policy based IPsec, right?
Can you please clarify what do you mean "policy based IPsec"?
Quoted 1 line
So can we reject a) from happening?
Technically yes.
Quoted 3 lines
IIUC what you're saying -
the result depending on order of configuration may be a major source of surprises / hard to debug problems for the user.
When I reviewed patches, I came exactly to an opposite conclusion :)
My rationale was that users who configure IPsec and TC are advanced users who knows their data flow and if they find a) option valuable, they can do it.
For example, a) allows to limit amount of data sent to IPsec engine.
I believe both a) and b) should be supported.
Thanks
Jakub Kicinski
maintainerRe: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 11 lines · On Fri, 14 Jul 2023 23:32:58 +0300 Leon Romanovsky wrote:
Quoted 8 lines · Jakub Kicinski
Quoted 4 lines · On Fri, 14 Jul 2023 21:40:13 +0300 Leon Romanovsky wrote:
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
And only b) matches what happens in the kernel with policy based IPsec, right?
Can you please clarify what do you mean "policy based IPsec"?
I mean without a separate xfrm netdev on which you can install TC rules of its own.
Quoted 6 lines
Quoted 3 lines
IIUC what you're saying -
the result depending on order of configuration may be a major source of surprises / hard to debug problems for the user.When I reviewed patches, I came exactly to an opposite conclusion :)
Quoted 7 lines
My rationale was that users who configure IPsec and TC are advanced users who knows their data flow and if they find a) option valuable, they can do it.
For example, a) allows to limit amount of data sent to IPsec engine.
I believe both a) and b) should be supported.
What does it take to switch between the modes?
Even if we want both modes we should have an explicit switch, I reckon. Or at least a way to read back what mode we ended up in.
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 8 lines · Jakub Kicinski
Quoted 7 lines · On Fri, 14 Jul 2023 23:32:58 +0300 Leon Romanovsky wrote:
Quoted 6 lines · Jakub Kicinski
Quoted 4 lines · On Fri, 14 Jul 2023 21:40:13 +0300 Leon Romanovsky wrote:
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
And only b) matches what happens in the kernel with policy based IPsec, right?
Can you please clarify what do you mean "policy based IPsec"?
I mean without a separate xfrm netdev on which you can install TC rules of its own.
I call it software IPsec.
Quoted 11 lines
Quoted 11 lines
Quoted 4 lines
IIUC what you're saying -
the result depending on order of configuration may be a major source of surprises / hard to debug problems for the user.When I reviewed patches, I came exactly to an opposite conclusion :)
My rationale was that users who configure IPsec and TC are advanced users who knows their data flow and if they find a) option valuable, they can do it.
Quoted 7 lines
Quoted 3 lines
For example, a) allows to limit amount of data sent to IPsec engine.
I believe both a) and b) should be supported.
What does it take to switch between the modes?
Even if we want both modes we should have an explicit switch, I reckon. Or at least a way to read back what mode we ended up in.
I had several internal discussions about how TC and IPsec should work together, and will need some time to think about proper implementation.
For now I'll add patch which makes TC and IPsec mutually exclusive.
Thanks
Quoted 1 line
Re: [PATCH net-next 09/12] net/mlx5: Compare with old_dest param to modify rule destination
Quoted 34 lines · Leon Romanovsky
Quoted 8 lines · Jakub Kicinski
Quoted 7 lines · On Fri, 14 Jul 2023 23:32:58 +0300 Leon Romanovsky wrote:
Quoted 6 lines · Jakub Kicinski
Quoted 4 lines · On Fri, 14 Jul 2023 21:40:13 +0300 Leon Romanovsky wrote:
It depends on configuration order, if user configures TC first, it will be a), if he/she configures IPsec first, it will be b).
I just think that option b) is really matters.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
And only b) matches what happens in the kernel with policy based IPsec, right?
Can you please clarify what do you mean "policy based IPsec"?
I mean without a separate xfrm netdev on which you can install TC rules of its own.
I call it software IPsec.
Quoted 15 lines
Quoted 14 lines
Quoted 4 lines
IIUC what you're saying -
the result depending on order of configuration may be a major source of surprises / hard to debug problems for the user.When I reviewed patches, I came exactly to an opposite conclusion :)
My rationale was that users who configure IPsec and TC are advanced users who knows their data flow and if they find a) option valuable, they can do it.
For example, a) allows to limit amount of data sent to IPsec engine.
I believe both a) and b) should be supported.
Quoted 8 lines
Quoted 3 lines
What does it take to switch between the modes?
Even if we want both modes we should have an explicit switch, I reckon. Or at least a way to read back what mode we ended up in.I had several internal discussions about how TC and IPsec should work together, and will need some time to think about proper implementation.
For now I'll add patch which makes TC and IPsec mutually exclusive.
Even this so called trivial patch is not so trivial in mlx5 current implementation. Jianbo is working on it.
Thanks
Quoted 5 lines
Thanks
Quoted 1 line
PATCH 10/12 net/mlx5e: Make IPsec offload work together with eswitch and TC
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
The eswitch mode is not allowed to change if there are any IPsec rules. Besides, by using mlx5_esw_try_lock() to get eswitch mode lock, IPsec rules are not allowed to be offloaded if there are any TC rules.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 59 ++++++++++++---- .../net/ethernet/mellanox/mlx5/core/eswitch.h | 14 ++++ .../mellanox/mlx5/core/eswitch_offloads.c | 70 +++++++++++++++++++ 3 files changed, 128 insertions(+), 15 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +44 -15
@@ -254,8 +254,6 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,mlx5_del_flow_rules (rx->sa.rule);mlx5_destroy_flow_group (rx->sa.group);mlx5_destroy_flow_table (rx->ft.sa); -if (rx->allow_tunnel_mode) -mlx5_eswitch_unblock_encap (mdev);if (rx == ipsec->rx_esw) {mlx5_esw_ipsec_rx_status_destroy (ipsec, rx); }else {
@@ -359,8 +357,6 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec, goto err_add;/* Create FT */ -if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_TUNNEL ) - rx->allow_tunnel_mode =mlx5_eswitch_block_encap (mdev);if (rx->allow_tunnel_mode) flags =MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT ; ft =ipsec_ft_create (attr.ns, attr.sa_level, attr.prio,2 , flags);
@@ -415,8 +411,6 @@ 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: -if (rx->allow_tunnel_mode) -mlx5_eswitch_unblock_encap (mdev);mlx5_del_flow_rules (rx->status.rule);mlx5_modify_header_dealloc (mdev, rx->status.modify_hdr); err_add:
@@ -434,13 +428,26 @@ static int rx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,if (rx->ft.refcnt) goto skip; +if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_TUNNEL ) + rx->allow_tunnel_mode =mlx5_eswitch_block_encap (mdev); + + err =mlx5_eswitch_block_mode_trylock (mdev); +if (err) + goto err_out; + err =rx_create (mdev, ipsec, rx, family); +mlx5_eswitch_block_mode_unlock (mdev, err);if (err) -return err; + goto err_out; skip: rx->ft.refcnt++;return 0 ; + +err_out: +if (rx->allow_tunnel_mode) +mlx5_eswitch_unblock_encap (mdev); +return err; } static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
@@ -449,7 +456,12 @@ static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,if (--rx->ft.refcnt)return ; +mlx5_eswitch_unblock_mode_lock (ipsec->mdev);rx_destroy (ipsec->mdev, ipsec, rx, family); +mlx5_eswitch_unblock_mode_unlock (ipsec->mdev); + +if (rx->allow_tunnel_mode) +mlx5_eswitch_unblock_encap (ipsec->mdev); } static struct mlx5e_ipsec_rx *rx_ft_get(struct mlx5_core_dev *mdev,
@@ -569,8 +581,6 @@ static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,mlx5_destroy_flow_group (tx->sa.group); }mlx5_destroy_flow_table (tx->ft.sa); -if (tx->allow_tunnel_mode) -mlx5_eswitch_unblock_encap (ipsec->mdev);mlx5_del_flow_rules (tx->status.rule);mlx5_destroy_flow_table (tx->ft.status); }
@@ -611,8 +621,6 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,if (err) goto err_status_rule; -if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_TUNNEL ) - tx->allow_tunnel_mode =mlx5_eswitch_block_encap (mdev);if (tx->allow_tunnel_mode) flags =MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT ; ft =ipsec_ft_create (tx->ns, attr.sa_level, attr.prio,4 , flags);
@@ -679,8 +687,6 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx, err_sa_miss:mlx5_destroy_flow_table (tx->ft.sa); err_sa_ft: -if (tx->allow_tunnel_mode) -mlx5_eswitch_unblock_encap (mdev);mlx5_del_flow_rules (tx->status.rule); err_status_rule:mlx5_destroy_flow_table (tx->ft.status);
@@ -714,16 +720,32 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,if (tx->ft.refcnt) goto skip; - err =tx_create (ipsec, tx, ipsec->roce); +if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_TUNNEL ) + tx->allow_tunnel_mode =mlx5_eswitch_block_encap (mdev); + + err =mlx5_eswitch_block_mode_trylock (mdev);if (err) -return err; + goto err_out; + + err =tx_create (ipsec, tx, ipsec->roce); +if (err) { +mlx5_eswitch_block_mode_unlock (mdev, err); + goto err_out; + }if (tx == ipsec->tx_esw)ipsec_esw_tx_ft_policy_set (mdev, tx->ft.pol); +mlx5_eswitch_block_mode_unlock (mdev, err); + skip: tx->ft.refcnt++;return 0 ; + +err_out: +if (tx->allow_tunnel_mode) +mlx5_eswitch_unblock_encap (mdev); +return err; }static void tx_put (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx *tx)
@@ -731,10 +753,17 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)if (--tx->ft.refcnt)return ; +mlx5_eswitch_unblock_mode_lock (ipsec->mdev); +if (tx == ipsec->tx_esw)ipsec_esw_tx_ft_policy_set (ipsec->mdev,NULL );tx_destroy (ipsec, tx, ipsec->roce); + +mlx5_eswitch_unblock_mode_unlock (ipsec->mdev); + +if (tx->allow_tunnel_mode) +mlx5_eswitch_unblock_encap (ipsec->mdev); } static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +14 -0
@@ -270,6 +270,7 @@ struct mlx5_esw_offload {u8 inline_mode;atomic64_t num_flows;u64 num_block_encap; +u64 num_block_mode;enum devlink_eswitch_encap_mode encap;struct ida vport_metadata_ida;unsigned int host_number;/* ECPF supports one external host */
@@ -789,6 +790,11 @@ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);bool mlx5_eswitch_block_encap (struct mlx5_core_dev *dev);void mlx5_eswitch_unblock_encap (struct mlx5_core_dev *dev); +int mlx5_eswitch_block_mode_trylock (struct mlx5_core_dev *dev); +void mlx5_eswitch_block_mode_unlock (struct mlx5_core_dev *dev,int err); +void mlx5_eswitch_unblock_mode_lock (struct mlx5_core_dev *dev); +void mlx5_eswitch_unblock_mode_unlock (struct mlx5_core_dev *dev); +static inline int mlx5_eswitch_num_vfs (struct mlx5_eswitch *esw) {if (mlx5_esw_allowed (esw))
@@ -867,6 +873,14 @@ static inline bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev)static inline void mlx5_eswitch_unblock_encap (struct mlx5_core_dev *dev) { } + +static inline int mlx5_eswitch_block_mode_trylock (struct mlx5_core_dev *dev) {return 0 ; } + +static inline void mlx5_eswitch_block_mode_unlock (struct mlx5_core_dev *dev,int err) {} + +static inline void mlx5_eswitch_unblock_mode_lock (struct mlx5_core_dev *dev) {} + +static inline void mlx5_eswitch_unblock_mode_unlock (struct mlx5_core_dev *dev) {}#endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESWITCH_H__ */
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +70 -0
82 lines not on this page · raw message
Signature · 1 line
2.41.0
PATCH 11/12 net/mlx5e: Modify and restore TC rules for IPSec TX rules
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
After IPsec policy/state TX rules are added, any TC flow rule, which forwards packets to uplink, is modified to forward to IPsec TX tables. As these tables are destroyed dynamically, whenever there is no reference to them, the destinations of this kind of rules must be restored to uplink.
There is a special case for packet encapsulation, as the packet_reformat_id in the extended destination is used to reformat packets, but only for the VPORT destination. To forward packet to IPsec table and do encapsulation in one FTE, move the packet_reformat_id to flow context, instead of using the extended destination. As a limitation, multiple encapsulations with table forwarding, and one together with other VPORT destinations, are not allowed, so add a check when offloading TC rules.
TC rules are not allowed before IPsec TX rule is added, so only need to restore TC rules after flush IPSec TX rules. As they are saved in the vport_rep rhashtables, we walk all the rules in the rhashtables, and find TC rules with destinations pointing to IPsec tables, and modify them one by one. To avoid concurrent issue, this handling is done under the protection of eswitch mode_lock.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 4 +- .../mellanox/mlx5/core/esw/ipsec_fs.c | 56 +++++++++++ .../mellanox/mlx5/core/esw/ipsec_fs.h | 3 + .../net/ethernet/mellanox/mlx5/core/eswitch.h | 2 + .../mellanox/mlx5/core/eswitch_offloads.c | 93 ++++++++++++++++++- 5 files changed, 154 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +3 -1
@@ -755,8 +755,10 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)mlx5_eswitch_unblock_mode_lock (ipsec->mdev); -if (tx == ipsec->tx_esw) +if (tx == ipsec->tx_esw) { +mlx5_esw_ipsec_restore_dest_uplink (ipsec->mdev);ipsec_esw_tx_ft_policy_set (ipsec->mdev,NULL ); + }tx_destroy (ipsec, tx, ipsec->roce);
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c +56 -0
65 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h +3 -0
@@ -24,6 +24,7 @@ int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id, u32 *ipsec_obj_id);void mlx5_esw_ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx_create_attr *attr); +void mlx5_esw_ipsec_restore_dest_uplink (struct mlx5_core_dev *mdev);#else static inline void mlx5_esw_ipsec_rx_status_destroy (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_rx *rx) {}
@@ -60,5 +61,7 @@ static inline int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv,static inline void mlx5_esw_ipsec_tx_create_attr_set (struct mlx5e_ipsec *ipsec,struct mlx5e_ipsec_tx_create_attr *attr) {} + +static inline void mlx5_esw_ipsec_restore_dest_uplink (struct mlx5_core_dev *mdev) {}#endif /* CONFIG_MLX5_ESWITCH */ #endif /* __MLX5_ESW_IPSEC_FS_H__ */
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +2 -0
@@ -816,6 +816,8 @@ mlx5_eswitch_get_slow_fdb(struct mlx5_eswitch *esw) return esw->fdb_table.offloads.slow_fdb; } +int mlx5_eswitch_restore_ipsec_rule (struct mlx5_eswitch *esw,struct mlx5_flow_handle *rule, +struct mlx5_esw_flow_attr *esw_attr,int attr_idx);#else /* CONFIG_MLX5_ESWITCH */ /* eswitch API stubs */ static inline int mlx5_eswitch_init (struct mlx5_core_dev *dev) {return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +90 -3
115 lines not on this page · raw message
Signature · 1 line
2.41.0
PATCH 12/12 net/mlx5e: Add get IPsec offload stats for uplink representor
In reply to Leon RomanovskyFrom: Jianbo Liu <[email protected]>
As IPsec offload is supported in switchdev mode, HW stats can be can be obtained from uplink rep.
--- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +1 -0
@@ -1341,6 +1341,7 @@ static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = { &MLX5E_STATS_GRP (channels), &MLX5E_STATS_GRP (per_port_buff_congest), #ifdef CONFIG_MLX5_EN_IPSEC + &MLX5E_STATS_GRP (ipsec_hw), &MLX5E_STATS_GRP (ipsec_sw), #endif &MLX5E_STATS_GRP(ptp),
Signature · 1 line
2.41.0