Skip to content

Commit

Permalink
net/mlx5: IPSec, Add command V2 support
Browse files Browse the repository at this point in the history
This patch adds V2 command support.
New fpga devices support extended features (udp encap, esn etc...), this
features require new hardware sadb format therefore we have a new version
of commands to manipulate it.

Signed-off-by: Yossef Efraim <yossefe@mellanox.com>
Signed-off-by: Aviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
  • Loading branch information
Aviad Yehezkel authored and Saeed Mahameed committed Mar 7, 2018
1 parent 788a821 commit 65802f4
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 44 deletions.
9 changes: 8 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,17 @@
void *mlx5_accel_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
struct mlx5_accel_ipsec_sa *cmd)
{
int cmd_size;

if (!MLX5_IPSEC_DEV(mdev))
return ERR_PTR(-EOPNOTSUPP);

return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd);
if (mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_V2_CMD)
cmd_size = sizeof(*cmd);
else
cmd_size = sizeof(cmd->ipsec_sa_v1);

return mlx5_fpga_ipsec_sa_cmd_exec(mdev, cmd, cmd_size);
}

int mlx5_accel_ipsec_sa_cmd_wait(void *ctx)
Expand Down
21 changes: 17 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/accel/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum {
MLX5_ACCEL_IPSEC_ESP = BIT(3),
MLX5_ACCEL_IPSEC_LSO = BIT(4),
MLX5_ACCEL_IPSEC_NO_TRAILER = BIT(5),
MLX5_ACCEL_IPSEC_V2_CMD = BIT(7),
};

#define MLX5_IPSEC_SADB_IP_AH BIT(7)
Expand All @@ -56,6 +57,9 @@ enum {
enum {
MLX5_IPSEC_CMD_ADD_SA = 0,
MLX5_IPSEC_CMD_DEL_SA = 1,
MLX5_IPSEC_CMD_ADD_SA_V2 = 2,
MLX5_IPSEC_CMD_DEL_SA_V2 = 3,
MLX5_IPSEC_CMD_MOD_SA_V2 = 4,
MLX5_IPSEC_CMD_SET_CAP = 5,
};

Expand All @@ -68,7 +72,7 @@ enum mlx5_accel_ipsec_enc_mode {
#define MLX5_IPSEC_DEV(mdev) (mlx5_accel_ipsec_device_caps(mdev) & \
MLX5_ACCEL_IPSEC_DEVICE)

struct mlx5_accel_ipsec_sa {
struct mlx5_accel_ipsec_sa_v1 {
__be32 cmd;
u8 key_enc[32];
u8 key_auth[32];
Expand All @@ -88,10 +92,19 @@ struct mlx5_accel_ipsec_sa {
__be32 sw_sa_handle;
__be16 tfclen;
u8 enc_mode;
u8 sip_masklen;
u8 dip_masklen;
u8 reserved1[2];
u8 flags;
u8 reserved[2];
u8 reserved2[2];
};

struct mlx5_accel_ipsec_sa {
struct mlx5_accel_ipsec_sa_v1 ipsec_sa_v1;
__be16 udp_sp;
__be16 udp_dp;
u8 reserved1[4];
__be32 esn;
__be16 vid; /* only 12 bits, rest is reserved */
__be16 reserved2;
} __packed;

/**
Expand Down
60 changes: 28 additions & 32 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,50 +133,46 @@ static void mlx5e_ipsec_build_hw_sa(u32 op, struct mlx5e_ipsec_sa_entry *sa_entr

memset(hw_sa, 0, sizeof(*hw_sa));

if (op == MLX5_IPSEC_CMD_ADD_SA) {
crypto_data_len = (x->aead->alg_key_len + 7) / 8;
key_len = crypto_data_len - 4; /* 4 bytes salt at end */
aead = x->data;
geniv_ctx = crypto_aead_ctx(aead);
ivsize = crypto_aead_ivsize(aead);

memcpy(&hw_sa->key_enc, x->aead->alg_key, key_len);
/* Duplicate 128 bit key twice according to HW layout */
if (key_len == 16)
memcpy(&hw_sa->key_enc[16], x->aead->alg_key, key_len);
memcpy(&hw_sa->gcm.salt_iv, geniv_ctx->salt, ivsize);
hw_sa->gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));
}

hw_sa->cmd = htonl(op);
hw_sa->flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
crypto_data_len = (x->aead->alg_key_len + 7) / 8;
key_len = crypto_data_len - 4; /* 4 bytes salt at end */
aead = x->data;
geniv_ctx = crypto_aead_ctx(aead);
ivsize = crypto_aead_ivsize(aead);

memcpy(&hw_sa->ipsec_sa_v1.key_enc, x->aead->alg_key, key_len);
/* Duplicate 128 bit key twice according to HW layout */
if (key_len == 16)
memcpy(&hw_sa->ipsec_sa_v1.key_enc[16], x->aead->alg_key, key_len);
memcpy(&hw_sa->ipsec_sa_v1.gcm.salt_iv, geniv_ctx->salt, ivsize);
hw_sa->ipsec_sa_v1.gcm.salt = *((__be32 *)(x->aead->alg_key + key_len));

