Extend packet offload to fully support libreswan
Subsystems (6)
cover Extend packet offload to fully support libreswan
From: Leon Romanovsky <[email protected]>
Hi Steffen,
The following patches are an outcome of Raed's work to add packet offload support to libreswan [1].
The series includes:
* Priority support to IPsec policies
* Statistics per-SA (visible through "ip -s xfrm state ..." command)
* Support to IKE policy holes
* Fine tuning to acquire logic.
--------------------------
Future submission roadmap, which can be seen here [2]:
* Support packet offload in IPsec tunnel mode
* Rework lifetime counters support to avoid HW bugs/limitations
* Some general cleanup.
So how do you want me to route the patches, as they have a dependency between them? xfrm-next/net-next/mlx5-next?
Thanks
[1] https://github.com/libreswan/libreswan/pull/986q
[2] https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/log/?h=xfrm-next
Paul Blakey (3):
net/mlx5: fs_chains: Refactor to detach chains from tc usage net/mlx5: fs_core: Allow ignore_flow_level on TX dest net/mlx5e: Use chains for IPsec policy priority offload
Raed Salem (6):
xfrm: add new device offload acquire flag
xfrm: copy_to_user_state fetch offloaded SA packets/bytes statistics net/mlx5e: Allow policies with reqid 0, to support IKE policy holes net/mlx5e: Support IPsec acquire default SA
net/mlx5e: Use one rule to count all IPsec Tx offloaded traffic net/mlx5e: Update IPsec per SA packets/bytes count
.../mellanox/mlx5/core/en_accel/ipsec.c | 71 ++- .../mellanox/mlx5/core/en_accel/ipsec.h | 13 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 528 ++++++++++++++---- .../mlx5/core/en_accel/ipsec_offload.c | 32 +- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 20 +- .../mellanox/mlx5/core/eswitch_offloads.c | 6 +- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 5 +- .../mellanox/mlx5/core/lib/fs_chains.c | 89 ++- .../mellanox/mlx5/core/lib/fs_chains.h | 9 +- include/net/xfrm.h | 5 + net/xfrm/xfrm_state.c | 1 + net/xfrm/xfrm_user.c | 2 + 12 files changed, 553 insertions(+), 228 deletions(-)
Signature · 1 line
2.39.2
PATCH 1/9 net/mlx5: fs_chains: Refactor to detach chains from tc usage
From: Paul Blakey <[email protected]>
To support more generic chains that will be used on other namespaces and without tc, refactor to remove the dependency on tc terms.
--- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 20 +---- .../mellanox/mlx5/core/eswitch_offloads.c | 6 +- .../mellanox/mlx5/core/lib/fs_chains.c | 89 +++++++++---------- .../mellanox/mlx5/core/lib/fs_chains.h | 9 +- 4 files changed, 55 insertions(+), 69 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +3 -17
@@ -5186,22 +5186,6 @@ static int mlx5e_tc_netdev_event(struct notifier_block *this,return NOTIFY_DONE ; } -static int mlx5e_tc_nic_get_ft_size (struct mlx5_core_dev *dev) -{ -int tc_grp_size, tc_tbl_size; -u32 max_flow_counter; - - max_flow_counter = (MLX5_CAP_GEN (dev, max_flow_counter_31_16) <<16 ) | -MLX5_CAP_GEN (dev, max_flow_counter_15_0); - - tc_grp_size =min_t (int, max_flow_counter,MLX5E_TC_TABLE_MAX_GROUP_SIZE ); - - tc_tbl_size =min_t (int, tc_grp_size *MLX5E_TC_TABLE_NUM_GROUPS , -BIT (MLX5_CAP_FLOWTABLE_NIC_RX (dev, log_max_ft_size))); - -return tc_tbl_size; -} -static int mlx5e_tc_nic_create_miss_table (struct mlx5e_priv *priv) {struct mlx5e_tc_table *tc =mlx5e_fs_get_tc (priv->fs);
@@ -5274,10 +5258,10 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv) attr.flags =MLX5_CHAINS_AND_PRIOS_SUPPORTED |MLX5_CHAINS_IGNORE_FLOW_LEVEL_SUPPORTED ; attr.ns =MLX5_FLOW_NAMESPACE_KERNEL ; - attr.max_ft_sz =mlx5e_tc_nic_get_ft_size (dev); attr.max_grp_num =MLX5E_TC_TABLE_NUM_GROUPS ; attr.default_ft = tc->miss_t; attr.mapping = chains_mapping; + attr.fs_base_prio =MLX5E_TC_PRIO ; tc->chains =mlx5_chains_create (dev, &attr);if (IS_ERR (tc->chains)) {
@@ -5285,6 +5269,8 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv) goto err_miss; } +mlx5_chains_print_info (tc->chains); + tc->post_act =mlx5e_tc_post_act_init (priv, tc->chains,MLX5_FLOW_NAMESPACE_KERNEL ); tc->ct =mlx5_tc_ct_init (priv, tc->chains, &tc->mod_hdr,MLX5_FLOW_NAMESPACE_KERNEL , tc->post_act);
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +2 -4
@@ -1374,14 +1374,11 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb)struct mlx5_flow_table *nf_ft, *ft;struct mlx5_chains_attr attr = {};struct mlx5_fs_chains *chains; -u32 fdb_max;int err; - fdb_max =1 <<MLX5_CAP_ESW_FLOWTABLE_FDB (dev, log_max_ft_size); -esw_init_chains_offload_flags (esw, &attr.flags); attr.ns =MLX5_FLOW_NAMESPACE_FDB ; - attr.max_ft_sz = fdb_max; + attr.fs_base_prio =FDB_TC_OFFLOAD ; attr.max_grp_num = esw->params.large_group_num; attr.default_ft = miss_fdb; attr.mapping = esw->offloads.reg_c0_obj_pool;
@@ -1392,6 +1389,7 @@ esw_chains_create(struct mlx5_eswitch *esw, struct mlx5_flow_table *miss_fdb)esw_warn (dev,"Failed to create fdb chains err(%d)\n" , err);return err; } +mlx5_chains_print_info (chains); esw->fdb_table.offloads.esw_chains_priv = chains;
drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +43 -46
186 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.h +7 -2
@@ -17,8 +17,9 @@ enum mlx5_chains_flags {struct mlx5_chains_attr {enum mlx5_flow_namespace_type ns; +int fs_base_prio; +int fs_base_level;u32 flags; -u32 max_ft_sz;u32 max_grp_num;struct mlx5_flow_table *default_ft;struct mapping_ctx *mapping;
@@ -68,6 +69,8 @@ void mlx5_chains_destroy(struct mlx5_fs_chains *chains);void mlx5_chains_set_end_ft (struct mlx5_fs_chains *chains,struct mlx5_flow_table *ft); +void +mlx5_chains_print_info (struct mlx5_fs_chains *chains);#else /* CONFIG_MLX5_CLS_ACT */
@@ -89,7 +92,9 @@ static inline struct mlx5_fs_chains * mlx5_chains_create(struct mlx5_core_dev *dev, struct mlx5_chains_attr *attr) {return NULL ; }static inline void -mlx5_chains_destroy (struct mlx5_fs_chains *chains) {}; +mlx5_chains_destroy (struct mlx5_fs_chains *chains) {} +static inline void +mlx5_chains_print_info (struct mlx5_fs_chains *chains) {}#endif /* CONFIG_MLX5_CLS_ACT */
Signature · 1 line
2.39.2
PATCH 2/9 net/mlx5: fs_core: Allow ignore_flow_level on TX dest
In reply to Leon RomanovskyFrom: Paul Blakey <[email protected]>
ignore_flow_level is also supported by firmware on TX, remove this limitation.
--- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +2 -1
@@ -1762,7 +1762,8 @@ static bool dest_is_valid(struct mlx5_flow_destination *dest,if (ignore_level) {if (ft->type !=FS_FT_FDB && - ft->type !=FS_FT_NIC_RX ) + ft->type !=FS_FT_NIC_RX && + ft->type !=FS_FT_NIC_TX )return false; if (dest->type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE &&
Signature · 1 line
2.39.2
PATCH 3/9 net/mlx5e: Use chains for IPsec policy priority offload
In reply to Leon RomanovskyFrom: Paul Blakey <[email protected]>
Currently, policy priority field is ignored and so order of matching is unpredictable.
Use chains for RX/TX policy offload to support the priority field.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 18 +- .../mellanox/mlx5/core/en_accel/ipsec.h | 2 + .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 362 ++++++++++++++---- .../mlx5/core/en_accel/ipsec_offload.c | 17 +- 4 files changed, 315 insertions(+), 84 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +16 -2
@@ -499,7 +499,8 @@ static void mlx5e_xfrm_update_curlft(struct xfrm_state *x)mlx5e_ipsec_aso_update_curlft (sa_entry, &x->curlft.packets); } -static int mlx5e_xfrm_validate_policy (struct xfrm_policy *x, +static int mlx5e_xfrm_validate_policy (struct mlx5_core_dev *mdev, +struct xfrm_policy *x,struct netlink_ext_ack *extack) {if (x->type !=XFRM_POLICY_TYPE_MAIN ) {
@@ -535,6 +536,18 @@ static int mlx5e_xfrm_validate_policy(struct xfrm_policy *x,return -EINVAL ; } +if (x->priority) { +if (!(mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_PRIO )) { +NL_SET_ERR_MSG_MOD (extack,"Device does not support policy priority" ); +return -EINVAL ; + } + +if (x->priority ==U32_MAX ) { +NL_SET_ERR_MSG_MOD (extack,"Device does not support requested policy priority" ); +return -EINVAL ; + } + } +return 0 ; }
@@ -560,6 +573,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry, attrs->upspec.sport =ntohs (sel->sport); attrs->upspec.sport_mask =ntohs (sel->sport_mask); attrs->upspec.proto = sel->proto; + attrs->prio = x->priority; } static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
@@ -576,7 +590,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,return -EOPNOTSUPP ; } - err =mlx5e_xfrm_validate_policy (x, extack); + err =mlx5e_xfrm_validate_policy (priv->mdev, x, extack);if (err)return err;
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +2 -0
@@ -94,6 +94,7 @@ enum mlx5_ipsec_cap {MLX5_IPSEC_CAP_ESN =1 <<1 ,MLX5_IPSEC_CAP_PACKET_OFFLOAD =1 <<2 ,MLX5_IPSEC_CAP_ROCE =1 <<3 , + MLX5_IPSEC_CAP_PRIO = 1 << 4, };struct mlx5e_priv ;
@@ -198,6 +199,7 @@ struct mlx5_accel_pol_xfrm_attrs { u8 type : 2; u8 dir : 2;u32 reqid; +u32 prio; };struct mlx5e_ipsec_pol_entry {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +285 -77
554 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +12 -5
@@ -36,11 +36,18 @@ 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 ; -if (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_PACKET_OFFLOAD ; +if (MLX5_CAP_IPSEC (mdev, ipsec_full_offload)) { +if (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_PACKET_OFFLOAD ; + +if (MLX5_CAP_FLOWTABLE_NIC_TX (mdev, ignore_flow_level) && +MLX5_CAP_FLOWTABLE_NIC_RX (mdev, ignore_flow_level)) + caps |=MLX5_IPSEC_CAP_PRIO ; + } if (mlx5_get_roce_state(mdev) && MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) & MLX5_FT_NIC_RX_2_NIC_RX_RDMA &&
Signature · 1 line
2.39.2
PATCH 4/9 xfrm: add new device offload acquire flag
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
During XFRM acquire flow, a default SA is created to be updated later, once acquire netlink message is handled in user space. When the relevant policy is offloaded this default SA is also offloaded to IPsec offload supporting driver, however this SA does not have context suitable for offloading in HW, nor is interesting to offload to HW, consequently needs a special driver handling apart from other offloaded SA(s). Add a special flag that marks such SA so driver can handle it correctly.
--- include/net/xfrm.h | 5 +++++ net/xfrm/xfrm_state.c | 1 + 2 files changed, 6 insertions(+)
include/net/xfrm.h +5 -0
@@ -138,6 +138,10 @@ enum { XFRM_DEV_OFFLOAD_PACKET, }; +enum { +XFRM_DEV_OFFLOAD_FLAG_ACQ =1 , +}; +struct xfrm_dev_offload {struct net_device *dev;netdevice_tracker dev_tracker;
@@ -145,6 +149,7 @@ struct xfrm_dev_offload {unsigned long offload_handle; u8 dir : 2; u8 type : 2; + u8 flags : 2; };struct xfrm_mode {
net/xfrm/xfrm_state.c +1 -0
@@ -1272,6 +1272,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, xso->dir = xdo->dir; xso->dev = xdo->dev; xso->real_dev = xdo->real_dev; + xso->flags =XFRM_DEV_OFFLOAD_FLAG_ACQ ;netdev_tracker_alloc (xso->dev, &xso->dev_tracker,GFP_ATOMIC ); error = xso->dev->xfrmdev_ops->xdo_dev_state_add (x,NULL );
Signature · 1 line
2.39.2
Re: [PATCH xfrm-next 4/9] xfrm: add new device offload acquire flag
Quoted 10 lines · Leon Romanovsky
From: Raed Salem <[email protected]>
During XFRM acquire flow, a default SA is created to be updated later, once acquire netlink message is handled in user space. When the relevant policy is offloaded this default SA is also offloaded to IPsec offload supporting driver, however this SA does not have context suitable for offloading in HW, nor is interesting to offload to HW, consequently needs a special driver handling apart from other offloaded SA(s). Add a special flag that marks such SA so driver can handle it correctly.
Quoted 2 lines
Signed-off-by Raed Salem <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>
PATCH 5/9 xfrm: copy_to_user_state fetch offloaded SA packets/bytes statistics
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Both in RX and TX, the traffic that performs IPsec packet offload transformation is accounted by HW only. Consequently, the HW should be queried for packets/bytes statistics when user asks for such transformation data.
--- net/xfrm/xfrm_user.c | 2 ++ 1 file changed, 2 insertions(+)
net/xfrm/xfrm_user.c +2 -0
@@ -901,6 +901,8 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)memcpy (&p->id, &x->id,sizeof (p->id));memcpy (&p->sel, &x->sel,sizeof (p->sel));memcpy (&p->lft, &x->lft,sizeof (p->lft)); +if (x->xso.dev) +xfrm_dev_state_update_curlft (x);memcpy (&p->curlft, &x->curlft,sizeof (p->curlft));put_unaligned (x->stats.replay_window, &p->stats.replay_window);put_unaligned (x->stats.replay, &p->stats.replay);
Signature · 1 line
2.39.2
Re: [PATCH xfrm-next 5/9] xfrm: copy_to_user_state fetch offloaded SA packets/bytes statistics
Quoted 9 lines · Leon Romanovsky
From: Raed Salem <[email protected]>
Both in RX and TX, the traffic that performs IPsec packet offload transformation is accounted by HW only. Consequently, the HW should be queried for packets/bytes statistics when user asks for such transformation data.
Signed-off-by Raed Salem <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>
PATCH 6/9 net/mlx5e: Allow policies with reqid 0, to support IKE policy holes
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
IKE policies hole, is special policy that exists to allow for IKE traffic to bypass IPsec encryption even though there is already a policies and SA(s) configured on same endpoints, these policies does not nessecarly have the reqid configured, so need to add an exception for such policies. These kind of policies are allowed under the condition that at least upper protocol and/or ips are not 0.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 11 +-- .../mellanox/mlx5/core/en_accel/ipsec.h | 7 ++ .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 68 ++++++++++++------- 3 files changed, 59 insertions(+), 27 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +7 -4
@@ -503,6 +503,8 @@ static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,struct xfrm_policy *x, struct netlink_ext_ack *extack) { + struct xfrm_selector *sel = &x->selector; +if (x->type !=XFRM_POLICY_TYPE_MAIN ) {NL_SET_ERR_MSG_MOD (extack,"Cannot offload non-main policy types" );return -EINVAL ;
@@ -520,8 +522,9 @@ static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,return -EINVAL ; } -if (!x->xfrm_vec[0 ].reqid) { -NL_SET_ERR_MSG_MOD (extack,"Cannot offload policy without reqid" ); +if (!x->xfrm_vec[0 ].reqid && sel->proto ==IPPROTO_IP && +addr6_all_zero (sel->saddr.a6) &&addr6_all_zero (sel->daddr.a6)) { +NL_SET_ERR_MSG_MOD (extack,"Unsupported policy with reqid 0 without at least one of upper protocol or ip addr(s) different than 0" );return -EINVAL ; }
@@ -530,8 +533,8 @@ static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,return -EINVAL ; } -if (x->selector.proto !=IPPROTO_IP && - (x->selector.proto !=IPPROTO_UDP || x->xdo.dir !=XFRM_DEV_OFFLOAD_OUT )) { +if (sel->proto !=IPPROTO_IP && + (sel->proto !=IPPROTO_UDP || x->xdo.dir !=XFRM_DEV_OFFLOAD_OUT )) {NL_SET_ERR_MSG_MOD (extack,"Device does not support upper protocol other than UDP, and only Tx direction" );return -EINVAL ; }
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +7 -0
@@ -254,6 +254,13 @@ mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry *pol_entry) {return pol_entry->ipsec->mdev; } + +static inline bool addr6_all_zero (__be32 *addr6) +{ +static const __be32 zaddr6[4 ] = {}; + +return !memcmp (addr6, zaddr6,sizeof (*zaddr6)); +}#else static inline void mlx5e_ipsec_init (struct mlx5e_priv *priv) {
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +45 -23
113 lines not on this page · raw message
Signature · 1 line
2.39.2
PATCH 7/9 net/mlx5e: Support IPsec acquire default SA
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
During XFRM stack acquire flow, a default SA is created to be updated later, once acquire netlink message is handled in user space.
This SA is also passed to IPsec offload supporting driver, however this SA acts only as placeholder and does not have context suitable for offloading in HW yet. Identify this kind of SA by special offload flag (XFRM_DEV_OFFLOAD_FLAG_ACQ), and create a SW only context.
In such cases with special mark so it won't be installed in HW in addition flow and on remove/delete free this SW only context.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +21 -5
@@ -308,6 +308,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,struct net_device *netdev = x->xso.real_dev;struct mlx5e_ipsec *ipsec;struct mlx5e_priv *priv; +gfp_t gfp;int err; priv =netdev_priv (netdev);
@@ -315,16 +316,20 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,return -EOPNOTSUPP ; ipsec = priv->ipsec; - err =mlx5e_xfrm_validate_state (priv->mdev, x, extack); -if (err) -return err; - - sa_entry =kzalloc (sizeof (*sa_entry),GFP_KERNEL ); + gfp = (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ ) ?GFP_ATOMIC :GFP_KERNEL ; + sa_entry =kzalloc (sizeof (*sa_entry), gfp);if (!sa_entry)return -ENOMEM ; sa_entry->x = x; sa_entry->ipsec = ipsec; +/* Check if this SA is originated from acquire flow temporary SA */ +if (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ ) + goto out; + + err =mlx5e_xfrm_validate_state (priv->mdev, x, extack); +if (err) + goto err_xfrm;/* check esn */ mlx5e_ipsec_update_esn_state (sa_entry);
@@ -353,6 +358,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, mlx5e_ipsec_set_iv_esn : mlx5e_ipsec_set_iv;INIT_WORK (&sa_entry->modify_work.work, _update_xfrm_state); +out: x->xso.offload_handle = (unsigned long )sa_entry;return 0 ;
@@ -372,6 +378,9 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)struct mlx5e_ipsec *ipsec = sa_entry->ipsec;struct mlx5e_ipsec_sa_entry *old; +if (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ ) +return ; + old =xa_erase_bh (&ipsec->sadb, sa_entry->ipsec_obj_id);WARN_ON (old != sa_entry); }
@@ -380,9 +389,13 @@ static void mlx5e_xfrm_free_state(struct xfrm_state *x) {struct mlx5e_ipsec_sa_entry *sa_entry =to_ipsec_sa_entry (x); +if (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ ) + goto sa_entry_free; +cancel_work_sync (&sa_entry->modify_work.work);mlx5e_accel_ipsec_fs_del_rule (sa_entry);mlx5_ipsec_free_sa_ctx (sa_entry); +sa_entry_free:kfree (sa_entry); }
@@ -486,6 +499,9 @@ static void mlx5e_xfrm_update_curlft(struct xfrm_state *x)lockdep_assert_held (&x->lock); +if (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ ) +return ; +if (sa_entry->attrs.soft_packet_limit ==XFRM_INF )/* Limits are not configured, as soft limit * must be lowever than hard limit.
Signature · 1 line
2.39.2
PATCH 8/9 net/mlx5e: Use one rule to count all IPsec Tx offloaded traffic
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Currently one counter is shared between all IPsec Tx offloaded rules to count the total amount of packets/bytes that was IPsec Tx offloaded, replace this scheme by adding a new flow table (ft) with one rule that counts all flows that passes through this table (like Rx status ft), this ft is pointed by all IPsec Tx offloaded rules. The above allows to have a counter per tx flow rule in while keeping a separate global counter that store the aggregation outcome of all these per flow counters.
--- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 58 +++++++++++++++++-- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +- 2 files changed, 55 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +54 -4
@@ -41,6 +41,7 @@ struct mlx5e_ipsec_rx {struct mlx5e_ipsec_tx {struct mlx5e_ipsec_ft ft;struct mlx5e_ipsec_miss pol; +struct mlx5e_ipsec_rule status;struct mlx5_flow_namespace *ns;struct mlx5e_ipsec_fc *fc;struct mlx5_fs_chains *chains;
@@ -455,6 +456,39 @@ static void rx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 family, u32 prio)mutex_unlock (&rx->ft.mutex); } +static int ipsec_counter_rule_tx (struct mlx5_core_dev *mdev,struct mlx5e_ipsec_tx *tx) +{ +struct mlx5_flow_destination dest = {}; +struct mlx5_flow_act flow_act = {}; +struct mlx5_flow_handle *fte; +struct mlx5_flow_spec *spec; +int err; + + spec =kvzalloc (sizeof (*spec),GFP_KERNEL ); +if (!spec) +return -ENOMEM ; + +/* create fte */ + flow_act.action =MLX5_FLOW_CONTEXT_ACTION_ALLOW | +MLX5_FLOW_CONTEXT_ACTION_COUNT ; + dest.type =MLX5_FLOW_DESTINATION_TYPE_COUNTER ; + dest.counter_id =mlx5_fc_id (tx->fc->cnt); + fte =mlx5_add_flow_rules (tx->ft.status, spec, &flow_act, &dest,1 ); +if (IS_ERR (fte)) { + err =PTR_ERR (fte); +mlx5_core_err (mdev,"Fail to add ipsec tx counter rule err=%d\n" , err); + goto err_rule; + } + +kvfree (spec); + tx->status.rule = fte; +return 0 ; + +err_rule: +kvfree (spec); +return err; +} +/* IPsec TX flow steering */ static void tx_destroy (struct mlx5e_ipsec_tx *tx,struct mlx5_ipsec_fs *roce) {
@@ -468,6 +502,8 @@ static void tx_destroy(struct mlx5e_ipsec_tx *tx, struct mlx5_ipsec_fs *roce) }mlx5_destroy_flow_table (tx->ft.sa); +mlx5_del_flow_rules (tx->status.rule); +mlx5_destroy_flow_table (tx->ft.status); } static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
@@ -477,10 +513,20 @@ 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 (tx->ns,1 ,0 ,4 ); + ft =ipsec_ft_create (tx->ns,2 ,0 ,1 );if (IS_ERR (ft))return PTR_ERR (ft); + tx->ft.status = ft; + err =ipsec_counter_rule_tx (mdev, tx); +if (err) + goto err_status_rule; + + ft =ipsec_ft_create (tx->ns,1 ,0 ,4 ); +if (IS_ERR (ft)) { + err =PTR_ERR (ft); + goto err_sa_ft; + } tx->ft.sa = ft;if (mlx5_ipsec_device_caps (mdev) &MLX5_IPSEC_CAP_PRIO ) {
@@ -525,6 +571,10 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx, } err_pol_ft:mlx5_destroy_flow_table (tx->ft.sa); +err_sa_ft: +mlx5_del_flow_rules (tx->status.rule); +err_status_rule: +mlx5_destroy_flow_table (tx->ft.status);return err; }
@@ -949,11 +999,11 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) flow_act.crypto.type =MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_IPSEC ; flow_act.crypto.obj_id = sa_entry->ipsec_obj_id; flow_act.flags |=FLOW_ACT_NO_APPEND ; - flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_ALLOW | + flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |MLX5_FLOW_CONTEXT_ACTION_COUNT ; - dest.type =MLX5_FLOW_DESTINATION_TYPE_COUNTER ; - dest.counter_id =mlx5_fc_id (tx->fc->cnt); + dest.ft = tx->ft.status; + dest.type =MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ; rule =mlx5_add_flow_rules (tx->ft.sa, spec, &flow_act, &dest,1 );if (IS_ERR (rule)) { err =PTR_ERR (rule);
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +1 -1
@@ -137,7 +137,7 @@#define LAG_MIN_LEVEL (OFFLOADS_MIN_LEVEL + KERNEL_RX_MACSEC_MIN_LEVEL + 1)#define KERNEL_TX_IPSEC_NUM_PRIOS 1 -#define KERNEL_TX_IPSEC_NUM_LEVELS 2 +#define KERNEL_TX_IPSEC_NUM_LEVELS 3#define KERNEL_TX_IPSEC_MIN_LEVEL (KERNEL_TX_IPSEC_NUM_LEVELS)#define KERNEL_TX_MACSEC_NUM_PRIOS 1
Signature · 1 line
2.39.2
PATCH 9/9 net/mlx5e: Update IPsec per SA packets/bytes count
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Providing per SA packets/bytes statistics mandates creating unique counter per SA flow for Rx/Tx, whenever offloaded SA statistics is desired query the specific SA counter to provide the stack with the needed data.
--- .../mellanox/mlx5/core/en_accel/ipsec.c | 20 +++------ .../mellanox/mlx5/core/en_accel/ipsec.h | 4 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 44 ++++++++++++++----- .../mlx5/core/en_accel/ipsec_offload.c | 15 ------- 4 files changed, 42 insertions(+), 41 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +7 -13
@@ -495,24 +495,18 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)static void mlx5e_xfrm_update_curlft (struct xfrm_state *x) {struct mlx5e_ipsec_sa_entry *sa_entry =to_ipsec_sa_entry (x); -int err; +struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule; +u64 packets, bytes, lastuse; -lockdep_assert_held (&x->lock); +lockdep_assert (lockdep_is_held (&x->lock) || +lockdep_is_held (&dev_net (x->xso.real_dev)->xfrm.xfrm_cfg_mutex));if (x->xso.flags &XFRM_DEV_OFFLOAD_FLAG_ACQ )return ; -if (sa_entry->attrs.soft_packet_limit ==XFRM_INF ) -/* Limits are not configured, as soft limit -* must be lowever than hard limit. -*/ -return ; - - err =mlx5e_ipsec_aso_query (sa_entry,NULL ); -if (err) -return ; - -mlx5e_ipsec_aso_update_curlft (sa_entry, &x->curlft.packets); +mlx5_fc_query_cached (ipsec_rule->fc, &bytes, &packets, &lastuse); + x->curlft.packets += packets; + x->curlft.bytes += bytes; } static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +1 -3
@@ -162,6 +162,7 @@ struct mlx5e_ipsec_rule {struct mlx5_flow_handle *rule;struct mlx5_modify_hdr *modify_hdr;struct mlx5_pkt_reformat *pkt_reformat; +struct mlx5_fc *fc; };struct mlx5e_ipsec_modify_state_work {
@@ -235,9 +236,6 @@ void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec);int mlx5e_ipsec_aso_query (struct mlx5e_ipsec_sa_entry *sa_entry,struct mlx5_wqe_aso_ctrl_seg *data); -void mlx5e_ipsec_aso_update_curlft (struct mlx5e_ipsec_sa_entry *sa_entry, -u64 *packets); -void mlx5e_accel_ipsec_fs_read_stats (struct mlx5e_priv *priv,void *ipsec_stats);
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +34 -10
112 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +0 -15
@@ -489,18 +489,3 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,spin_unlock_bh (&aso->lock);return ret; } - -void mlx5e_ipsec_aso_update_curlft (struct mlx5e_ipsec_sa_entry *sa_entry, -u64 *packets) -{ -struct mlx5e_ipsec *ipsec = sa_entry->ipsec; -struct mlx5e_ipsec_aso *aso = ipsec->aso; -u64 hard_cnt; - - hard_cnt =MLX5_GET (ipsec_aso, aso->ctx, remove_flow_pkt_cnt); -/* HW decresases the limit till it reaches zero to fire an avent. -* We need to fix the calculations, so the returned count is a total -* number of passed packets and not how much left. -*/ - *packets = sa_entry->attrs.hard_packet_limit - hard_cnt; -}
Signature · 1 line
2.39.2
Leon Romanovsky
maintainerQuoted 3 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Hi Steffen,
<...>
Quoted 2 lines
So how do you want me to route the patches, as they have a dependency between them? xfrm-next/net-next/mlx5-next?
Can you please share your opinion and/or ack/nack xfrm patches, so we will be able to progress?
Thanks
Quoted 36 lines
Thanks
[1] https://github.com/libreswan/libreswan/pull/986q
[2] https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/log/?h=xfrm-nextPaul Blakey (3):
net/mlx5:fs_chains: Refactor to detach chains from tc usage net/mlx5:fs_core: Allowignore_flow_levelon TX dest net/mlx5e: Use chains for IPsec policy priority offloadRaed Salem (6):
xfrm: add new device offload acquire flag
xfrm:copy_to_user_statefetch offloaded SA packets/bytes statistics net/mlx5e: Allow policies with reqid 0, to support IKE policy holes net/mlx5e: Support IPsec acquire default SA
net/mlx5e: Use one rule to count all IPsec Tx offloaded traffic net/mlx5e: Update IPsec per SA packets/bytes count.../mellanox/mlx5/core/en_accel/ipsec.c | 71 ++- .../mellanox/mlx5/core/en_accel/ipsec.h | 13 +- .../mellanox/mlx5/core/en_accel/ipsec_fs.c | 528 ++++++++++++++---- .../mlx5/core/en_accel/ipsec_offload.c | 32 +- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 20 +- .../mellanox/mlx5/core/eswitch_offloads.c | 6 +- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 5 +- .../mellanox/mlx5/core/lib/fs_chains.c | 89 ++- .../mellanox/mlx5/core/lib/fs_chains.h | 9 +- include/net/xfrm.h | 5 + net/xfrm/xfrm_state.c | 1 + net/xfrm/xfrm_user.c | 2 + 12 files changed, 553 insertions(+), 228 deletions(-)Signature · 1 line
2.39.2
Steffen Klassert
maintainerQuoted 13 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Hi Steffen,
The following patches are an outcome of Raed's work to add packet offload support to libreswan [1].
The series includes:
* Priority support to IPsec policies
* Statistics per-SA (visible through "ip -s xfrm state ..." command)
* Support to IKE policy holes
* Fine tuning to acquire logic.
Quoted 8 lines
--------------------------
Future submission roadmap, which can be seen here [2]:
* Support packet offload in IPsec tunnel mode
* Rework lifetime counters support to avoid HW bugs/limitations
* Some general cleanup.So how do you want me to route the patches, as they have a dependency between them? xfrm-next/net-next/mlx5-next?
As the changes to the xfrm core are just minor compared to the rest of the patchset, I'd not absolutely require to route it through ipsec-next. Do it as you prefer, but let me know how you plan to do it.
Quoted 20 lines · Steffen Klassert
Quoted 19 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Hi Steffen,
The following patches are an outcome of Raed's work to add packet offload support to libreswan [1].
The series includes:
* Priority support to IPsec policies
* Statistics per-SA (visible through "ip -s xfrm state ..." command)
* Support to IKE policy holes
* Fine tuning to acquire logic.--------------------------
Future submission roadmap, which can be seen here [2]:
* Support packet offload in IPsec tunnel mode
* Rework lifetime counters support to avoid HW bugs/limitations
* Some general cleanup.
Quoted 7 lines
Quoted 2 lines
So how do you want me to route the patches, as they have a dependency between them? xfrm-next/net-next/mlx5-next?
As the changes to the xfrm core are just minor compared to the rest of the patchset, I'd not absolutely require to route it through ipsec-next. Do it as you prefer, but let me know how you plan to do it.
I prefer to prepare and send PR directly to netdev, but I need your Acked-by on xfrm patches first, before doing it.
Thanks