From patchwork Thu Feb 18 12:15:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 87975 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 EB63DA054D; Thu, 18 Feb 2021 13:16:27 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EC43716073F; Thu, 18 Feb 2021 13:16:21 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id B7CEF160720 for ; Thu, 18 Feb 2021 13:16:20 +0100 (CET) IronPort-SDR: LwphVUsEa+x7zNvrMyUsqISPgA8xgSBEvvdEXohkOn58ABdkZl2eq77zerLfmZgycNkhZS4TuG O5XZ7rFKPRWg== X-IronPort-AV: E=McAfee;i="6000,8403,9898"; a="244937269" X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="244937269" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2021 04:16:19 -0800 IronPort-SDR: Q8aXr8/ZlE8gVMYqIJNoBytqUMqjWm2HdJQkyfdOkhAgw+B9QVFkE42J6YPVTQkCsj3by8kIX0 hYVzqJXRFKaQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="385921507" Received: from silpixa00400466.ir.intel.com ([10.237.213.210]) by fmsmga008.fm.intel.com with ESMTP; 18 Feb 2021 04:16:17 -0800 From: Conor Walsh To: jerinj@marvell.com, stephen@networkplumber.org, bernard.iremonger@intel.com, konstantin.ananyev@intel.com, vladimir.medvedkin@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Thu, 18 Feb 2021 12:15:48 +0000 Message-Id: <20210218121552.1888092-2-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218121552.1888092-1-conor.walsh@intel.com> References: <20210218121552.1888092-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 1/5] examples/l3fwd: fix LPM IPv6 subnets 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 Sender: "dev" The IPv6 subnets used were not within the 2001:200::/48 subnet Changed to 2001:200:0:{0-7}::/64 where 0-7 is the port ID Fixes: 37afe381bde4 ("examples/l3fwd: use reserved IP addresses") Signed-off-by: Conor Walsh --- examples/l3fwd/l3fwd_lpm.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c index 3dcf1fef18..1cfaf36572 100644 --- a/examples/l3fwd/l3fwd_lpm.c +++ b/examples/l3fwd/l3fwd_lpm.c @@ -42,7 +42,10 @@ struct ipv6_l3fwd_lpm_route { uint8_t if_out; }; -/* 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). */ +/* + * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). + * 198.18.{0-7}.0/24 = Port {0-7} + */ static const struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { {RTE_IPV4(198, 18, 0, 0), 24, 0}, {RTE_IPV4(198, 18, 1, 0), 24, 1}, @@ -54,16 +57,19 @@ static const struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { {RTE_IPV4(198, 18, 7, 0), 24, 7}, }; -/* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180) */ +/* + * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180). + * 2001:200:0:{0-7}::/64 = Port {0-7} + */ static const struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = { - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 0}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 48, 1}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0}, 48, 2}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0}, 48, 3}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0}, 48, 4}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0}, 48, 5}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0}, 48, 6}, - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0}, 48, 7}, + {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 0}, + {{32, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 1}, + {{32, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, + {{32, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, + {{32, 1, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 4}, + {{32, 1, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 5}, + {{32, 1, 2, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 6}, + {{32, 1, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 7}, }; #define IPV4_L3FWD_LPM_MAX_RULES 1024 From patchwork Thu Feb 18 12:15:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 87976 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 89CFEA054D; Thu, 18 Feb 2021 13:16:35 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 27A11160748; Thu, 18 Feb 2021 13:16:24 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id E0A27160737 for ; Thu, 18 Feb 2021 13:16:21 +0100 (CET) IronPort-SDR: 0aOo7VgZ1fQUMv9gYLrDVhT3LBQvh9U1lJohGwV7VmD+Kf4zU4YQGrAVyYtP70oPRrY0ljpLMU hDReiKBFqZug== X-IronPort-AV: E=McAfee;i="6000,8403,9898"; a="244937278" X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="244937278" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2021 04:16:21 -0800 IronPort-SDR: cQQ2EoyUfC1ueD8madg8sWmbANtOIWgTs3MferuHsuamrNXesr49bWPI6hwFdZIySM3TpTVt3y fJxwDiTCkI+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="385921519" Received: from silpixa00400466.ir.intel.com ([10.237.213.210]) by fmsmga008.fm.intel.com with ESMTP; 18 Feb 2021 04:16:19 -0800 From: Conor Walsh To: jerinj@marvell.com, stephen@networkplumber.org, bernard.iremonger@intel.com, konstantin.ananyev@intel.com, vladimir.medvedkin@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Thu, 18 Feb 2021 12:15:49 +0000 Message-Id: <20210218121552.1888092-3-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218121552.1888092-1-conor.walsh@intel.com> References: <20210218121552.1888092-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 2/5] examples/l3fwd: move l3fwd routes to common header 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 Sender: "dev" To prevent code duplication from the addition of lookup methods the routes specified in lpm should be moved to a common header. Signed-off-by: Conor Walsh --- examples/l3fwd/l3fwd_common_route.h | 48 +++++++++++++++++++ examples/l3fwd/l3fwd_lpm.c | 74 +++++++---------------------- 2 files changed, 65 insertions(+), 57 deletions(-) create mode 100644 examples/l3fwd/l3fwd_common_route.h diff --git a/examples/l3fwd/l3fwd_common_route.h b/examples/l3fwd/l3fwd_common_route.h new file mode 100644 index 0000000000..7f0125a8a5 --- /dev/null +++ b/examples/l3fwd/l3fwd_common_route.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Intel Corporation + */ + +#include +#include + +struct ipv4_l3fwd_common_route { + uint32_t ip; + uint8_t depth; + uint8_t if_out; +}; + +struct ipv6_l3fwd_common_route { + uint8_t ip[16]; + uint8_t depth; + uint8_t if_out; +}; + +/* + * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). + * 198.18.{0-7}.0/24 = Port {0-7} + */ +static const struct ipv4_l3fwd_common_route ipv4_l3fwd_common_route_array[] = { + {RTE_IPV4(198, 18, 0, 0), 24, 0}, + {RTE_IPV4(198, 18, 1, 0), 24, 1}, + {RTE_IPV4(198, 18, 2, 0), 24, 2}, + {RTE_IPV4(198, 18, 3, 0), 24, 3}, + {RTE_IPV4(198, 18, 4, 0), 24, 4}, + {RTE_IPV4(198, 18, 5, 0), 24, 5}, + {RTE_IPV4(198, 18, 6, 0), 24, 6}, + {RTE_IPV4(198, 18, 7, 0), 24, 7}, +}; + +/* + * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180). + * 2001:200:0:{0-7}::/64 = Port {0-7} + */ +static const struct ipv6_l3fwd_common_route ipv6_l3fwd_common_route_array[] = { + {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 0}, + {{32, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 1}, + {{32, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, + {{32, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, + {{32, 1, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 4}, + {{32, 1, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 5}, + {{32, 1, 2, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 6}, + {{32, 1, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 7}, +}; diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c index 1cfaf36572..818cf717d1 100644 --- a/examples/l3fwd/l3fwd_lpm.c +++ b/examples/l3fwd/l3fwd_lpm.c @@ -30,47 +30,7 @@ #include "l3fwd.h" #include "l3fwd_event.h" -struct ipv4_l3fwd_lpm_route { - uint32_t ip; - uint8_t depth; - uint8_t if_out; -}; - -struct ipv6_l3fwd_lpm_route { - uint8_t ip[16]; - uint8_t depth; - uint8_t if_out; -}; - -/* - * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). - * 198.18.{0-7}.0/24 = Port {0-7} - */ -static const struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = { - {RTE_IPV4(198, 18, 0, 0), 24, 0}, - {RTE_IPV4(198, 18, 1, 0), 24, 1}, - {RTE_IPV4(198, 18, 2, 0), 24, 2}, - {RTE_IPV4(198, 18, 3, 0), 24, 3}, - {RTE_IPV4(198, 18, 4, 0), 24, 4}, - {RTE_IPV4(198, 18, 5, 0), 24, 5}, - {RTE_IPV4(198, 18, 6, 0), 24, 6}, - {RTE_IPV4(198, 18, 7, 0), 24, 7}, -}; - -/* - * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180). - * 2001:200:0:{0-7}::/64 = Port {0-7} - */ -static const struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = { - {{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 0}, - {{32, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 1}, - {{32, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 2}, - {{32, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 3}, - {{32, 1, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 4}, - {{32, 1, 2, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 5}, - {{32, 1, 2, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 6}, - {{32, 1, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 7}, -}; +#include "l3fwd_common_route.h" #define IPV4_L3FWD_LPM_MAX_RULES 1024 #define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8) @@ -485,18 +445,18 @@ setup_lpm(const int socketid) socketid); /* populate the LPM table */ - for (i = 0; i < RTE_DIM(ipv4_l3fwd_lpm_route_array); i++) { + for (i = 0; i < RTE_DIM(ipv4_l3fwd_common_route_array); i++) { struct in_addr in; /* skip unused ports */ - if ((1 << ipv4_l3fwd_lpm_route_array[i].if_out & + if ((1 << ipv4_l3fwd_common_route_array[i].if_out & enabled_port_mask) == 0) continue; ret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid], - ipv4_l3fwd_lpm_route_array[i].ip, - ipv4_l3fwd_lpm_route_array[i].depth, - ipv4_l3fwd_lpm_route_array[i].if_out); + ipv4_l3fwd_common_route_array[i].ip, + ipv4_l3fwd_common_route_array[i].depth, + ipv4_l3fwd_common_route_array[i].if_out); if (ret < 0) { rte_exit(EXIT_FAILURE, @@ -504,11 +464,11 @@ setup_lpm(const int socketid) i, socketid); } - in.s_addr = htonl(ipv4_l3fwd_lpm_route_array[i].ip); + in.s_addr = htonl(ipv4_l3fwd_common_route_array[i].ip); printf("LPM: Adding route %s / %d (%d)\n", inet_ntop(AF_INET, &in, abuf, sizeof(abuf)), - ipv4_l3fwd_lpm_route_array[i].depth, - ipv4_l3fwd_lpm_route_array[i].if_out); + ipv4_l3fwd_common_route_array[i].depth, + ipv4_l3fwd_common_route_array[i].if_out); } /* create the LPM6 table */ @@ -525,17 +485,17 @@ setup_lpm(const int socketid) socketid); /* populate the LPM table */ - for (i = 0; i < RTE_DIM(ipv6_l3fwd_lpm_route_array); i++) { + for (i = 0; i < RTE_DIM(ipv6_l3fwd_common_route_array); i++) { /* skip unused ports */ - if ((1 << ipv6_l3fwd_lpm_route_array[i].if_out & + if ((1 << ipv6_l3fwd_common_route_array[i].if_out & enabled_port_mask) == 0) continue; ret = rte_lpm6_add(ipv6_l3fwd_lpm_lookup_struct[socketid], - ipv6_l3fwd_lpm_route_array[i].ip, - ipv6_l3fwd_lpm_route_array[i].depth, - ipv6_l3fwd_lpm_route_array[i].if_out); + ipv6_l3fwd_common_route_array[i].ip, + ipv6_l3fwd_common_route_array[i].depth, + ipv6_l3fwd_common_route_array[i].if_out); if (ret < 0) { rte_exit(EXIT_FAILURE, @@ -544,10 +504,10 @@ setup_lpm(const int socketid) } printf("LPM: Adding route %s / %d (%d)\n", - inet_ntop(AF_INET6, ipv6_l3fwd_lpm_route_array[i].ip, + inet_ntop(AF_INET6, ipv6_l3fwd_common_route_array[i].ip, abuf, sizeof(abuf)), - ipv6_l3fwd_lpm_route_array[i].depth, - ipv6_l3fwd_lpm_route_array[i].if_out); + ipv6_l3fwd_common_route_array[i].depth, + ipv6_l3fwd_common_route_array[i].if_out); } } From patchwork Thu Feb 18 12:15:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 87977 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 3F36FA054D; Thu, 18 Feb 2021 13:16:42 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 59962160754; Thu, 18 Feb 2021 13:16:26 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 2A644160749 for ; Thu, 18 Feb 2021 13:16:23 +0100 (CET) IronPort-SDR: bnQ9576hc7HGUAgAJCkXFvfChk8Voe3qBiuKrlyGmWnooQrf+ENiwrqIrCw2joowjFuYrsB/bS PA1wlObExeyg== X-IronPort-AV: E=McAfee;i="6000,8403,9898"; a="244937293" X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="244937293" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2021 04:16:23 -0800 IronPort-SDR: PoaQK9bATREnhwpgqnljgegOvoIEM4gFvxAgoEI8ib3n8QZfeWGlzmhZPZOgRGcy6yopFatIoU Sal3a6HFu1bQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="385921527" Received: from silpixa00400466.ir.intel.com ([10.237.213.210]) by fmsmga008.fm.intel.com with ESMTP; 18 Feb 2021 04:16:21 -0800 From: Conor Walsh To: jerinj@marvell.com, stephen@networkplumber.org, bernard.iremonger@intel.com, konstantin.ananyev@intel.com, vladimir.medvedkin@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Thu, 18 Feb 2021 12:15:50 +0000 Message-Id: <20210218121552.1888092-4-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218121552.1888092-1-conor.walsh@intel.com> References: <20210218121552.1888092-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 3/5] examples/l3fwd: add FIB infrastructure 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 Sender: "dev" The purpose of this commit is to add the necessary function calls and supporting infrastructure to allow the Forwarding Information Base (FIB) library to be integrated into the l3fwd sample app. The flag '-F' has been added to the applications options to allow the user to specify that l3fwd uses FIB as its lookup method. Signed-off-by: Conor Walsh --- examples/l3fwd/Makefile | 2 +- examples/l3fwd/l3fwd.h | 27 ++++++++++++++-- examples/l3fwd/l3fwd_event.c | 9 ++++++ examples/l3fwd/l3fwd_event.h | 1 + examples/l3fwd/l3fwd_fib.c | 60 ++++++++++++++++++++++++++++++++++++ examples/l3fwd/main.c | 43 +++++++++++++++++++------- examples/l3fwd/meson.build | 4 +-- 7 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 examples/l3fwd/l3fwd_fib.c diff --git a/examples/l3fwd/Makefile b/examples/l3fwd/Makefile index 7e70bbd826..5f7baffbf7 100644 --- a/examples/l3fwd/Makefile +++ b/examples/l3fwd/Makefile @@ -5,7 +5,7 @@ APP = l3fwd # all source are stored in SRCS-y -SRCS-y := main.c l3fwd_lpm.c l3fwd_em.c l3fwd_event.c +SRCS-y := main.c l3fwd_lpm.c l3fwd_fib.c l3fwd_em.c l3fwd_event.c SRCS-y += l3fwd_event_generic.c l3fwd_event_internal_port.c # Build using pkg-config variables if possible diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h index 2cf06099e0..a808d60247 100644 --- a/examples/l3fwd/l3fwd.h +++ b/examples/l3fwd/l3fwd.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation + * Copyright(c) 2010-2021 Intel Corporation */ #ifndef __L3_FWD_H__ @@ -180,13 +180,16 @@ is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len) int init_mem(uint16_t portid, unsigned int nb_mbuf); -/* Function pointers for LPM or EM functionality. */ +/* Function pointers for LPM, EM or FIB functionality. */ void setup_lpm(const int socketid); void setup_hash(const int socketid); +void +setup_fib(const int socketid); + int em_check_ptype(int portid); @@ -207,6 +210,9 @@ em_main_loop(__rte_unused void *dummy); int lpm_main_loop(__rte_unused void *dummy); +int +fib_main_loop(__rte_unused void *dummy); + int lpm_event_main_loop_tx_d(__rte_unused void *dummy); int @@ -225,8 +231,17 @@ em_event_main_loop_tx_q(__rte_unused void *dummy); int em_event_main_loop_tx_q_burst(__rte_unused void *dummy); +int +fib_event_main_loop_tx_d(__rte_unused void *dummy); +int +fib_event_main_loop_tx_d_burst(__rte_unused void *dummy); +int +fib_event_main_loop_tx_q(__rte_unused void *dummy); +int +fib_event_main_loop_tx_q_burst(__rte_unused void *dummy); + -/* Return ipv4/ipv6 fwd lookup struct for LPM or EM. */ +/* Return ipv4/ipv6 fwd lookup struct for LPM, EM or FIB. */ void * em_get_ipv4_l3fwd_lookup_struct(const int socketid); @@ -239,4 +254,10 @@ lpm_get_ipv4_l3fwd_lookup_struct(const int socketid); void * lpm_get_ipv6_l3fwd_lookup_struct(const int socketid); +void * +fib_get_ipv4_l3fwd_lookup_struct(const int socketid); + +void * +fib_get_ipv6_l3fwd_lookup_struct(const int socketid); + #endif /* __L3_FWD_H__ */ diff --git a/examples/l3fwd/l3fwd_event.c b/examples/l3fwd/l3fwd_event.c index 4d31593a0a..961860ea18 100644 --- a/examples/l3fwd/l3fwd_event.c +++ b/examples/l3fwd/l3fwd_event.c @@ -227,6 +227,12 @@ l3fwd_event_resource_setup(struct rte_eth_conf *port_conf) [1][0] = em_event_main_loop_tx_q, [1][1] = em_event_main_loop_tx_q_burst, }; + const event_loop_cb fib_event_loop[2][2] = { + [0][0] = fib_event_main_loop_tx_d, + [0][1] = fib_event_main_loop_tx_d_burst, + [1][0] = fib_event_main_loop_tx_q, + [1][1] = fib_event_main_loop_tx_q_burst, + }; uint32_t event_queue_cfg; int ret; @@ -264,4 +270,7 @@ l3fwd_event_resource_setup(struct rte_eth_conf *port_conf) evt_rsrc->ops.em_event_loop = em_event_loop[evt_rsrc->tx_mode_q] [evt_rsrc->has_burst]; + + evt_rsrc->ops.fib_event_loop = fib_event_loop[evt_rsrc->tx_mode_q] + [evt_rsrc->has_burst]; } diff --git a/examples/l3fwd/l3fwd_event.h b/examples/l3fwd/l3fwd_event.h index 0e46164170..3ad1902ab5 100644 --- a/examples/l3fwd/l3fwd_event.h +++ b/examples/l3fwd/l3fwd_event.h @@ -55,6 +55,7 @@ struct l3fwd_event_setup_ops { adapter_setup_cb adapter_setup; event_loop_cb lpm_event_loop; event_loop_cb em_event_loop; + event_loop_cb fib_event_loop; }; struct l3fwd_event_resources { diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c new file mode 100644 index 0000000000..0a2d02db2f --- /dev/null +++ b/examples/l3fwd/l3fwd_fib.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 Intel Corporation + */ + +#include +#include + +#include "l3fwd.h" +#include "l3fwd_event.h" +#include "l3fwd_common_route.h" + +/* Main fib processing loop. */ +int +fib_main_loop(__rte_unused void *dummy) +{ + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_d(__rte_unused void *dummy) +{ + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_d_burst(__rte_unused void *dummy) +{ + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_q(__rte_unused void *dummy) +{ + return 0; +} + +int __rte_noinline +fib_event_main_loop_tx_q_burst(__rte_unused void *dummy) +{ + return 0; +} + +/* Function to setup fib. */ +void +setup_fib(__rte_unused const int socketid) +{} + +/* Return ipv4 fib lookup struct. */ +void * +fib_get_ipv4_l3fwd_lookup_struct(__rte_unused const int socketid) +{ + return 0; +} + +/* Return ipv6 fib lookup struct. */ +void * +fib_get_ipv6_l3fwd_lookup_struct(__rte_unused const int socketid) +{ + return 0; +} diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c index bb49e5faff..6881b49478 100644 --- a/examples/l3fwd/main.c +++ b/examples/l3fwd/main.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2016 Intel Corporation + * Copyright(c) 2010-2021 Intel Corporation */ #include @@ -60,9 +60,10 @@ static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Ports set in promiscuous mode off by default. */ static int promiscuous_on; -/* Select Longest-Prefix or Exact match. */ +/* Select Longest-Prefix, Exact match or Forwarding Information Base. */ static int l3fwd_lpm_on; static int l3fwd_em_on; +static int l3fwd_fib_on; /* Global variables. */ @@ -162,10 +163,19 @@ static struct l3fwd_lkp_mode l3fwd_lpm_lkp = { .get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct, }; +static struct l3fwd_lkp_mode l3fwd_fib_lkp = { + .setup = setup_fib, + .check_ptype = lpm_check_ptype, + .cb_parse_ptype = lpm_cb_parse_ptype, + .main_loop = fib_main_loop, + .get_ipv4_lookup_struct = fib_get_ipv4_l3fwd_lookup_struct, + .get_ipv6_lookup_struct = fib_get_ipv6_l3fwd_lookup_struct, +}; + /* * Setup lookup methods for forwarding. - * Currently exact-match and longest-prefix-match - * are supported ones. + * Currently exact-match, longest-prefix-match and forwarding information + * base are the supported ones. */ static void setup_l3fwd_lookup_tables(void) @@ -173,6 +183,9 @@ setup_l3fwd_lookup_tables(void) /* Setup HASH lookup functions. */ if (l3fwd_em_on) l3fwd_lkp = l3fwd_em_lkp; + /* Setup FIB lookup functions. */ + else if (l3fwd_fib_on) + l3fwd_lkp = l3fwd_fib_lkp; /* Setup LPM lookup functions. */ else l3fwd_lkp = l3fwd_lpm_lkp; @@ -292,6 +305,7 @@ print_usage(const char *prgname) " -P : Enable promiscuous mode\n" " -E : Enable exact match\n" " -L : Enable longest prefix match (default)\n" + " -F : Enable forwarding information base\n" " --config (port,queue,lcore): Rx queue configuration\n" " --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for port X\n" " --enable-jumbo: Enable jumbo frames\n" @@ -492,6 +506,7 @@ static const char short_options[] = "P" /* promiscuous */ "L" /* enable long prefix match */ "E" /* enable exact match */ + "F" /* forwarding information base */ ; #define CMD_LINE_OPT_CONFIG "config" @@ -596,6 +611,10 @@ parse_args(int argc, char **argv) l3fwd_lpm_on = 1; break; + case 'F': + l3fwd_fib_on = 1; + break; + /* long options */ case CMD_LINE_OPT_CONFIG_NUM: ret = parse_config(optarg); @@ -686,9 +705,9 @@ parse_args(int argc, char **argv) } } - /* If both LPM and EM are selected, return error. */ - if (l3fwd_lpm_on && l3fwd_em_on) { - fprintf(stderr, "LPM and EM are mutually exclusive, select only one\n"); + /* If more than 1 of LPM, EM and FIB are selected, return error. */ + if ((l3fwd_lpm_on + l3fwd_em_on + l3fwd_fib_on) > 1) { + fprintf(stderr, "LPM, EM and FIB are mutually exclusive, select only one\n"); return -1; } @@ -711,14 +730,14 @@ parse_args(int argc, char **argv) * Nothing is selected, pick longest-prefix match * as default match. */ - if (!l3fwd_lpm_on && !l3fwd_em_on) { - fprintf(stderr, "LPM or EM none selected, default LPM on\n"); + if (!l3fwd_lpm_on && !l3fwd_em_on && !l3fwd_fib_on) { + fprintf(stderr, "Neither LPM, EM, or FIB selected, default LPM on\n"); l3fwd_lpm_on = 1; } /* * ipv6 and hash flags are valid only for - * exact macth, reset them to default for + * exact match, reset them to default for * longest-prefix match. */ if (l3fwd_lpm_on) { @@ -780,7 +799,7 @@ init_mem(uint16_t portid, unsigned int nb_mbuf) printf("Allocated mbuf pool on socket %d\n", socketid); - /* Setup either LPM or EM(f.e Hash). But, only once per + /* Setup LPM, EM(f.e Hash) or FIB. But, only once per * available socket. */ if (!lkp_per_socket[socketid]) { @@ -1221,6 +1240,8 @@ main(int argc, char **argv) l3fwd_event_resource_setup(&port_conf); if (l3fwd_em_on) l3fwd_lkp.main_loop = evt_rsrc->ops.em_event_loop; + else if (l3fwd_fib_on) + l3fwd_lkp.main_loop = evt_rsrc->ops.fib_event_loop; else l3fwd_lkp.main_loop = evt_rsrc->ops.lpm_event_loop; l3fwd_event_service_setup(); diff --git a/examples/l3fwd/meson.build b/examples/l3fwd/meson.build index 7d72b1b365..2e5d1d34f2 100644 --- a/examples/l3fwd/meson.build +++ b/examples/l3fwd/meson.build @@ -7,8 +7,8 @@ # DPDK instance, use 'make' allow_experimental_apis = true -deps += ['hash', 'lpm', 'eventdev'] +deps += ['hash', 'lpm', 'fib', 'eventdev'] sources = files( - 'l3fwd_em.c', 'l3fwd_lpm.c', 'l3fwd_event.c', + 'l3fwd_em.c', 'l3fwd_lpm.c', 'l3fwd_fib.c', 'l3fwd_event.c', 'l3fwd_event_internal_port.c', 'l3fwd_event_generic.c', 'main.c' ) From patchwork Thu Feb 18 12:15:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 87978 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 8EE13A054D; Thu, 18 Feb 2021 13:16:50 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 15830160763; Thu, 18 Feb 2021 13:16:28 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 2F47B160752 for ; Thu, 18 Feb 2021 13:16:26 +0100 (CET) IronPort-SDR: EdmnplWWFyAjxm4WBYdHVZXr+TaMCa2XiOn04TlHewXvlOZk+o/PUp59XYmQHzRksVk/tzzR8x Wv+xMfXk5rmg== X-IronPort-AV: E=McAfee;i="6000,8403,9898"; a="244937308" X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="244937308" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2021 04:16:25 -0800 IronPort-SDR: n/t4ITcoQJzEXUQqZ9Rtzm30544QMMkkVz9oq8Q8/4SUPV0Z0G4o8RYgx+whf1ni4PNZT1a0C3 gExFy/olEFdg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="385921537" Received: from silpixa00400466.ir.intel.com ([10.237.213.210]) by fmsmga008.fm.intel.com with ESMTP; 18 Feb 2021 04:16:23 -0800 From: Conor Walsh To: jerinj@marvell.com, stephen@networkplumber.org, bernard.iremonger@intel.com, konstantin.ananyev@intel.com, vladimir.medvedkin@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Thu, 18 Feb 2021 12:15:51 +0000 Message-Id: <20210218121552.1888092-5-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218121552.1888092-1-conor.walsh@intel.com> References: <20210218121552.1888092-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 4/5] examples/l3fwd: implement FIB lookup method 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 Sender: "dev" This patch implements the Forwarding Information Base (FIB) library in l3fwd using the function calls and infrastructure introduced in the previous patch. Signed-off-by: Conor Walsh --- examples/l3fwd/l3fwd_fib.c | 440 ++++++++++++++++++++++++++++++++++++- 1 file changed, 434 insertions(+), 6 deletions(-) diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c index 0a2d02db2f..b45b20e06a 100644 --- a/examples/l3fwd/l3fwd_fib.c +++ b/examples/l3fwd/l3fwd_fib.c @@ -2,59 +2,487 @@ * Copyright(c) 2021 Intel Corporation */ +#include +#include +#include +#include + #include #include #include "l3fwd.h" +#include "l3fwd_sse.h" #include "l3fwd_event.h" #include "l3fwd_common_route.h" +/* Configure how many packets ahead to prefetch for fib. */ +#define FIB_PREFETCH_OFFSET 4 + +/* A non-existent portid is needed to denote a default hop for fib. */ +#define FIB_DEFAULT_HOP 999 + +static struct rte_fib *ipv4_l3fwd_fib_lookup_struct[NB_SOCKETS]; +static struct rte_fib6 *ipv6_l3fwd_fib_lookup_struct[NB_SOCKETS]; + +/* Parse packet type and ip address. */ +static inline void +l3fwd_fib_parse_packet(struct rte_mbuf *mbuf, + uint32_t *ipv4, uint32_t *ipv4_cnt, + uint8_t ipv6[RTE_FIB6_IPV6_ADDR_SIZE], + uint32_t *ipv6_cnt, uint8_t *ip_type) +{ + struct rte_ether_hdr *eth_hdr; + struct rte_ipv4_hdr *ipv4_hdr; + struct rte_ipv6_hdr *ipv6_hdr; + + eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *); + /* IPv4 */ + if (mbuf->packet_type & RTE_PTYPE_L3_IPV4) { + ipv4_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1); + *ipv4 = rte_be_to_cpu_32(ipv4_hdr->dst_addr); + /* Store type of packet in type_arr (IPv4=1, IPv6=0). */ + *ip_type = 1; + (*ipv4_cnt)++; + } + /* IPv6 */ + else { + ipv6_hdr = (struct rte_ipv6_hdr *)(eth_hdr + 1); + rte_mov16(ipv6, (const uint8_t *)ipv6_hdr->dst_addr); + *ip_type = 0; + (*ipv6_cnt)++; + } +} + +/* Bulk parse, fib lookup and send. */ +static inline void +l3fwd_fib_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, + uint16_t portid, struct lcore_conf *qconf) +{ + uint32_t ipv4_arr[nb_rx]; + uint8_t ipv6_arr[nb_rx][RTE_FIB6_IPV6_ADDR_SIZE]; + uint16_t hops[nb_rx]; + uint64_t hopsv4[nb_rx], hopsv6[nb_rx]; + uint8_t type_arr[nb_rx]; + uint32_t ipv4_cnt = 0, ipv6_cnt = 0; + uint32_t ipv4_reassem = 0, ipv6_reassem = 0; + int32_t i; + + /* Prefetch first packets. */ + for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_rx; i++) + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i], void *)); + + /* Parse packet info and prefetch. */ + for (i = 0; i < (nb_rx - FIB_PREFETCH_OFFSET); i++) { + /* Prefetch packet. */ + rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[ + i + FIB_PREFETCH_OFFSET], + void *)); + l3fwd_fib_parse_packet(pkts_burst[i], + &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, + &type_arr[i]); + } + + /* Parse remaining packet info. */ + for (; i < nb_rx; i++) + l3fwd_fib_parse_packet(pkts_burst[i], + &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, + &type_arr[i]); + + /* Lookup IPv4 hops if IPv4 packets are present. */ + if (likely(ipv4_cnt > 0)) + rte_fib_lookup_bulk(qconf->ipv4_lookup_struct, + ipv4_arr, hopsv4, ipv4_cnt); + + /* Lookup IPv6 hops if IPv6 packets are present. */ + if (ipv6_cnt > 0) + rte_fib6_lookup_bulk(qconf->ipv6_lookup_struct, + ipv6_arr, hopsv6, ipv6_cnt); + + /* Add IPv4 and IPv6 hops to one array depending on type. */ + for (i = 0; i < nb_rx; i++) { + if (type_arr[i]) { + if (hopsv4[ipv4_reassem] != FIB_DEFAULT_HOP) + hops[i] = (uint16_t)hopsv4[ipv4_reassem]; + else + hops[i] = portid; + ipv4_reassem++; + } else { + if (hopsv6[ipv6_reassem] != FIB_DEFAULT_HOP) + hops[i] = (uint16_t)hopsv6[ipv6_reassem]; + else + hops[i] = portid; + ipv6_reassem++; + } + } + + send_packets_multi(qconf, pkts_burst, hops, nb_rx); +} + /* Main fib processing loop. */ int fib_main_loop(__rte_unused void *dummy) { + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + unsigned int lcore_id; + uint64_t prev_tsc, diff_tsc, cur_tsc; + int i, nb_rx; + uint16_t portid; + uint8_t queueid; + struct lcore_conf *qconf; + const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / + US_PER_S * BURST_TX_DRAIN_US; + + prev_tsc = 0; + + lcore_id = rte_lcore_id(); + qconf = &lcore_conf[lcore_id]; + + if (qconf->n_rx_queue == 0) { + RTE_LOG(INFO, L3FWD, "lcore %u has nothing to do\n", lcore_id); + return 0; + } + + RTE_LOG(INFO, L3FWD, "entering main loop on lcore %u\n", lcore_id); + + for (i = 0; i < qconf->n_rx_queue; i++) { + + portid = qconf->rx_queue_list[i].port_id; + queueid = qconf->rx_queue_list[i].queue_id; + RTE_LOG(INFO, L3FWD, + " -- lcoreid=%u portid=%u rxqueueid=%hhu\n", + lcore_id, portid, queueid); + } + + while (!force_quit) { + + cur_tsc = rte_rdtsc(); + + /* TX burst queue drain. */ + diff_tsc = cur_tsc - prev_tsc; + if (unlikely(diff_tsc > drain_tsc)) { + + for (i = 0; i < qconf->n_tx_port; ++i) { + portid = qconf->tx_port_id[i]; + if (qconf->tx_mbufs[portid].len == 0) + continue; + send_burst(qconf, + qconf->tx_mbufs[portid].len, + portid); + qconf->tx_mbufs[portid].len = 0; + } + + prev_tsc = cur_tsc; + } + + /* Read packet from RX queues. */ + for (i = 0; i < qconf->n_rx_queue; ++i) { + portid = qconf->rx_queue_list[i].port_id; + queueid = qconf->rx_queue_list[i].queue_id; + nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst, + MAX_PKT_BURST); + if (nb_rx == 0) + continue; + + /* Use fib to lookup port IDs and transmit them. */ + l3fwd_fib_send_packets(nb_rx, pkts_burst, + portid, qconf); + } + } + return 0; } +/* One eventdev loop for single and burst using fib. */ +static __rte_always_inline void +fib_event_loop(struct l3fwd_event_resources *evt_rsrc, + const uint8_t flags) +{ + const int event_p_id = l3fwd_get_free_event_port(evt_rsrc); + const uint8_t tx_q_id = evt_rsrc->evq.event_q_id[ + evt_rsrc->evq.nb_queues - 1]; + const uint8_t event_d_id = evt_rsrc->event_d_id; + const uint16_t deq_len = evt_rsrc->deq_depth; + struct rte_event events[MAX_PKT_BURST]; + struct lcore_conf *lconf; + unsigned int lcore_id; + int nb_enq, nb_deq, i; + + uint32_t ipv4_arr[MAX_PKT_BURST]; + uint8_t ipv6_arr[MAX_PKT_BURST][RTE_FIB6_IPV6_ADDR_SIZE]; + uint64_t hopsv4[MAX_PKT_BURST], hopsv6[MAX_PKT_BURST]; + uint8_t type_arr[MAX_PKT_BURST]; + uint32_t ipv4_cnt, ipv6_cnt; + uint32_t ipv4_reassem, ipv6_reassem; + + if (event_p_id < 0) + return; + + lcore_id = rte_lcore_id(); + + lconf = &lcore_conf[lcore_id]; + + RTE_LOG(INFO, L3FWD, "entering %s on lcore %u\n", __func__, lcore_id); + + while (!force_quit) { + /* Read events from RX queues. */ + nb_deq = rte_event_dequeue_burst(event_d_id, event_p_id, + events, deq_len, 0); + if (nb_deq == 0) { + rte_pause(); + continue; + } + + /* Reset counters. */ + ipv4_cnt = 0; + ipv6_cnt = 0; + ipv4_reassem = 0; + ipv6_reassem = 0; + + /* Prefetch first packets. */ + for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_deq; i++) + rte_prefetch0(rte_pktmbuf_mtod(events[i].mbuf, void *)); + + /* Parse packet info and prefetch. */ + for (i = 0; i < (nb_deq - FIB_PREFETCH_OFFSET); i++) { + if (flags & L3FWD_EVENT_TX_ENQ) { + events[i].queue_id = tx_q_id; + events[i].op = RTE_EVENT_OP_FORWARD; + } + + if (flags & L3FWD_EVENT_TX_DIRECT) + rte_event_eth_tx_adapter_txq_set(events[i].mbuf, + 0); + + /* Prefetch packet. */ + rte_prefetch0(rte_pktmbuf_mtod(events[ + i + FIB_PREFETCH_OFFSET].mbuf, + void *)); + + l3fwd_fib_parse_packet(events[i].mbuf, + &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, + &type_arr[i]); + } + + /* Parse remaining packet info. */ + for (; i < nb_deq; i++) { + if (flags & L3FWD_EVENT_TX_ENQ) { + events[i].queue_id = tx_q_id; + events[i].op = RTE_EVENT_OP_FORWARD; + } + + if (flags & L3FWD_EVENT_TX_DIRECT) + rte_event_eth_tx_adapter_txq_set(events[i].mbuf, + 0); + + l3fwd_fib_parse_packet(events[i].mbuf, + &ipv4_arr[ipv4_cnt], &ipv4_cnt, + ipv6_arr[ipv6_cnt], &ipv6_cnt, + &type_arr[i]); + } + + /* Lookup IPv4 hops if IPv4 packets are present. */ + if (likely(ipv4_cnt > 0)) + rte_fib_lookup_bulk(lconf->ipv4_lookup_struct, + ipv4_arr, hopsv4, ipv4_cnt); + + /* Lookup IPv6 hops if IPv6 packets are present. */ + if (ipv6_cnt > 0) + rte_fib6_lookup_bulk(lconf->ipv6_lookup_struct, + ipv6_arr, hopsv6, ipv6_cnt); + + /* Assign ports looked up in fib depending on IPv4 or IPv6 */ + for (i = 0; i < nb_deq; i++) { + if (type_arr[i]) { + if (hopsv4[ipv4_reassem] != FIB_DEFAULT_HOP) + events[i].mbuf->port = + (uint16_t)hopsv4[ipv4_reassem]; + ipv4_reassem++; + } else { + if (hopsv6[ipv6_reassem] != FIB_DEFAULT_HOP) + events[i].mbuf->port = + (uint16_t)hopsv6[ipv6_reassem]; + ipv6_reassem++; + } + } + + if (flags & L3FWD_EVENT_TX_ENQ) { + nb_enq = rte_event_enqueue_burst(event_d_id, event_p_id, + events, nb_deq); + while (nb_enq < nb_deq && !force_quit) + nb_enq += rte_event_enqueue_burst(event_d_id, + event_p_id, events + nb_enq, + nb_deq - nb_enq); + } + + if (flags & L3FWD_EVENT_TX_DIRECT) { + nb_enq = rte_event_eth_tx_adapter_enqueue(event_d_id, + event_p_id, events, nb_deq, 0); + while (nb_enq < nb_deq && !force_quit) + nb_enq += rte_event_eth_tx_adapter_enqueue( + event_d_id, event_p_id, + events + nb_enq, + nb_deq - nb_enq, 0); + } + } +} + int __rte_noinline fib_event_main_loop_tx_d(__rte_unused void *dummy) { + struct l3fwd_event_resources *evt_rsrc = + l3fwd_get_eventdev_rsrc(); + + fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_DIRECT); return 0; } int __rte_noinline fib_event_main_loop_tx_d_burst(__rte_unused void *dummy) { + struct l3fwd_event_resources *evt_rsrc = + l3fwd_get_eventdev_rsrc(); + + fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_DIRECT); return 0; } int __rte_noinline fib_event_main_loop_tx_q(__rte_unused void *dummy) { + struct l3fwd_event_resources *evt_rsrc = + l3fwd_get_eventdev_rsrc(); + + fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_ENQ); return 0; } int __rte_noinline fib_event_main_loop_tx_q_burst(__rte_unused void *dummy) { + struct l3fwd_event_resources *evt_rsrc = + l3fwd_get_eventdev_rsrc(); + + fib_event_loop(evt_rsrc, L3FWD_EVENT_TX_ENQ); return 0; } /* Function to setup fib. */ void -setup_fib(__rte_unused const int socketid) -{} +setup_fib(const int socketid) +{ + struct rte_fib6_conf config; + struct rte_fib_conf config_ipv4; + unsigned int i; + int ret; + char s[64]; + char abuf[INET6_ADDRSTRLEN]; + + /* Create the fib IPv4 table. */ + config_ipv4.type = RTE_FIB_DIR24_8; + config_ipv4.max_routes = (1 << 16); + config_ipv4.default_nh = FIB_DEFAULT_HOP; + config_ipv4.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; + config_ipv4.dir24_8.num_tbl8 = (1 << 15); + snprintf(s, sizeof(s), "IPV4_L3FWD_FIB_%d", socketid); + ipv4_l3fwd_fib_lookup_struct[socketid] = + rte_fib_create(s, socketid, &config_ipv4); + if (ipv4_l3fwd_fib_lookup_struct[socketid] == NULL) + rte_exit(EXIT_FAILURE, + "Unable to create the l3fwd FIB table on socket %d\n", + socketid); + + /* Populate the fib ipv4 table. */ + for (i = 0; i < RTE_DIM(ipv4_l3fwd_common_route_array); i++) { + struct in_addr in; + + /* Skip unused ports. */ + if ((1 << ipv4_l3fwd_common_route_array[i].if_out & + enabled_port_mask) == 0) + continue; + + ret = rte_fib_add(ipv4_l3fwd_fib_lookup_struct[socketid], + ipv4_l3fwd_common_route_array[i].ip, + ipv4_l3fwd_common_route_array[i].depth, + ipv4_l3fwd_common_route_array[i].if_out); + + if (ret < 0) { + rte_exit(EXIT_FAILURE, + "Unable to add entry %u to the l3fwd FIB table on socket %d\n", + i, socketid); + } + + in.s_addr = htonl(ipv4_l3fwd_common_route_array[i].ip); + if (inet_ntop(AF_INET, &in, abuf, sizeof(abuf)) != NULL) { + printf("FIB: Adding route %s / %d (%d)\n", + abuf, + ipv4_l3fwd_common_route_array[i].depth, + ipv4_l3fwd_common_route_array[i].if_out); + } else { + printf("FIB: IPv4 route added to port %d\n", + ipv4_l3fwd_common_route_array[i].if_out); + } + } + + /* Create the fib IPv6 table. */ + snprintf(s, sizeof(s), "IPV6_L3FWD_FIB_%d", socketid); + + config.type = RTE_FIB6_TRIE; + config.max_routes = (1 << 16) - 1; + config.default_nh = FIB_DEFAULT_HOP; + config.trie.nh_sz = RTE_FIB6_TRIE_4B; + config.trie.num_tbl8 = (1 << 15); + ipv6_l3fwd_fib_lookup_struct[socketid] = rte_fib6_create(s, socketid, + &config); + if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL) + rte_exit(EXIT_FAILURE, + "Unable to create the l3fwd FIB table on socket %d\n", + socketid); + + /* Populate the fib IPv6 table. */ + for (i = 0; i < RTE_DIM(ipv6_l3fwd_common_route_array); i++) { + + /* Skip unused ports. */ + if ((1 << ipv6_l3fwd_common_route_array[i].if_out & + enabled_port_mask) == 0) + continue; + + ret = rte_fib6_add(ipv6_l3fwd_fib_lookup_struct[socketid], + ipv6_l3fwd_common_route_array[i].ip, + ipv6_l3fwd_common_route_array[i].depth, + ipv6_l3fwd_common_route_array[i].if_out); + + if (ret < 0) { + rte_exit(EXIT_FAILURE, + "Unable to add entry %u to the l3fwd FIB table on socket %d\n", + i, socketid); + } + + if (inet_ntop(AF_INET6, ipv6_l3fwd_common_route_array[i].ip, + abuf, sizeof(abuf)) != NULL) { + printf("FIB: Adding route %s / %d (%d)\n", + abuf, + ipv6_l3fwd_common_route_array[i].depth, + ipv6_l3fwd_common_route_array[i].if_out); + } else { + printf("FIB: IPv6 route added to port %d\n", + ipv6_l3fwd_common_route_array[i].if_out); + } + } +} /* Return ipv4 fib lookup struct. */ void * -fib_get_ipv4_l3fwd_lookup_struct(__rte_unused const int socketid) +fib_get_ipv4_l3fwd_lookup_struct(const int socketid) { - return 0; + return ipv4_l3fwd_fib_lookup_struct[socketid]; } /* Return ipv6 fib lookup struct. */ void * -fib_get_ipv6_l3fwd_lookup_struct(__rte_unused const int socketid) +fib_get_ipv6_l3fwd_lookup_struct(const int socketid) { - return 0; + return ipv6_l3fwd_fib_lookup_struct[socketid]; } From patchwork Thu Feb 18 12:15:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Conor Walsh X-Patchwork-Id: 87979 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 AB105A054D; Thu, 18 Feb 2021 13:16:57 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 548CB160747; Thu, 18 Feb 2021 13:16:30 +0100 (CET) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id 3E477160766 for ; Thu, 18 Feb 2021 13:16:28 +0100 (CET) IronPort-SDR: /GzcoRXzAET8siA5mGyYadIZYyHDug+cjhPubPzm5tBMVHSV4aOfkKIDGcjWFGMFNy66B+KRiE NJ5dLfyCDL3w== X-IronPort-AV: E=McAfee;i="6000,8403,9898"; a="244937317" X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="244937317" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2021 04:16:27 -0800 IronPort-SDR: ndPnyAHgez1mePqjmnkj3/tAfMoRCIFBLlrBGp+KSdeTW7Mz5yooWZrqcVOWmRPdfO18ChWNbj CviJLMMxPfqQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,187,1610438400"; d="scan'208";a="385921549" Received: from silpixa00400466.ir.intel.com ([10.237.213.210]) by fmsmga008.fm.intel.com with ESMTP; 18 Feb 2021 04:16:25 -0800 From: Conor Walsh To: jerinj@marvell.com, stephen@networkplumber.org, bernard.iremonger@intel.com, konstantin.ananyev@intel.com, vladimir.medvedkin@intel.com Cc: dev@dpdk.org, Conor Walsh Date: Thu, 18 Feb 2021 12:15:52 +0000 Message-Id: <20210218121552.1888092-6-conor.walsh@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210218121552.1888092-1-conor.walsh@intel.com> References: <20210218121552.1888092-1-conor.walsh@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 5/5] doc/guides/l3_forward: update documentation for FIB 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 Sender: "dev" The purpose of this patch is to update the l3fwd user guide to include the changes proposed in this patchset. Signed-off-by: Conor Walsh --- doc/guides/sample_app_ug/l3_forward.rst | 103 ++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 8 deletions(-) diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst index e7875f8dcd..266e1eb810 100644 --- a/doc/guides/sample_app_ug/l3_forward.rst +++ b/doc/guides/sample_app_ug/l3_forward.rst @@ -11,7 +11,7 @@ The application performs L3 forwarding. Overview -------- -The application demonstrates the use of the hash and LPM libraries in the DPDK +The application demonstrates the use of the hash, LPM and FIB libraries in DPDK to implement packet forwarding using poll or event mode PMDs for packet I/O. The initialization and run-time paths are very similar to those of the :doc:`l2_forward_real_virtual` and :doc:`l2_forward_event`. @@ -22,7 +22,7 @@ decision is made based on information read from the input packet. Eventdev can optionally use S/W or H/W (if supported by platform) scheduler implementation for packet I/O based on run time parameters. -The lookup method is either hash-based or LPM-based and is selected at run time. When the selected lookup method is hash-based, +The lookup method is hash-based, LPM-based or FIB-based and is selected at run time. When the selected lookup method is hash-based, a hash object is used to emulate the flow classification stage. The hash object is used in correlation with a flow table to map each input packet to its flow at runtime. @@ -30,14 +30,14 @@ The hash lookup key is represented by a DiffServ 5-tuple composed of the followi Source IP Address, Destination IP Address, Protocol, Source Port and Destination Port. The ID of the output interface for the input packet is read from the identified flow table entry. The set of flows used by the application is statically configured and loaded into the hash at initialization time. -When the selected lookup method is LPM based, an LPM object is used to emulate the forwarding stage for IPv4 packets. -The LPM object is used as the routing table to identify the next hop for each input packet at runtime. +When the selected lookup method is LPM or FIB based, an LPM or FIB object is used to emulate the forwarding stage for IPv4 packets. +The LPM or FIB object is used as the routing table to identify the next hop for each input packet at runtime. -The LPM lookup key is represented by the Destination IP Address field read from the input packet. -The ID of the output interface for the input packet is the next hop returned by the LPM lookup. -The set of LPM rules used by the application is statically configured and loaded into the LPM object at initialization time. +The LPM and FIB lookup keys are represented by the Destination IP Address field read from the input packet. +The ID of the output interface for the input packet is the next hop returned by the LPM or FIB lookup. +The set of LPM and FIB rules used by the application is statically configured and loaded into the LPM or FIB object at initialization time. -In the sample application, hash-based forwarding supports IPv4 and IPv6. LPM-based forwarding supports IPv4 only. +In the sample application, hash-based and FIB-based forwarding supports both IPv4 and IPv6. LPM-based forwarding supports IPv4 only. Compiling the Application ------------------------- @@ -55,6 +55,7 @@ The application has a number of command line options:: [-P] [-E] [-L] + [-F] --config(port,queue,lcore)[,(port,queue,lcore)] [--eth-dest=X,MM:MM:MM:MM:MM:MM] [--enable-jumbo [--max-pkt-len PKTLEN]] @@ -78,6 +79,8 @@ Where, * ``-L:`` Optional, enable longest prefix match. +* ``-F:`` Optional, enable forwarding information base. + * ``--config (port,queue,lcore)[,(port,queue,lcore)]:`` Determines which queues from which ports are mapped to which cores. * ``--eth-dest=X,MM:MM:MM:MM:MM:MM:`` Optional, ethernet destination for port X. @@ -290,6 +293,61 @@ The LPM object is created and loaded with the pre-configured entries read from a } #endif +FIB Initialization +~~~~~~~~~~~~~~~~~~ + +The FIB object is created and loaded with the pre-configured entries read from a global array. + +.. code-block:: c + + #if (APP_LOOKUP_METHOD == APP_LOOKUP_FIB) + + void + setup_fib(const int socketid) + { + unsigned int i; + int ret; + char s[64]; + + /* create the FIB table */ + + snprintf(s, sizeof(s), "IPV4_L3FWD_FIB_%d", socketid); + + ipv4_l3fwd_fib_lookup_struct[socketid] = rte_fib_create(s, socketid, IPV4_L3FWD_FIB_MAX_RULES); + + if (ipv4_l3fwd_fib_lookup_struct[socketid] == NULL) + rte_exit(EXIT_FAILURE, "Unable to create the l3fwd FIB table on socket %d\n", socketid); + + /* populate the FIB table */ + + for (i = 0; i < IPV4_L3FWD_NUM_ROUTES; i++) { + struct in_addr in; + + /* skip unused ports */ + if ((1 << ipv4_l3fwd_fib_route_array[i].if_out & enabled_port_mask) == 0) + continue; + + ret = rte_fib_add(ipv4_l3fwd_fib_lookup_struct[socketid], + ipv4_l3fwd_fib_route_array[i].ip, + ipv4_l3fwd_fib_route_array[i].depth, + ipv4_l3fwd_fib_route_array[i].if_out); + + if (ret < 0) { + rte_exit(EXIT_FAILURE, "Unable to add entry %u to the l3fwd FIB table on socket %d\n", + i, socketid); + } + + in.s_addr = htonl(ipv4_l3fwd_fib_route_array[i].ip); + printf("FIB: Adding route %s / %d (%d)\n", + inet_ntop(AF_INET, &in, abuf, sizeof(abuf)), + ipv4_l3fwd_fib_route_array[i].depth, + ipv4_l3fwd_fib_route_array[i].if_out); + } + + /* ipv6 omitted from this example for brevity */ + } + #endif + Packet Forwarding for Hash-based Lookups ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -380,6 +438,35 @@ for LPM-based lookups is done by the get_ipv4_dst_port() function below: return ((rte_lpm_lookup(ipv4_l3fwd_lookup_struct, rte_be_to_cpu_32(ipv4_hdr->dst_addr), &next_hop) == 0)? next_hop : portid); } +Packet Forwarding for FIB-based Lookups +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The FIB library was designed to process multiple packets at once, it does not have separate functions for single +and bulk lookups. ``rte_fib_lookup_bulk`` is used for ipv4 lookups and ``rte_fib6_lookup_bulk`` for ipv6. +An example of a FIB lookup function can be seen below: + +.. code-block:: c + + static inline uint16_t + fib_get_ipv4_dst_ports(struct rte_fib *ipv4_l3fwd_lookup_struct, uint32_t *ipv4_addrs, uint64_t *next_hops, uint16_t portid, int nb_pkts) + { + uint16_t hops[nb_pkts]; + + rte_fib_lookup_bulk(ipv4_l3fwd_lookup_struct, ipv4_addrs, next_hops, nb_pkts); + + /* + * If FIB has returned its default value for an unknown IP address set it to the portid supplied. + * FIB uses uint64_t for hops but l3fwd uses uint16_t so the values are cast. + */ + + for (i = 0; i < nb_pkts; i++) + (next_hops[i]==FIB_DEFAULT_HOP) ? (hops[i] = (uint16_t)portid) : (hops[i] = (uint16_t)next_hop[i]); + + return hops; + } + + /* IPv6 example omitted for brevity */ + Eventdev Driver Initialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Eventdev driver initialization is same as L2 forwarding eventdev application.