Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65802f48 authored by Aviad Yehezkel's avatar Aviad Yehezkel Committed by Saeed Mahameed
Browse files

net/mlx5: IPSec, Add command V2 support



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: default avatarYossef Efraim <yossefe@mellanox.com>
Signed-off-by: default avatarAviad Yehezkel <aviadye@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 788a8210
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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)
+17 −4
Original line number Diff line number Diff line
@@ -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)
@@ -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,
};

@@ -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];
@@ -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;

/**
+28 −32
Original line number Diff line number Diff line
@@ -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);
	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->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));
	}
		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->cmd = htonl(op);
	hw_sa->flags |= MLX5_IPSEC_SADB_SA_VALID | MLX5_IPSEC_SADB_SPI_EN;
	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;
	}
	hw_sa->spi = x->id.spi;
	hw_sa->sw_sa_handle = htonl(sa_entry->handle);
		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->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)
+7 −4
Original line number Diff line number Diff line
@@ -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)
@@ -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;
	}
@@ -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;
}

+3 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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);
}
Loading