hw_sa->ipsec_sa_v1.cmd = htonl(op);
hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
if (x->props.family == AF_INET) {
hw_sa->sip[3] = x->props.saddr.a4;
hw_sa->dip[3] = x->id.daddr.a4;
hw_sa->sip_masklen = 32;
hw_sa->dip_masklen = 32;
hw_sa->ipsec_sa_v1.sip[3] = x->props.saddr.a4;
hw_sa->ipsec_sa_v1.dip[3] = x->id.daddr.a4;
} else {
memcpy(hw_sa->sip, x->props.saddr.a6, sizeof(hw_sa->sip));
memcpy(hw_sa->dip, x->id.daddr.a6, sizeof(hw_sa->dip));
hw_sa->sip_masklen = 128;
hw_sa->dip_masklen = 128;
hw_sa->flags |= MLX5_IPSEC_SADB_IPV6;
memcpy(hw_sa->ipsec_sa_v1.sip, x->props.saddr.a6,
sizeof(hw_sa->ipsec_sa_v1.sip));
memcpy(hw_sa->ipsec_sa_v1.dip, x->id.daddr.a6,
sizeof(hw_sa->ipsec_sa_v1.dip));
hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IPV6;
}
hw_sa->spi = x->id.spi;
hw_sa->sw_sa_handle = htonl(sa_entry->handle);
hw_sa->ipsec_sa_v1.spi = x->id.spi;
hw_sa->ipsec_sa_v1.sw_sa_handle = htonl(sa_entry->handle);
switch (x->id.proto) {
case IPPROTO_ESP:
hw_sa->flags |= MLX5_IPSEC_SADB_IP_ESP;
hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_ESP;
break;
case IPPROTO_AH:
hw_sa->flags |= MLX5_IPSEC_SADB_IP_AH;
hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_IP_AH;
break;
default:
break;
}
hw_sa->enc_mode = mlx5e_ipsec_enc_mode(x);
hw_sa->ipsec_sa_v1.enc_mode = mlx5e_ipsec_enc_mode(x);
if (!(x->xso.flags & XFRM_OFFLOAD_INBOUND))
hw_sa->flags |= MLX5_IPSEC_SADB_DIR_SX;
hw_sa->ipsec_sa_v1.flags |= MLX5_IPSEC_SADB_DIR_SX;
}

static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
Expand Down
11 changes: 7 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ static int mlx5_fpga_ipsec_cmd_wait(void *ctx)
}

void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
struct mlx5_accel_ipsec_sa *cmd)
struct mlx5_accel_ipsec_sa *cmd, int cmd_size)
{
return mlx5_fpga_ipsec_cmd_exec(mdev, cmd, sizeof(*cmd));
return mlx5_fpga_ipsec_cmd_exec(mdev, cmd, cmd_size);
}

int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
Expand All @@ -239,9 +239,9 @@ int mlx5_fpga_ipsec_sa_cmd_wait(void *ctx)
goto out;

sa = (struct mlx5_accel_ipsec_sa *)&context->command;
if (sa->sw_sa_handle != context->resp.sw_sa_handle) {
if (sa->ipsec_sa_v1.sw_sa_handle != context->resp.sw_sa_handle) {
mlx5_fpga_err(context->dev, "mismatch SA handle. cmd 0x%08x vs resp 0x%08x\n",
ntohl(sa->sw_sa_handle),
ntohl(sa->ipsec_sa_v1.sw_sa_handle),
ntohl(context->resp.sw_sa_handle));
res = -EIO;
}
Expand Down Expand Up @@ -276,6 +276,9 @@ u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev)
if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, rx_no_trailer))
ret |= MLX5_ACCEL_IPSEC_NO_TRAILER;

if (MLX5_GET(ipsec_extended_cap, fdev->ipsec->caps, v2_command))
ret |= MLX5_ACCEL_IPSEC_V2_CMD;

return ret;
}

Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#ifdef CONFIG_MLX5_FPGA

void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
struct mlx5_accel_ipsec_sa *cmd);
struct mlx5_accel_ipsec_sa *cmd, int cmd_size);
int mlx5_fpga_ipsec_sa_cmd_wait(void *context);

u32 mlx5_fpga_ipsec_device_caps(struct mlx5_core_dev *mdev);
Expand All @@ -53,7 +53,8 @@ void mlx5_fpga_ipsec_cleanup(struct mlx5_core_dev *mdev);
#else

static inline void *mlx5_fpga_ipsec_sa_cmd_exec(struct mlx5_core_dev *mdev,
struct mlx5_accel_ipsec_sa *cmd)
struct mlx5_accel_ipsec_sa *cmd,
int cmd_size)
{
return ERR_PTR(-EOPNOTSUPP);
}
Expand Down
4 changes: 3 additions & 1 deletion include/linux/mlx5/mlx5_ifc_fpga.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,9 @@ struct mlx5_ifc_fpga_destroy_qp_out_bits {
struct mlx5_ifc_ipsec_extended_cap_bits {
u8 encapsulation[0x20];

u8 reserved_0[0x14];
u8 reserved_0[0x12];
u8 v2_command[0x1];
u8 udp_encap[0x1];
u8 rx_no_trailer[0x1];
u8 ipv4_fragment[0x1];
u8 ipv6[0x1];
Expand Down

0 comments on commit 65802f4

Please sign in to comment.