From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 368B4C43331 for ; Thu, 26 Mar 2020 17:01:22 +0000 (UTC) Received: from dpdk.org (dpdk.org [92.243.14.124]) by mail.kernel.org (Postfix) with ESMTP id C3C7620714 for ; Thu, 26 Mar 2020 17:01:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="CEKKHGmH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C3C7620714 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=marvell.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=dev-bounces@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 44B7D1C198; Thu, 26 Mar 2020 17:58:02 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id D973F1C0AF for ; Thu, 26 Mar 2020 17:58:00 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 02QGjC4C002902; Thu, 26 Mar 2020 09:57:59 -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=VnX3Uixv6eMvlLaWxSJEWA1356/8t3gOcfwSNdlaL4o=; b=CEKKHGmHLOZKUULyQf1KvdLGyA9TRaHg6tZJZEhlWmyCAFvW2lVXsQWy1jGZ9EuMAlZt UpYqGgG0gBzNaGM8+di3zvEbhvFqEWcQhIN4vcbwfQ49G6SnvnaubRjOqYORPG1KSGju PlisILyW3I/pacy5e8RhGUhbmvDaN6dF2MxvY/5YcWXjp8Vsx53kK/No29UxpanCf+r0 wNGmCUYih5Bl711h0bSAurjFzaum+RMkp1ZojvQCJ1k5FZQR6mXT4MYebIzJnN4Mz2F/ hTRkwURrZyiWx0wy92StgyDz8o+DlH3zuKulBDAH6nRa51v5+amICKlBRF1S00Rgk8sZ cw== Received: from sc-exch04.marvell.com ([199.233.58.184]) by mx0b-0016f401.pphosted.com with ESMTP id 300bpcvu80-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Thu, 26 Mar 2020 09:57:59 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by SC-EXCH04.marvell.com (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Mar 2020 09:57:56 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Mar 2020 09:57:56 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Mar 2020 09:57:55 -0700 Received: from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14]) by maili.marvell.com (Postfix) with ESMTP id DD72F3F7040; Thu, 26 Mar 2020 09:57:53 -0700 (PDT) From: To: Nithin Dabilpuram , Pavan Nikhilesh CC: , , , , , Date: Thu, 26 Mar 2020 22:26:38 +0530 Message-ID: <20200326165644.866053-23-jerinj@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200326165644.866053-1-jerinj@marvell.com> References: <20200318213551.3489504-1-jerinj@marvell.com> <20200326165644.866053-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.645 definitions=2020-03-26_08:2020-03-26, 2020-03-26 signatures=0 Subject: [dpdk-dev] [PATCH v2 22/28] 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 | 80 ++++++++++++++++++++++++++++ lib/librte_node/ip4_rewrite.c | 56 +++++++++++++++++++ lib/librte_node/ip4_rewrite_priv.h | 22 ++++++++ lib/librte_node/rte_node_ip4_api.h | 44 +++++++++++++++ lib/librte_node/rte_node_version.map | 2 + 6 files changed, 221 insertions(+), 1 deletion(-) diff --git a/lib/librte_node/ethdev_ctrl.c b/lib/librte_node/ethdev_ctrl.c index b2ac5e2c4..845d92987 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++) { @@ -93,6 +97,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 a9e204148..0665d1ea5 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) /* ARM64 NEON */ static uint16_t @@ -512,12 +514,90 @@ 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 in next hop */ + val = (next_node << 16) | next_hop; + 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 ef49ccea0..5663f1eb1 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 37c12bf82..394cac097 100644 --- a/lib/librte_node/rte_node_ip4_api.h +++ b/lib/librte_node/rte_node_ip4_api.h @@ -36,6 +36,50 @@ enum rte_node_ip4_lookup_next { /**< Number of next nodes of lookup node. */ }; +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * 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); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * 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