From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2DBFA059F; Sat, 11 Apr 2020 16:19:10 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2D2B11C1ED; Sat, 11 Apr 2020 16:16:07 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id DDE631C1ED for ; Sat, 11 Apr 2020 16:16:05 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03BEFbmC021902; Sat, 11 Apr 2020 07:16:03 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0818; bh=cgfmw5/vOsklhjv6SumeEXTykLayOCubEw6saKtYRnM=; b=jvYWSgrCvmQsZmVrsB9X2KRuK16AXj8aBDGtrvVFkugXGehSMZIjbOk87TYF7xSlP/Ug aNnwuRRVk/1MK1VoMNo31ueSaB48pTTQOrS9Yp3SMyNl3+lTYw59zR6dCwv5gHg1cBT1 zWEhK5C5ad2pBNT4sMGsGZD25+piLlh6l0cw+iD9GpvvzokompRyoGcUvD4VzIcSMncV iK7ALbYVaXAfVosz2zH2qoeiRNT/iUGOqTjg55XB9QDw3uUagoUjKw1TVfyv3jzaEgS3 gb8DID2mqklP3ZBW1SQMPLqGVKYRfliMtCq/sGUBvBHrE9yYTndChMdmlNPfCP7gww3o vA== Received: from sc-exch03.marvell.com ([199.233.58.183]) by mx0a-0016f401.pphosted.com with ESMTP id 30bb8q8n7s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sat, 11 Apr 2020 07:16:03 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 11 Apr 2020 07:16:02 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 11 Apr 2020 07:16:02 -0700 Received: from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14]) by maili.marvell.com (Postfix) with ESMTP id 7C0DF3F703F; Sat, 11 Apr 2020 07:15:59 -0700 (PDT) From: To: Nithin Dabilpuram , Pavan Nikhilesh CC: , , , , , , , Date: Sat, 11 Apr 2020 19:44:22 +0530 Message-ID: <20200411141428.1987768-24-jerinj@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200411141428.1987768-1-jerinj@marvell.com> References: <20200405085613.1336841-1-jerinj@marvell.com> <20200411141428.1987768-1-jerinj@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-11_04:2020-04-09, 2020-04-11 signatures=0 Subject: [dpdk-dev] [PATCH v5 23/29] node: add ipv4 rewrite and lookup ctrl API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Nithin Dabilpuram Add ip4_rewrite and ip4_lookup ctrl API. ip4_lookup ctrl API is used to add route entries for LPM lookup with result data containing next hop id and next proto. ip4_rewrite ctrl API is used to add rewrite data for every next hop. Signed-off-by: Nithin Dabilpuram Signed-off-by: Pavan Nikhilesh Signed-off-by: Kiran Kumar K --- lib/librte_node/ethdev_ctrl.c | 18 ++++++- lib/librte_node/ip4_lookup.c | 79 ++++++++++++++++++++++++++++ lib/librte_node/ip4_rewrite.c | 56 ++++++++++++++++++++ lib/librte_node/ip4_rewrite_priv.h | 22 ++++++++ lib/librte_node/rte_node_ip4_api.h | 38 +++++++++++++ lib/librte_node/rte_node_version.map | 2 + 6 files changed, 214 insertions(+), 1 deletion(-) diff --git a/lib/librte_node/ethdev_ctrl.c b/lib/librte_node/ethdev_ctrl.c index 599d20b0b..13b8b705f 100644 --- a/lib/librte_node/ethdev_ctrl.c +++ b/lib/librte_node/ethdev_ctrl.c @@ -11,6 +11,7 @@ #include "ethdev_rx_priv.h" #include "ethdev_tx_priv.h" +#include "ip4_rewrite_priv.h" #include "node_private.h" static struct ethdev_ctrl { @@ -21,14 +22,17 @@ int rte_node_eth_config(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs) { + struct rte_node_register *ip4_rewrite_node; struct ethdev_tx_node_main *tx_node_data; uint16_t tx_q_used, rx_q_used, port_id; struct rte_node_register *tx_node; char name[RTE_NODE_NAMESIZE]; + const char *next_nodes = name; struct rte_mempool *mp; + int i, j, rc; uint32_t id; - int i, j; + ip4_rewrite_node = ip4_rewrite_node_get(); tx_node_data = ethdev_tx_node_data_get(); tx_node = ethdev_tx_node_get(); for (i = 0; i < nb_confs; i++) { @@ -92,6 +96,18 @@ rte_node_eth_config(struct rte_node_ethdev_config *conf, uint16_t nb_confs, node_dbg("ethdev", "Tx node %s-%s: is at %u", tx_node->name, name, id); + + /* Prepare the actual name of the cloned node */ + snprintf(name, sizeof(name), "ethdev_tx-%u", port_id); + + /* Add this tx port node as next to ip4_rewrite_node */ + rte_node_edge_update(ip4_rewrite_node->id, RTE_EDGE_ID_INVALID, + &next_nodes, 1); + /* Assuming edge id is the last one alloc'ed */ + rc = ip4_rewrite_set_next( + port_id, rte_node_edge_count(ip4_rewrite_node->id) - 1); + if (rc < 0) + return rc; } ctrl.nb_graphs = nb_graphs; diff --git a/lib/librte_node/ip4_lookup.c b/lib/librte_node/ip4_lookup.c index 39c8d8db0..8e6379457 100644 --- a/lib/librte_node/ip4_lookup.c +++ b/lib/librte_node/ip4_lookup.c @@ -28,6 +28,8 @@ struct ip4_lookup_node_main { struct rte_lpm *lpm_tbl[RTE_MAX_NUMA_NODES]; }; +static struct ip4_lookup_node_main ip4_lookup_nm; + #if defined(RTE_MACHINE_CPUFLAG_NEON) #include "ip4_lookup_neon.h" #elif defined(RTE_ARCH_X86) @@ -109,12 +111,89 @@ ip4_lookup_node_process(struct rte_graph *graph, struct rte_node *node, #endif +int +rte_node_ip4_route_add(uint32_t ip, uint8_t depth, uint16_t next_hop, + enum rte_node_ip4_lookup_next next_node) +{ + char abuf[INET6_ADDRSTRLEN]; + struct in_addr in; + uint8_t socket; + uint32_t val; + int ret; + + in.s_addr = htonl(ip); + inet_ntop(AF_INET, &in, abuf, sizeof(abuf)); + /* Embedded next node id into 24 bit next hop */ + val = ((next_node << 16) | next_hop) & ((1ull << 24) - 1); + node_dbg("ip4_lookup", "LPM: Adding route %s / %d nh (0x%x)", abuf, + depth, val); + + for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) { + if (!ip4_lookup_nm.lpm_tbl[socket]) + continue; + + ret = rte_lpm_add(ip4_lookup_nm.lpm_tbl[socket], + ip, depth, val); + if (ret < 0) { + node_err("ip4_lookup", + "Unable to add entry %s / %d nh (%x) to LPM table on sock %d, rc=%d\n", + abuf, depth, val, socket, ret); + return ret; + } + } + + return 0; +} + +static int +setup_lpm(struct ip4_lookup_node_main *nm, int socket) +{ + struct rte_lpm_config config_ipv4; + char s[RTE_LPM_NAMESIZE]; + + /* One LPM table per socket */ + if (nm->lpm_tbl[socket]) + return 0; + + /* create the LPM table */ + config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES; + config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S; + config_ipv4.flags = 0; + snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socket); + nm->lpm_tbl[socket] = rte_lpm_create(s, socket, &config_ipv4); + if (nm->lpm_tbl[socket] == NULL) + return -rte_errno; + + return 0; +} + static int ip4_lookup_node_init(const struct rte_graph *graph, struct rte_node *node) { + struct rte_lpm **lpm_p = (struct rte_lpm **)&node->ctx; + uint16_t socket, lcore_id; + static uint8_t init_once; + int rc; + RTE_SET_USED(graph); RTE_SET_USED(node); + if (!init_once) { + /* Setup LPM tables for all sockets */ + RTE_LCORE_FOREACH(lcore_id) + { + socket = rte_lcore_to_socket_id(lcore_id); + rc = setup_lpm(&ip4_lookup_nm, socket); + if (rc) { + node_err("ip4_lookup", + "Failed to setup lpm tbl for sock %u, rc=%d", + socket, rc); + return rc; + } + } + init_once = 1; + } + *lpm_p = ip4_lookup_nm.lpm_tbl[graph->socket]; node_dbg("ip4_lookup", "Initialized ip4_lookup node"); return 0; diff --git a/lib/librte_node/ip4_rewrite.c b/lib/librte_node/ip4_rewrite.c index 333e34761..bb7f671b5 100644 --- a/lib/librte_node/ip4_rewrite.c +++ b/lib/librte_node/ip4_rewrite.c @@ -256,6 +256,56 @@ ip4_rewrite_node_init(const struct rte_graph *graph, struct rte_node *node) return 0; } +int +ip4_rewrite_set_next(uint16_t port_id, uint16_t next_index) +{ + if (ip4_rewrite_nm == NULL) { + ip4_rewrite_nm = rte_zmalloc( + "ip4_rewrite", sizeof(struct ip4_rewrite_node_main), + RTE_CACHE_LINE_SIZE); + if (ip4_rewrite_nm == NULL) + return -ENOMEM; + } + ip4_rewrite_nm->next_index[port_id] = next_index; + + return 0; +} + +int +rte_node_ip4_rewrite_add(uint16_t next_hop, uint8_t *rewrite_data, + uint8_t rewrite_len, uint16_t dst_port) +{ + struct ip4_rewrite_nh_header *nh; + + if (next_hop >= RTE_GRAPH_IP4_REWRITE_MAX_NH) + return -EINVAL; + + if (rewrite_len > RTE_GRAPH_IP4_REWRITE_MAX_LEN) + return -EINVAL; + + if (ip4_rewrite_nm == NULL) { + ip4_rewrite_nm = rte_zmalloc( + "ip4_rewrite", sizeof(struct ip4_rewrite_node_main), + RTE_CACHE_LINE_SIZE); + if (ip4_rewrite_nm == NULL) + return -ENOMEM; + } + + /* Check if dst port doesn't exist as edge */ + if (!ip4_rewrite_nm->next_index[dst_port]) + return -EINVAL; + + /* Update next hop */ + nh = &ip4_rewrite_nm->nh[next_hop]; + + memcpy(nh->rewrite_data, rewrite_data, rewrite_len); + nh->tx_node = ip4_rewrite_nm->next_index[dst_port]; + nh->rewrite_len = rewrite_len; + nh->enabled = true; + + return 0; +} + static struct rte_node_register ip4_rewrite_node = { .process = ip4_rewrite_node_process, .name = "ip4_rewrite", @@ -267,4 +317,10 @@ static struct rte_node_register ip4_rewrite_node = { .init = ip4_rewrite_node_init, }; +struct rte_node_register * +ip4_rewrite_node_get(void) +{ + return &ip4_rewrite_node; +} + RTE_NODE_REGISTER(ip4_rewrite_node); diff --git a/lib/librte_node/ip4_rewrite_priv.h b/lib/librte_node/ip4_rewrite_priv.h index 420996a03..80f0abdc9 100644 --- a/lib/librte_node/ip4_rewrite_priv.h +++ b/lib/librte_node/ip4_rewrite_priv.h @@ -48,6 +48,28 @@ struct ip4_rewrite_node_main { /**< Next index of each configured port. */ }; +/** + * @internal + * + * Get the ipv4 rewrite node. + * + * @retrun + * Pointer to the ipv4 rewrite node. + */ +struct rte_node_register *ip4_rewrite_node_get(void); + +/** + * @internal + * + * Set the Edge index of a given port_id. + * + * @param port_id + * Ethernet port identifier. + * @param next_index + * Edge index of the Given Tx node. + */ +int ip4_rewrite_set_next(uint16_t port_id, uint16_t next_index); + #ifdef __cplusplus } #endif diff --git a/lib/librte_node/rte_node_ip4_api.h b/lib/librte_node/rte_node_ip4_api.h index 0b9ba48a2..31a752b00 100644 --- a/lib/librte_node/rte_node_ip4_api.h +++ b/lib/librte_node/rte_node_ip4_api.h @@ -33,6 +33,44 @@ enum rte_node_ip4_lookup_next { /**< Number of next nodes of lookup node. */ }; +/** + * Add ipv4 route to lookup table. + * + * @param ip + * IP address of route to be added. + * @param depth + * Depth of the rule to be added. + * @param next_hop + * Next hop id of the rule result to be added. + * @param next_node + * Next node to redirect traffic to. + * + * @return + * 0 on success, negative otherwise. + */ +__rte_experimental +int rte_node_ip4_route_add(uint32_t ip, uint8_t depth, uint16_t next_hop, + enum rte_node_ip4_lookup_next next_node); + +/** + * Add a next hop's rewrite data. + * + * @param next_hop + * Next hop id to add rewrite data to. + * @param rewrite_data + * Rewrite data. + * @param rewrite_len + * Length of rewrite data. + * @param dst_port + * Destination port to redirect traffic to. + * + * @return + * 0 on success, negative otherwise. + */ +__rte_experimental +int rte_node_ip4_rewrite_add(uint16_t next_hop, uint8_t *rewrite_data, + uint8_t rewrite_len, uint16_t dst_port); + #ifdef __cplusplus } #endif diff --git a/lib/librte_node/rte_node_version.map b/lib/librte_node/rte_node_version.map index c6c71bd02..a799b0d38 100644 --- a/lib/librte_node/rte_node_version.map +++ b/lib/librte_node/rte_node_version.map @@ -2,6 +2,8 @@ EXPERIMENTAL { global: rte_node_eth_config; + rte_node_ip4_route_add; + rte_node_ip4_rewrite_add; rte_node_logtype; local: *; }; -- 2.25.1