diff options
author | Leon Romanovsky <leonro@nvidia.com> | 2023-04-13 15:29:24 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-04-17 18:55:25 -0700 |
commit | efbd31c4d844e55526587cc3820ca8a11d7db733 (patch) | |
tree | c27e434508d7c021c4924bb1a5c235b860b6da1e /drivers | |
parent | 37a417ca911a52828aa84340484e4ccd33b7baae (diff) | |
download | linux-stable-efbd31c4d844e55526587cc3820ca8a11d7db733.tar.gz linux-stable-efbd31c4d844e55526587cc3820ca8a11d7db733.tar.bz2 linux-stable-efbd31c4d844e55526587cc3820ca8a11d7db733.zip |
net/mlx5e: Support IPsec TX packet offload in tunnel mode
Extend mlx5 driver with logic to support IPsec TX packet offload
in tunnel mode.
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c | 52 |
2 files changed, 64 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 7c55b37c1c01..36f3ffd54355 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -271,6 +271,18 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, neigh_ha_snapshot(addr, n, netdev); ether_addr_copy(attrs->smac, addr); break; + case XFRM_DEV_OFFLOAD_OUT: + ether_addr_copy(attrs->smac, addr); + n = neigh_lookup(&arp_tbl, &attrs->daddr.a4, netdev); + if (!n) { + n = neigh_create(&arp_tbl, &attrs->daddr.a4, netdev); + if (IS_ERR(n)) + return; + neigh_event_send(n, NULL); + } + neigh_ha_snapshot(addr, n, netdev); + ether_addr_copy(attrs->dmac, addr); + break; default: return; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c index 001d7c3add6a..4c800b54d8b6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c @@ -11,6 +11,7 @@ #define NUM_IPSEC_FTE BIT(15) #define MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE 16 +#define IPSEC_TUNNEL_DEFAULT_TTL 0x40 struct mlx5e_ipsec_fc { struct mlx5_fc *cnt; @@ -842,12 +843,31 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev, struct mlx5_accel_esp_xfrm_attrs *attrs, struct mlx5_pkt_reformat_params *reformat_params) { + struct ip_esp_hdr *esp_hdr; + struct ipv6hdr *ipv6hdr; struct ethhdr *eth_hdr; + struct iphdr *iphdr; char *reformatbf; size_t bfflen; + void *hdr; bfflen = sizeof(*eth_hdr); + if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) { + bfflen += sizeof(*esp_hdr) + 8; + + switch (attrs->family) { + case AF_INET: + bfflen += sizeof(*iphdr); + break; + case AF_INET6: + bfflen += sizeof(*ipv6hdr); + break; + default: + return -EINVAL; + } + } + reformatbf = kzalloc(bfflen, GFP_KERNEL); if (!reformatbf) return -ENOMEM; @@ -871,6 +891,38 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev, case XFRM_DEV_OFFLOAD_IN: reformat_params->type = MLX5_REFORMAT_TYPE_L3_ESP_TUNNEL_TO_L2; break; + case XFRM_DEV_OFFLOAD_OUT: + reformat_params->type = MLX5_REFORMAT_TYPE_L2_TO_L3_ESP_TUNNEL; + reformat_params->param_0 = attrs->authsize; + + hdr = reformatbf + sizeof(*eth_hdr); + switch (attrs->family) { + case AF_INET: + iphdr = (struct iphdr *)hdr; + memcpy(&iphdr->saddr, &attrs->saddr.a4, 4); + memcpy(&iphdr->daddr, &attrs->daddr.a4, 4); + iphdr->version = 4; + iphdr->ihl = 5; + iphdr->ttl = IPSEC_TUNNEL_DEFAULT_TTL; + iphdr->protocol = IPPROTO_ESP; + hdr += sizeof(*iphdr); + break; + case AF_INET6: + ipv6hdr = (struct ipv6hdr *)hdr; + memcpy(&ipv6hdr->saddr, &attrs->saddr.a6, 16); + memcpy(&ipv6hdr->daddr, &attrs->daddr.a6, 16); + ipv6hdr->nexthdr = IPPROTO_ESP; + ipv6hdr->version = 6; + ipv6hdr->hop_limit = IPSEC_TUNNEL_DEFAULT_TTL; + hdr += sizeof(*ipv6hdr); + break; + default: + goto free_reformatbf; + } + + esp_hdr = (struct ip_esp_hdr *)hdr; + esp_hdr->spi = htonl(attrs->spi); + break; default: goto free_reformatbf; } |