Skip to content

Commit

Permalink
net/mlx5e: Skip IPsec encryption for TX path without matching policy
Browse files Browse the repository at this point in the history
Software implementation of IPsec skips encryption of packets in TX
path if no matching policy is found. So align HW implementation to
this behavior, by requiring matching reqid for offloaded policy and
SA.

Reviewed-by: Raed Salem <raeds@nvidia.com>
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
Leon Romanovsky authored and Steffen Klassert committed Dec 8, 2022
1 parent 81f8fba commit 6721239
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
7 changes: 7 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
memcpy(&attrs->daddr, x->id.daddr.a6, sizeof(attrs->daddr));
attrs->family = x->props.family;
attrs->type = x->xso.type;
attrs->reqid = x->props.reqid;
}

static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
Expand Down Expand Up @@ -267,6 +268,11 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
x->replay_esn->replay_window);
return -EINVAL;
}

if (!x->props.reqid) {
netdev_info(netdev, "Cannot offload without reqid\n");
return -EINVAL;
}
}
return 0;
}
Expand Down Expand Up @@ -503,6 +509,7 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
attrs->dir = x->xdo.dir;
attrs->action = x->action;
attrs->type = XFRM_DEV_OFFLOAD_PACKET;
attrs->reqid = x->xfrm_vec[0].reqid;
}

static int mlx5e_xfrm_add_policy(struct xfrm_policy *x)
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct mlx5_accel_esp_xfrm_attrs {
u8 family;
u32 replay_window;
u32 authsize;
u32 reqid;
};

enum mlx5_ipsec_cap {
Expand Down Expand Up @@ -178,12 +179,13 @@ struct mlx5_accel_pol_xfrm_attrs {
u8 action;
u8 type : 2;
u8 dir : 2;
u32 reqid;
};

struct mlx5e_ipsec_pol_entry {
struct xfrm_policy *x;
struct mlx5e_ipsec *ipsec;
struct mlx5_flow_handle *rule;
struct mlx5e_ipsec_rule ipsec_rule;
struct mlx5_accel_pol_xfrm_attrs attrs;
};

Expand Down
39 changes: 33 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,17 @@ static void setup_fte_reg_a(struct mlx5_flow_spec *spec)
misc_parameters_2.metadata_reg_a, MLX5_ETH_WQE_FT_META_IPSEC);
}

static void setup_fte_reg_c0(struct mlx5_flow_spec *spec, u32 reqid)
{
/* Pass policy check before choosing this SA */
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;

MLX5_SET(fte_match_param, spec->match_criteria,
misc_parameters_2.metadata_reg_c_0, reqid);
MLX5_SET(fte_match_param, spec->match_value,
misc_parameters_2.metadata_reg_c_0, reqid);
}

static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
struct mlx5_flow_act *flow_act)
{
Expand All @@ -470,6 +481,11 @@ static int setup_modify_header(struct mlx5_core_dev *mdev, u32 val, u8 dir,
MLX5_ACTION_IN_FIELD_METADATA_REG_B);
ns_type = MLX5_FLOW_NAMESPACE_KERNEL;
break;
case XFRM_DEV_OFFLOAD_OUT:
MLX5_SET(set_action_in, action, field,
MLX5_ACTION_IN_FIELD_METADATA_REG_C_0);
ns_type = MLX5_FLOW_NAMESPACE_EGRESS;
break;
default:
return -EINVAL;
}
Expand Down Expand Up @@ -646,6 +662,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
setup_fte_reg_a(spec);
break;
case XFRM_DEV_OFFLOAD_PACKET:
setup_fte_reg_c0(spec, attrs->reqid);
err = setup_pkt_reformat(mdev, attrs, &flow_act);
if (err)
goto err_pkt_reformat;
Expand Down Expand Up @@ -712,6 +729,11 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)

setup_fte_no_frags(spec);

err = setup_modify_header(mdev, attrs->reqid, XFRM_DEV_OFFLOAD_OUT,
&flow_act);
if (err)
goto err_mod_header;

switch (attrs->action) {
case XFRM_POLICY_ALLOW:
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
Expand Down Expand Up @@ -741,10 +763,13 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
}

kvfree(spec);
pol_entry->rule = rule;
pol_entry->ipsec_rule.rule = rule;
pol_entry->ipsec_rule.modify_hdr = flow_act.modify_hdr;
return 0;

err_action:
mlx5_modify_header_dealloc(mdev, flow_act.modify_hdr);
err_mod_header:
kvfree(spec);
err_alloc:
tx_ft_put(pol_entry->ipsec);
Expand Down Expand Up @@ -807,7 +832,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
}

kvfree(spec);
pol_entry->rule = rule;
pol_entry->ipsec_rule.rule = rule;
return 0;

err_action:
Expand Down Expand Up @@ -964,16 +989,18 @@ int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)

void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
{
struct mlx5e_ipsec_rule *ipsec_rule = &pol_entry->ipsec_rule;
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);

mlx5_del_flow_rules(pol_entry->rule);
mlx5_del_flow_rules(ipsec_rule->rule);

if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT) {
tx_ft_put(pol_entry->ipsec);
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
rx_ft_put(mdev, pol_entry->ipsec, pol_entry->attrs.family);
return;
}

rx_ft_put(mdev, pol_entry->ipsec, pol_entry->attrs.family);
mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
tx_ft_put(pol_entry->ipsec);
}

void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
Expand Down

0 comments on commit 6721239

Please sign in to comment.