From patchwork Wed Jun 7 13:02:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 128300 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C9F3942C4D; Wed, 7 Jun 2023 15:04:31 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A826C42D6C; Wed, 7 Jun 2023 15:03:00 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 3466E42D39 for ; Wed, 7 Jun 2023 15:02:53 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.69.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id A044BE12CA; Wed, 7 Jun 2023 17:02:52 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Denis Pryazhennikov , Andy Moreton Subject: [PATCH v4 11/34] net/sfc: add API to manage HW Conntrack table Date: Wed, 7 Jun 2023 17:02:22 +0400 Message-Id: <20230607130245.8048-12-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230607130245.8048-1-ivan.malov@arknetworks.am> References: <20230601195538.8265-1-ivan.malov@arknetworks.am> <20230607130245.8048-1-ivan.malov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Denis Pryazhennikov The new API allows to manipulate entries in the HW Conntrack table. It uses a new Table Access API as a backend. Signed-off-by: Denis Pryazhennikov Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton --- drivers/net/sfc/meson.build | 1 + drivers/net/sfc/sfc_mae_ct.c | 201 +++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_mae_ct.h | 68 ++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 drivers/net/sfc/sfc_mae_ct.c create mode 100644 drivers/net/sfc/sfc_mae_ct.h diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build index c9d4264674..5adde68517 100644 --- a/drivers/net/sfc/meson.build +++ b/drivers/net/sfc/meson.build @@ -92,6 +92,7 @@ sources = files( 'sfc_tbl_meta_cache.c', 'sfc_mae.c', 'sfc_mae_counter.c', + 'sfc_mae_ct.c', 'sfc_flow.c', 'sfc_flow_rss.c', 'sfc_flow_tunnel.c', diff --git a/drivers/net/sfc/sfc_mae_ct.c b/drivers/net/sfc/sfc_mae_ct.c new file mode 100644 index 0000000000..fd6819c8a5 --- /dev/null +++ b/drivers/net/sfc/sfc_mae_ct.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + */ + +#include "sfc.h" +#include "sfc_mae_ct.h" + +/* SF-123102-TC-1A § 10.6.3: Conntrack_Table key */ +static void +sfc_mae_ct_key_to_mcdi_key(const sfc_mae_conntrack_key_t *key, + const efx_table_field_descriptor_t *fields, + unsigned int n_fields, uint32_t *mcdi_key, + unsigned int key_size) +{ + unsigned int i; + + for (i = 0; i < n_fields; i++) { + const efx_table_field_descriptor_t *desc = &fields[i]; + + if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER) + continue; + + switch (desc->field_id) { + case EFX_TABLE_FIELD_ID_IP_PROTO: + sfc_tbls_field_set_u8(mcdi_key, key_size, desc->lbn, + desc->width, key->ip_proto); + break; + case EFX_TABLE_FIELD_ID_ETHER_TYPE: + sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn, + desc->width, key->ether_type_le); + break; + case EFX_TABLE_FIELD_ID_SRC_PORT: + sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn, + desc->width, key->src_port_le); + break; + case EFX_TABLE_FIELD_ID_DST_PORT: + sfc_tbls_field_set_u16(mcdi_key, key_size, desc->lbn, + desc->width, key->dst_port_le); + break; + case EFX_TABLE_FIELD_ID_SRC_IP: + sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn, + desc->width, + (const uint32_t *)key->src_addr_le); + break; + case EFX_TABLE_FIELD_ID_DST_IP: + sfc_tbls_field_set_ip(mcdi_key, key_size, desc->lbn, + desc->width, + (const uint32_t *)key->dst_addr_le); + break; + + default: + break; + } + } +} + +/* SF-123102-TC-1A § 10.6.4: Conntrack_Table response */ +static void +sfc_mae_ct_response_to_mcdi_response(const sfc_mae_conntrack_response_t *response, + const efx_table_field_descriptor_t *fields, + unsigned int n_fields, uint32_t *mcdi_resp, + unsigned int resp_size) +{ + unsigned int i; + + for (i = 0; i < n_fields; i++) { + const efx_table_field_descriptor_t *desc = &fields[i]; + + if (desc->mask_type == EFX_TABLE_FIELD_MASK_NEVER) + continue; + + /* Fields of responses are always reported with the EXACT type. */ + SFC_ASSERT(desc->mask_type == EFX_TABLE_FIELD_MASK_EXACT); + + switch (desc->field_id) { + case EFX_TABLE_FIELD_ID_CT_MARK: + sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn, + desc->width, response->ct_mark); + break; + case EFX_TABLE_FIELD_ID_COUNTER_ID: + sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn, + desc->width, response->counter_id); + break; + case EFX_TABLE_FIELD_ID_NAT_DIR: + sfc_tbls_field_set_u8(mcdi_resp, resp_size, desc->lbn, + desc->width, response->nat.dir_is_dst); + break; + case EFX_TABLE_FIELD_ID_NAT_IP: + sfc_tbls_field_set_u32(mcdi_resp, resp_size, desc->lbn, + desc->width, response->nat.ip_le); + break; + case EFX_TABLE_FIELD_ID_NAT_PORT: + sfc_tbls_field_set_u16(mcdi_resp, resp_size, desc->lbn, + desc->width, response->nat.port_le); + break; + + default: + break; + } + } +} + +int +sfc_mae_conntrack_insert(struct sfc_adapter *sa, + const sfc_mae_conntrack_key_t *key, + const sfc_mae_conntrack_response_t *response) +{ + const struct sfc_tbls *tables = &sa->hw_tables; + uint8_t data[EFX_TABLE_ENTRY_LENGTH_MAX] = {0}; + const struct sfc_tbl_meta *meta = NULL; + unsigned int response_size; + uint32_t *response_data; + unsigned int data_size; + unsigned int key_size; + uint32_t *start_data; + uint16_t resp_width; + uint16_t key_width; + uint32_t *key_data; + uint32_t *end_data; + int rc = 0; + + if (tables->status != SFC_TBLS_STATUS_SUPPORTED) + return -ENOTSUP; + + if (!sfc_mae_conntrack_is_supported(sa)) + return -ENOTSUP; + + meta = sfc_mae_conntrack_meta_lookup(sa); + if (meta == NULL) + return -ENOENT; + + key_width = meta->descriptor.key_width; + resp_width = meta->descriptor.resp_width; + + start_data = (uint32_t *)data; + key_data = start_data; + response_data = sfc_tbls_next_req_fields(key_data, key_width); + end_data = sfc_tbls_next_req_fields(response_data, resp_width); + + key_size = RTE_PTR_DIFF(response_data, key_data); + response_size = RTE_PTR_DIFF(end_data, response_data); + data_size = RTE_PTR_DIFF(end_data, start_data); + SFC_ASSERT(data_size <= sizeof(data)); + + sfc_mae_ct_key_to_mcdi_key(key, meta->keys, + meta->descriptor.n_key_fields, key_data, + key_size); + sfc_mae_ct_response_to_mcdi_response(response, meta->responses, + meta->descriptor.n_resp_fields, + response_data, response_size); + + rc = sfc_tbls_bcam_entry_insert(sa->nic, EFX_TABLE_ID_CONNTRACK, + key_width, resp_width, data, + data_size); + + return rc; +} + +int +sfc_mae_conntrack_delete(struct sfc_adapter *sa, + const sfc_mae_conntrack_key_t *key) +{ + const struct sfc_tbls *tables = &sa->hw_tables; + uint8_t data[EFX_TABLE_ENTRY_LENGTH_MAX] = {0}; + const struct sfc_tbl_meta *meta = NULL; + unsigned int data_size; + uint32_t *start_data; + uint16_t key_width; + uint32_t *key_data; + uint32_t *end_data; + int rc = 0; + + if (tables->status != SFC_TBLS_STATUS_SUPPORTED) + return -ENOTSUP; + + if (!sfc_mae_conntrack_is_supported(sa)) + return -ENOTSUP; + + meta = sfc_mae_conntrack_meta_lookup(sa); + if (meta == NULL) + return -ENOENT; + + key_width = meta->descriptor.key_width; + + start_data = (uint32_t *)data; + key_data = start_data; + end_data = sfc_tbls_next_req_fields(key_data, key_width); + + data_size = RTE_PTR_DIFF(end_data, start_data); + SFC_ASSERT(data_size <= sizeof(data)); + + sfc_mae_ct_key_to_mcdi_key(key, meta->keys, + meta->descriptor.n_key_fields, + key_data, data_size); + + rc = sfc_tbls_bcam_entry_delete(sa->nic, EFX_TABLE_ID_CONNTRACK, + key_width, data, data_size); + + return rc; +} diff --git a/drivers/net/sfc/sfc_mae_ct.h b/drivers/net/sfc/sfc_mae_ct.h new file mode 100644 index 0000000000..b5a3181cd3 --- /dev/null +++ b/drivers/net/sfc/sfc_mae_ct.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2023 Advanced Micro Devices, Inc. + */ + +#ifndef _SFC_MAE_CONNTRACK_H +#define _SFC_MAE_CONNTRACK_H + +#include + +#include + +#include "efx.h" + +#include "sfc_tbls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sfc_mae_conntrack_key_s { + uint8_t ip_proto; + uint16_t ether_type_le; + + uint16_t src_port_le; + uint16_t dst_port_le; + + uint8_t src_addr_le[RTE_SIZEOF_FIELD(struct rte_ipv6_hdr, src_addr)]; + uint8_t dst_addr_le[RTE_SIZEOF_FIELD(struct rte_ipv6_hdr, dst_addr)]; +} sfc_mae_conntrack_key_t; + +typedef struct sfc_mae_conntrack_nat_s { + uint32_t ip_le; + uint16_t port_le; + bool dir_is_dst; +} sfc_mae_conntrack_nat_t; + +typedef struct sfc_mae_conntrack_response_s { + uint32_t ct_mark; + sfc_mae_conntrack_nat_t nat; + uint32_t counter_id; +} sfc_mae_conntrack_response_t; + +struct sfc_adapter; + +static inline bool +sfc_mae_conntrack_is_supported(struct sfc_adapter *sa) +{ + return sfc_tbls_id_is_supported(sa, EFX_TABLE_ID_CONNTRACK); +} + +static inline const struct sfc_tbl_meta * +sfc_mae_conntrack_meta_lookup(struct sfc_adapter *sa) +{ + return sfc_tbl_meta_lookup(sa, EFX_TABLE_ID_CONNTRACK); +} + +int sfc_mae_conntrack_insert(struct sfc_adapter *sa, + const sfc_mae_conntrack_key_t *key, + const sfc_mae_conntrack_response_t *response); + +int sfc_mae_conntrack_delete(struct sfc_adapter *sa, + const sfc_mae_conntrack_key_t *key); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_MAE_CONNTRACK_H */