From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-BY2-obe.outbound.protection.outlook.com (mail-by2nam03on0058.outbound.protection.outlook.com [104.47.42.58]) by dpdk.org (Postfix) with ESMTP id EF64598 for ; Tue, 21 Feb 2017 15:47:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmonicinc.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=9DjOB/fbGl7/iY1J9bibK/KGtax1CBv/VGOB8utohms=; b=P4COBiWEIV8YCdSN8xSrpjjtNnYNBBKAo89ZEI9RxNvqm4Oj0HA6rKwBUXUUsWd+IVdUbYsIuojpeJvmaVWG6D3dyv4GUKpfNmZi40KhcN4cwbiK6mANV/7i30qMWQf3H75fwnK+wigrm9eWrGQ2VfR8HC/0Fds3fQUIIxdaqHo= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Vladyslav.Buslov@harmonicinc.com; Received: from kms.harmonicinc.com (95.67.66.62) by CY4PR11MB1352.namprd11.prod.outlook.com (10.173.16.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.919.13; Tue, 21 Feb 2017 14:47:16 +0000 From: Vladyslav Buslov To: CC: Date: Tue, 21 Feb 2017 16:46:39 +0200 Message-ID: <1487688399-9552-1-git-send-email-vladyslav.buslov@harmonicinc.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1487524499-9570-1-git-send-email-vladyslav.buslov@harmonicinc.com> References: <1487524499-9570-1-git-send-email-vladyslav.buslov@harmonicinc.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [95.67.66.62] X-ClientProxiedBy: AM4PR0701CA0033.eurprd07.prod.outlook.com (10.165.102.43) To CY4PR11MB1352.namprd11.prod.outlook.com (10.173.16.146) X-MS-Office365-Filtering-Correlation-Id: d6579672-6aa5-403f-c99f-08d45a688853 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:CY4PR11MB1352; X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1352; 3:oqyP1HGuaSsEIu+72hmT1eJ36Q2L74G08z4sDkSISpqf793vhw7zvV1XeidKvCbv8tlRR3axbXDJk/MC1bDtxWmhn2TDBPPxv2jkkBjbdGcQOov1rPrOuam93HixSLJVPwU1jbt3wLAqYKTgUKpcqmcmlIsfc64KCVcfZh3C03jGYxKv49oWlmZcHxGBXlIAel/Yse2jTCUEgYlFvHDc86Su3cwRDC0wF3PZEhsDsmvCseFpmeZhKc4YIvPz+B/xXoKrmim6OK8MxdL7DkwIfk0fpsIwUXMOSQ0eTu7s1jY=; 25:+YIMestyB1JxhFmroH7V+R5MGPga1geq1DAkYAuPE0pDGKUNMgU9pXqFuscp+Q9JgbbcVx/YK8l0BejmBrTybEMnHAM69v0KjwkVIlN5bM3NedGqBMegPKq+Vcs7Sj7xPErlXfEDc/lVg8GDMRxxP7JQPH80Prr+W1qAZF3KmExmndmGDMQrTXLb805AJFIy3XGjkAWAsZE02IHA654+hM2i25hrkPVIOP17TDOTbyXejrNnhZHhmQPfdD3QjZP64JpWnYx/vaB6EKwdsG79ZQeDe5oJUOjpJ5JEI3JzGcYM+fzUQQ75XvGNqb5J/qxPQ14XQz3lhPsM1yKTZfqIiSaZdMpaFg32DMCitlnGiiG+EMWoS0KpW1Oea8ZacwqzBkOIFlUJnNH9wfff+BpGP/WstYZ2rm7SfuahBGRO8jatkULIZii1B/n/fTgNS3/sqreBulkEqfAHoMtqtIRVdw== X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1352; 31:32ZqXD0hGcbIlskQUYvhermg3lRU6gruvX1chw9l8JwNL7pT90RL/UDHUrTfWKFs8Gh1W3Cac+KQ87JRizafMZ4OicAfxuazpxZPTRMz7ubh6HrGPP+v2a7r8vMXlPnLh9QmdzStXSmWogNKqIwjFSPnujjiT2iCcT9eCDJai/eZRchWEgblS6TffYdFV3CFnx2laqZsuAIH/D3aqjIYtGke0sagVLqlmVAxkEm5peTHnF+zTBHcrgFBXwu/ufE4RxaCOuiaEUQb7cs0EmpuCw==; 20:LnXfep2uTbWwqXaMbRv5yHFa4g8HSw18VTuPxdiTfZpsp1Y0u0bYlIFAAYoHmxfCCYq3d1FeMqhAY95/mtqLmyXEYX53pZ/rCGFpEh0Zh0ttr38IqiEPTkGWIacvaV8qWoEIz3L2pQqMLaQvj4DT0qj9hxnm4Qizc4vOgJlO5Olan1SB7vZj7rilKu9hxpDONAB9nqKrMAb03Ja2cG5ERSjcw5ZkOPW8kBa8UMklRHq/qTS1m6Wq+IiM7ApJomxM/oMkhsMA1zSCsvDcSwHDoDGYJECJapVEOmzyVCG05+7fODY3IFWzp5iuYXYeKerqnTU78QDOIhGvB4C/YbECBbOhDLhsK/6RPF5XLnZcaGynZ1IlUhVksv5GsxUEWBM7P45tAD6pVmQRKYsSmVa/C7jxAqRE+bePXFQf8BGhjB2OlbzGIhy3GY9LL8Clwb9wfYhrzXDbkQlDCMBp7CH0DQziKC1ZTmQx3w5VckzvKlWkEiTeaiMpEgRsCUc7YEDV X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026)(6041248)(20161123555025)(20161123564025)(20161123562025)(20161123560025)(20161123558025)(6072148); SRVR:CY4PR11MB1352; BCL:0; PCL:0; RULEID:; SRVR:CY4PR11MB1352; X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1352; 4:6yY/N3wHMOddMPNmVBL7TERL1/RljynYJvC8nYtL1GEtrfedXHj+27ctFR/Z3WAoWLN8sotSZ89JWgqW6Prsw2QsIwIXZj3B5E8OnNyZ131lJZugGpgiBy3TFXixJ1di2+iTgM17m3S3hUW/zF9JwUrcPIl1AMLngV8w4NSE8DEbOVR85T+jWS2oQgY0bipcKNlCqdQ9TSEwYkER2J+sVwb+T4C93vHlS8AYchM0RYioFAWERMScBxFvyPMEd5ziRetm4p/R9jhXXd+b8XAKoNDXIk4LA5amFIJv1Y9IPdA1dHzJUqYEOugtBl/cuCf6y0SKHOSlddXM47k4C01n9YnWeS2KjIiTqi6M9mp5HmebdZOjFQ/X4D0mRuteS4l+FC0yaO7jwCk+8AYD/6eA/m5fdEIbrRpKe3wqb3fiHRDpyA+jfKqJoiNnrDOrqXqyE7GwJ2RkPt6IZ0DePzhH8hrYnsFppogDHKPe9HnWG/+SUI9+4/z8b/J/s33gtb5CRMMP32IbCEI7w6I+dnk7sbsZuf7rtxRHRIDj2YZXTwVFYp9IsVtXctAhzWG+uwUnGUtNLYzFOsOj+uMXya3iCIZ9xneZe4wNRfLiw3ZVm5Yjd1cpxv1wsU02DqQPAquCeLFFB//SpDH4E0XfNj70DzDPnxOClxxNjLs+G0bporE= X-Forefront-PRVS: 0225B0D5BC X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39860400002)(39410400002)(39850400002)(39450400003)(39840400002)(189002)(199003)(2906002)(6116002)(76176999)(50986999)(53936002)(2950100002)(6666003)(66066001)(6916009)(3846002)(38730400002)(97736004)(50226002)(36756003)(110136004)(189998001)(106356001)(105586002)(33646002)(42186005)(305945005)(69596002)(53416004)(2351001)(50466002)(47776003)(6486002)(101416001)(48376002)(68736007)(5660300001)(25786008)(92566002)(4326007)(53946003)(81156014)(81166006)(7736002)(8676002)(86362001)(575784001)(5003940100001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR11MB1352; H:kms.harmonicinc.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: harmonicinc.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR11MB1352; 23:3oIUfDazphCd2Oxvcybk5ZiWeS02pe4IUKd0w4RNE?= =?us-ascii?Q?2QgaJzUS1TsoTtKl5yd48MIoL2JHjI08R8oQolVd3Vtag2bf8y4JLgRIxXyE?= =?us-ascii?Q?XUBxbS0UvINdC8lCaRTBJkp0XKMLWTEZ8snObMHH0/gOCfxO7pW35oFc3wUW?= =?us-ascii?Q?oz5cVQ85xBHsyaYYg9TMgqipvJhV2MdwMIvkFf0nYRNNIEL+a9dwJQgV/7cr?= =?us-ascii?Q?Em3qrSksqZif2eEnzC8oUjhhDSvZ7p2VDQFzvn+QihFdV9V8P8xB0daKAWdW?= =?us-ascii?Q?CB+bJ/a8EJx3Ad4DzQIRfkWgDfV90nUyRr+mG3MjcN55RNaYTvWEqnXrXuPv?= =?us-ascii?Q?w8YZ0J77ITHqpVsVTf5oyU38mPoSXHbhdKR7LCQJFdZw2Z1DZikVhtw3fvCO?= =?us-ascii?Q?/8x+lQX2cWLrK0xNROEZMW1xJhPati/A8xm4bVRs50WYqF3i7DrwhVRhl88S?= =?us-ascii?Q?HTRtWEf1+GOhm/K323qiCPgCc+gR3SPb/LHqoDw+XV83m4v9j7zI91OfuksN?= =?us-ascii?Q?KoUKPktFxDy7/1GVZwPezFQAVv822yI980RbArPwbNPq+XCWnOne+WulVDOu?= =?us-ascii?Q?fQfvfS6xI47ZHCOgwJHdgdc/mzJ+gUHZp2Vfeb+vXBC4EX+yu7uWI/0FApnf?= =?us-ascii?Q?NFxU1ZCZ8m+E+OfoHCcwgLwdE3+dls8WkXk73N8Uj/fKUBcByY0fKgTaJl5f?= =?us-ascii?Q?bDUKXYnNrEU3eXG+uNq6Sv1SeWx7tIJSMQJP+icvA/N76fRYF18yhdz7TGK3?= =?us-ascii?Q?SK+TsCmW1g8fhyBbdbvjW2yltuRmsVHYtnNCHcCK/O6DwU2rikWNbs2WSEbO?= =?us-ascii?Q?vhAufoqRYpr4cS7a8AdsZMU8i/eHghDGwKaUXNRQbu6VI3xseAeADBqF8x54?= =?us-ascii?Q?Ko3b+uoKLYRg1Q4brxCOlnksitfL7qKgMuVr5FbnkF8HXVZ+DR8UZdrtKMKM?= =?us-ascii?Q?J+o49Fo85XfmGeyUBk0dmEVjWAxUWbkJY4RNCQ9fifRDAPKKmpsnbm+kYm/n?= =?us-ascii?Q?+gnOXPHZc5553X8zcf9y9SEEE0ZBNM7IXgP0YCq/LdpsZ/AeQd4HyBrlFuWQ?= =?us-ascii?Q?CXAvxpLnFmBrHSIFxsyL/ssmgGcu6XGd3+URr70n6BhdIdSJG5y9emZHWL9r?= =?us-ascii?Q?/m0rl8BpGkJq0qVR3DP8a6kXiWjvcNjlfcVbkP5KJY+3Qmc8ZmdczL8NvaGo?= =?us-ascii?Q?BIW6PTIKxbWvvzDimtTvG9Xu5w5gi/DQk3OLJt7mVNMjhLDYmPfmaE+DuiMT?= =?us-ascii?Q?69jxjfB19GN+iBcO0Xhmri5JYmvON5ApVjyoLBS?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1352; 6:cenNROWw1vYp5cXJfuOtTG65dLkN04LjgZDKUyqXGJc8g+mDyMrpZW3gSBY45ZJHuiXK0yWhC8Qf5EhItkXfelZw2x1EBL3dIuozTFfUNKbN1Sffe4QmfZOmPSyIdx78I6xCO7aVLuMvwRUkp2vACG/cjykpfqGfGauStmapkJi/Ejg/golEUQrkQ+JCWMHee5NZx/zgpAkIsPHjvXg7f2gUDRKq9QTPBp51LE1ZDMxsHNRMwpCF5PtIAdfbzmTs4x/VvJ42pT6L/4sr14kL7BivsEfFsTXfUhrY3QcA7wNgwDHzl8Z8ypLOf+7nbxuJwxnGRgA2M+cLeXgzTpBXHukfoQuaEhVGlqD6UV0/vVIbgNYH6XQLfpkNL5nvgGg4Xj2ajbf8K1wVBYS/9JKc85TQYBBfkbSE9XVCrpkX+Jg=; 5:1T8cT/z7QnRKvVxiwuHUwJIFH3MFkyRy3ceNKCmHficYovdp9Qn7IHFJRChnp0i5+Ca+idTTUQ3aCpuBBlAvhU+mMO+BSq06WLev/PwaDPAuQE/rggnvJwuG3igpGKE1LWU1HUSYyLBNVIkcNfcDlw==; 24:LhMs/LRgryMWPu6C5xYLj/xtiUJ183TaDOgmKKbyDcrvYnA16AJudoVWlLNUhHItOeFyd8Ow4iWyV19D+6ETfwR/bo8umwfU9bZOhbpEOGg= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR11MB1352; 7:0UvnHpV3/YtNFp9U4PszDJ/ikN3jKbq496rTBZEhdyNf8GJKXjSsmOO8UumYernXge4rRrM8mjmn+zqY99JfoVt81OOseaBxNTiFRcrpxkH6YQ+N5lWzysjDwcE7m5NwQfCOjsJfI1Ev9au1JgJV6CnMGSLgtMRVct5O2O+J2uI6swX5zH1/NwJtiZEqB01zjm0jkLkLwuaH5L7sQpJ84Uko1FxjjWv9xgHfcCbjK6wGNd7ohIE3PP/UAtipyYPPIP7novUxKGj2/qIrMLEKtTZ7RrugRI0yvpt+EXFE2joB5UYtwBF9yzbVUZMWUeYASaKs/8+vcYgL5+hJmugCnA==; 20:5B/mYZrPJEqnO3sdyAwtYjV0+Fa0R4nBvWq6b96Irm8iRDgxSJPESrPrAdrC1zA04kHwufeHPEHjoYiVqFiuCZ+4kug+ryWbuVimp8L4RwQmPQ4xOitxFmdfd5hD11oyFi6NtFqTVkkDCqjf3SceSq3kP7GfyZ4SHmR23Xvk1r4= X-OriginatorOrg: harmonicinc.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Feb 2017 14:47:16.7716 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1352 Subject: [dpdk-dev] [PATCH v2] lpm: extend IPv6 next hop field 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: , X-List-Received-Date: Tue, 21 Feb 2017 14:47:21 -0000 This patch extend next_hop field from 8-bits to 21-bits in LPM library for IPv6. Added versioning symbols to functions and updated library and applications that have a dependency on LPM library. Signed-off-by: Vladyslav Buslov --- app/test/test_lpm6.c | 115 ++++++++++++++------ app/test/test_lpm6_perf.c | 4 +- doc/guides/prog_guide/lpm6_lib.rst | 2 +- doc/guides/rel_notes/release_17_05.rst | 5 + examples/ip_fragmentation/main.c | 17 +-- examples/ip_reassembly/main.c | 17 +-- examples/ipsec-secgw/ipsec-secgw.c | 2 +- examples/l3fwd/l3fwd_lpm_sse.h | 24 ++--- examples/performance-thread/l3fwd-thread/main.c | 11 +- lib/librte_lpm/rte_lpm6.c | 134 +++++++++++++++++++++--- lib/librte_lpm/rte_lpm6.h | 32 +++++- lib/librte_lpm/rte_lpm_version.map | 10 ++ lib/librte_table/rte_table_lpm_ipv6.c | 9 +- 13 files changed, 292 insertions(+), 90 deletions(-) diff --git a/app/test/test_lpm6.c b/app/test/test_lpm6.c index 61134f7..e0e7bf0 100644 --- a/app/test/test_lpm6.c +++ b/app/test/test_lpm6.c @@ -79,6 +79,7 @@ static int32_t test24(void); static int32_t test25(void); static int32_t test26(void); static int32_t test27(void); +static int32_t test28(void); rte_lpm6_test tests6[] = { /* Test Cases */ @@ -110,6 +111,7 @@ rte_lpm6_test tests6[] = { test25, test26, test27, + test28, }; #define NUM_LPM6_TESTS (sizeof(tests6)/sizeof(tests6[0])) @@ -354,7 +356,7 @@ test6(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t next_hop_return = 0; + uint32_t next_hop_return = 0; int32_t status = 0; config.max_rules = MAX_RULES; @@ -392,7 +394,7 @@ test7(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[10][16]; - int16_t next_hop_return[10]; + int32_t next_hop_return[10]; int32_t status = 0; config.max_rules = MAX_RULES; @@ -469,7 +471,8 @@ test9(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 16, next_hop_add = 100, next_hop_return = 0; + uint8_t depth = 16; + uint32_t next_hop_add = 100, next_hop_return = 0; int32_t status = 0; uint8_t i; @@ -513,7 +516,8 @@ test10(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; + uint8_t depth; + uint32_t next_hop_add = 100; int32_t status = 0; int i; @@ -557,7 +561,8 @@ test11(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; + uint8_t depth; + uint32_t next_hop_add = 100; int32_t status = 0; config.max_rules = MAX_RULES; @@ -617,7 +622,8 @@ test12(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; + uint8_t depth; + uint32_t next_hop_add = 100; int32_t status = 0; config.max_rules = MAX_RULES; @@ -655,7 +661,8 @@ test13(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add = 100; + uint8_t depth; + uint32_t next_hop_add = 100; int32_t status = 0; config.max_rules = 2; @@ -702,7 +709,8 @@ test14(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 25, next_hop_add = 100; + uint8_t depth = 25; + uint32_t next_hop_add = 100; int32_t status = 0; int i; @@ -748,7 +756,8 @@ test15(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0; + uint8_t depth = 24; + uint32_t next_hop_add = 100, next_hop_return = 0; int32_t status = 0; config.max_rules = MAX_RULES; @@ -784,7 +793,8 @@ test16(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth = 128, next_hop_add = 100, next_hop_return = 0; + uint8_t depth = 128; + uint32_t next_hop_add = 100, next_hop_return = 0; int32_t status = 0; config.max_rules = MAX_RULES; @@ -828,7 +838,8 @@ test17(void) uint8_t ip1[] = {127,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255}; uint8_t ip2[] = {128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint8_t depth, next_hop_add, next_hop_return; + uint8_t depth; + uint32_t next_hop_add, next_hop_return; int32_t status = 0; config.max_rules = MAX_RULES; @@ -857,7 +868,7 @@ test17(void) /* Loop with rte_lpm6_delete. */ for (depth = 16; depth >= 1; depth--) { - next_hop_add = (uint8_t) (depth - 1); + next_hop_add = (depth - 1); status = rte_lpm6_delete(lpm, ip2, depth); TEST_LPM_ASSERT(status == 0); @@ -893,8 +904,9 @@ test18(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[16], ip_1[16], ip_2[16]; - uint8_t depth, depth_1, depth_2, next_hop_add, next_hop_add_1, - next_hop_add_2, next_hop_return; + uint8_t depth, depth_1, depth_2; + uint32_t next_hop_add, next_hop_add_1, + next_hop_add_2, next_hop_return; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1055,7 +1067,8 @@ test19(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; + uint8_t depth; + uint32_t next_hop_add, next_hop_return; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1253,7 +1266,8 @@ test20(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; + uint8_t depth; + uint32_t next_hop_add, next_hop_return; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1320,8 +1334,9 @@ test21(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip_batch[4][16]; - uint8_t depth, next_hop_add; - int16_t next_hop_return[4]; + uint8_t depth; + uint32_t next_hop_add; + int32_t next_hop_return[4]; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1378,8 +1393,9 @@ test22(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip_batch[5][16]; - uint8_t depth[5], next_hop_add; - int16_t next_hop_return[5]; + uint8_t depth[5]; + uint32_t next_hop_add; + int32_t next_hop_return[5]; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1495,7 +1511,8 @@ test23(void) struct rte_lpm6_config config; uint32_t i; uint8_t ip[16]; - uint8_t depth, next_hop_add, next_hop_return; + uint8_t depth; + uint32_t next_hop_add, next_hop_return; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1579,7 +1596,8 @@ test25(void) struct rte_lpm6_config config; uint8_t ip[16]; uint32_t i; - uint8_t depth, next_hop_add, next_hop_return, next_hop_expected; + uint8_t depth; + uint32_t next_hop_add, next_hop_return, next_hop_expected; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1632,10 +1650,10 @@ test26(void) uint8_t d_ip_10_32 = 32; uint8_t d_ip_10_24 = 24; uint8_t d_ip_20_25 = 25; - uint8_t next_hop_ip_10_32 = 100; - uint8_t next_hop_ip_10_24 = 105; - uint8_t next_hop_ip_20_25 = 111; - uint8_t next_hop_return = 0; + uint32_t next_hop_ip_10_32 = 100; + uint32_t next_hop_ip_10_24 = 105; + uint32_t next_hop_ip_20_25 = 111; + uint32_t next_hop_return = 0; int32_t status = 0; config.max_rules = MAX_RULES; @@ -1650,7 +1668,7 @@ test26(void) return -1; status = rte_lpm6_lookup(lpm, ip_10_32, &next_hop_return); - uint8_t test_hop_10_32 = next_hop_return; + uint32_t test_hop_10_32 = next_hop_return; TEST_LPM_ASSERT(status == 0); TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_32); @@ -1659,7 +1677,7 @@ test26(void) return -1; status = rte_lpm6_lookup(lpm, ip_10_24, &next_hop_return); - uint8_t test_hop_10_24 = next_hop_return; + uint32_t test_hop_10_24 = next_hop_return; TEST_LPM_ASSERT(status == 0); TEST_LPM_ASSERT(next_hop_return == next_hop_ip_10_24); @@ -1668,7 +1686,7 @@ test26(void) return -1; status = rte_lpm6_lookup(lpm, ip_20_25, &next_hop_return); - uint8_t test_hop_20_25 = next_hop_return; + uint32_t test_hop_20_25 = next_hop_return; TEST_LPM_ASSERT(status == 0); TEST_LPM_ASSERT(next_hop_return == next_hop_ip_20_25); @@ -1707,7 +1725,8 @@ test27(void) struct rte_lpm6 *lpm = NULL; struct rte_lpm6_config config; uint8_t ip[] = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,0}; - uint8_t depth = 128, next_hop_add = 100, next_hop_return; + uint8_t depth = 128; + uint32_t next_hop_add = 100, next_hop_return; int32_t status = 0; int i, j; @@ -1746,6 +1765,42 @@ test27(void) } /* + * Call add, lookup and delete for a single rule with maximum 21bit next_hop + * size. + * Check that next_hop returned from lookup is equal to provisioned value. + * Delete the rule and check that the same test returs a miss. + */ +int32_t +test28(void) +{ + struct rte_lpm6 *lpm = NULL; + struct rte_lpm6_config config; + uint8_t ip[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t depth = 16; + uint32_t next_hop_add = 0x001FFFFF, next_hop_return = 0; + int32_t status = 0; + + config.max_rules = MAX_RULES; + config.number_tbl8s = NUMBER_TBL8S; + config.flags = 0; + + lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + status = rte_lpm6_add(lpm, ip, depth, next_hop_add); + TEST_LPM_ASSERT(status == 0); + + status = rte_lpm6_lookup(lpm, ip, &next_hop_return); + TEST_LPM_ASSERT((status == 0) && (next_hop_return == next_hop_add)); + + status = rte_lpm6_delete(lpm, ip, depth); + TEST_LPM_ASSERT(status == 0); + rte_lpm6_free(lpm); + + return PASS; +} + +/* * Do all unit tests. */ static int diff --git a/app/test/test_lpm6_perf.c b/app/test/test_lpm6_perf.c index 0723081..30be430 100644 --- a/app/test/test_lpm6_perf.c +++ b/app/test/test_lpm6_perf.c @@ -86,7 +86,7 @@ test_lpm6_perf(void) struct rte_lpm6_config config; uint64_t begin, total_time; unsigned i, j; - uint8_t next_hop_add = 0xAA, next_hop_return = 0; + uint32_t next_hop_add = 0xAA, next_hop_return = 0; int status = 0; int64_t count = 0; @@ -148,7 +148,7 @@ test_lpm6_perf(void) count = 0; uint8_t ip_batch[NUM_IPS_ENTRIES][16]; - int16_t next_hops[NUM_IPS_ENTRIES]; + int32_t next_hops[NUM_IPS_ENTRIES]; for (i = 0; i < NUM_IPS_ENTRIES; i++) memcpy(ip_batch[i], large_ips_table[i].ip, 16); diff --git a/doc/guides/prog_guide/lpm6_lib.rst b/doc/guides/prog_guide/lpm6_lib.rst index 0aea5c5..f791507 100644 --- a/doc/guides/prog_guide/lpm6_lib.rst +++ b/doc/guides/prog_guide/lpm6_lib.rst @@ -53,7 +53,7 @@ several thousand IPv6 rules, but the number can vary depending on the case. An LPM prefix is represented by a pair of parameters (128-bit key, depth), with depth in the range of 1 to 128. An LPM rule is represented by an LPM prefix and some user data associated with the prefix. The prefix serves as the unique identifier for the LPM rule. -In this implementation, the user data is 1-byte long and is called "next hop", +In this implementation, the user data is 21-bits long and is called "next hop", which corresponds to its main use of storing the ID of the next hop in a routing table entry. The main methods exported for the LPM component are: diff --git a/doc/guides/rel_notes/release_17_05.rst b/doc/guides/rel_notes/release_17_05.rst index 48fb5bd..723e085 100644 --- a/doc/guides/rel_notes/release_17_05.rst +++ b/doc/guides/rel_notes/release_17_05.rst @@ -41,6 +41,9 @@ New Features Also, make sure to start the actual text at the margin. ========================================================= +* **Increased number of next hops for LPM IPv6 to 2^21.** + + The next_hop field is extended from 8 bits to 21 bits for IPv6. Resolved Issues --------------- @@ -110,6 +113,8 @@ API Changes Also, make sure to start the actual text at the margin. ========================================================= +* The LPM ``next_hop`` field is extended from 8 bits to 21 bits for IPv6 + while keeping ABI compatibility. ABI Changes ----------- diff --git a/examples/ip_fragmentation/main.c b/examples/ip_fragmentation/main.c index e1e32c6..89d08c8 100644 --- a/examples/ip_fragmentation/main.c +++ b/examples/ip_fragmentation/main.c @@ -265,8 +265,8 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf, uint8_t queueid, uint8_t port_in) { struct rx_queue *rxq; - uint32_t i, len, next_hop_ipv4; - uint8_t next_hop_ipv6, port_out, ipv6; + uint32_t i, len, next_hop; + uint8_t port_out, ipv6; int32_t len2; ipv6 = 0; @@ -290,9 +290,9 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf, ip_dst = rte_be_to_cpu_32(ip_hdr->dst_addr); /* Find destination port */ - if (rte_lpm_lookup(rxq->lpm, ip_dst, &next_hop_ipv4) == 0 && - (enabled_port_mask & 1 << next_hop_ipv4) != 0) { - port_out = next_hop_ipv4; + if (rte_lpm_lookup(rxq->lpm, ip_dst, &next_hop) == 0 && + (enabled_port_mask & 1 << next_hop) != 0) { + port_out = next_hop; /* Build transmission burst for new port */ len = qconf->tx_mbufs[port_out].len; @@ -326,9 +326,10 @@ l3fwd_simple_forward(struct rte_mbuf *m, struct lcore_queue_conf *qconf, ip_hdr = rte_pktmbuf_mtod(m, struct ipv6_hdr *); /* Find destination port */ - if (rte_lpm6_lookup(rxq->lpm6, ip_hdr->dst_addr, &next_hop_ipv6) == 0 && - (enabled_port_mask & 1 << next_hop_ipv6) != 0) { - port_out = next_hop_ipv6; + if (rte_lpm6_lookup(rxq->lpm6, ip_hdr->dst_addr, + &next_hop) == 0 && + (enabled_port_mask & 1 << next_hop) != 0) { + port_out = next_hop; /* Build transmission burst for new port */ len = qconf->tx_mbufs[port_out].len; diff --git a/examples/ip_reassembly/main.c b/examples/ip_reassembly/main.c index 50fe422..661b64f 100644 --- a/examples/ip_reassembly/main.c +++ b/examples/ip_reassembly/main.c @@ -346,8 +346,8 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue, struct rte_ip_frag_death_row *dr; struct rx_queue *rxq; void *d_addr_bytes; - uint32_t next_hop_ipv4; - uint8_t next_hop_ipv6, dst_port; + uint32_t next_hop; + uint8_t dst_port; rxq = &qconf->rx_queue_list[queue]; @@ -390,9 +390,9 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue, ip_dst = rte_be_to_cpu_32(ip_hdr->dst_addr); /* Find destination port */ - if (rte_lpm_lookup(rxq->lpm, ip_dst, &next_hop_ipv4) == 0 && - (enabled_port_mask & 1 << next_hop_ipv4) != 0) { - dst_port = next_hop_ipv4; + if (rte_lpm_lookup(rxq->lpm, ip_dst, &next_hop) == 0 && + (enabled_port_mask & 1 << next_hop) != 0) { + dst_port = next_hop; } eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv4); @@ -427,9 +427,10 @@ reassemble(struct rte_mbuf *m, uint8_t portid, uint32_t queue, } /* Find destination port */ - if (rte_lpm6_lookup(rxq->lpm6, ip_hdr->dst_addr, &next_hop_ipv6) == 0 && - (enabled_port_mask & 1 << next_hop_ipv6) != 0) { - dst_port = next_hop_ipv6; + if (rte_lpm6_lookup(rxq->lpm6, ip_hdr->dst_addr, + &next_hop) == 0 && + (enabled_port_mask & 1 << next_hop) != 0) { + dst_port = next_hop; } eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv6); diff --git a/examples/ipsec-secgw/ipsec-secgw.c b/examples/ipsec-secgw/ipsec-secgw.c index 5a4c9b7..5744c46 100644 --- a/examples/ipsec-secgw/ipsec-secgw.c +++ b/examples/ipsec-secgw/ipsec-secgw.c @@ -618,7 +618,7 @@ route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) static inline void route6_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[], uint8_t nb_pkts) { - int16_t hop[MAX_PKT_BURST * 2]; + int32_t hop[MAX_PKT_BURST * 2]; uint8_t dst_ip[MAX_PKT_BURST * 2][16]; uint8_t *ip6_dst; uint16_t i, offset; diff --git a/examples/l3fwd/l3fwd_lpm_sse.h b/examples/l3fwd/l3fwd_lpm_sse.h index 538fe3d..aa06b6d 100644 --- a/examples/l3fwd/l3fwd_lpm_sse.h +++ b/examples/l3fwd/l3fwd_lpm_sse.h @@ -40,8 +40,7 @@ static inline __attribute__((always_inline)) uint16_t lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt, uint8_t portid) { - uint32_t next_hop_ipv4; - uint8_t next_hop_ipv6; + uint32_t next_hop; struct ipv6_hdr *ipv6_hdr; struct ipv4_hdr *ipv4_hdr; struct ether_hdr *eth_hdr; @@ -51,9 +50,11 @@ lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt, eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1); - return (uint16_t) ((rte_lpm_lookup(qconf->ipv4_lookup_struct, - rte_be_to_cpu_32(ipv4_hdr->dst_addr), &next_hop_ipv4) == 0) ? - next_hop_ipv4 : portid); + return (uint16_t) ( + (rte_lpm_lookup(qconf->ipv4_lookup_struct, + rte_be_to_cpu_32(ipv4_hdr->dst_addr), + &next_hop) == 0) ? + next_hop : portid); } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) { @@ -61,8 +62,8 @@ lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt, ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1); return (uint16_t) ((rte_lpm6_lookup(qconf->ipv6_lookup_struct, - ipv6_hdr->dst_addr, &next_hop_ipv6) == 0) - ? next_hop_ipv6 : portid); + ipv6_hdr->dst_addr, &next_hop) == 0) + ? next_hop : portid); } @@ -78,14 +79,13 @@ static inline __attribute__((always_inline)) uint16_t lpm_get_dst_port_with_ipv4(const struct lcore_conf *qconf, struct rte_mbuf *pkt, uint32_t dst_ipv4, uint8_t portid) { - uint32_t next_hop_ipv4; - uint8_t next_hop_ipv6; + uint32_t next_hop; struct ipv6_hdr *ipv6_hdr; struct ether_hdr *eth_hdr; if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) { return (uint16_t) ((rte_lpm_lookup(qconf->ipv4_lookup_struct, dst_ipv4, - &next_hop_ipv4) == 0) ? next_hop_ipv4 : portid); + &next_hop) == 0) ? next_hop : portid); } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) { @@ -93,8 +93,8 @@ lpm_get_dst_port_with_ipv4(const struct lcore_conf *qconf, struct rte_mbuf *pkt, ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1); return (uint16_t) ((rte_lpm6_lookup(qconf->ipv6_lookup_struct, - ipv6_hdr->dst_addr, &next_hop_ipv6) == 0) - ? next_hop_ipv6 : portid); + ipv6_hdr->dst_addr, &next_hop) == 0) + ? next_hop : portid); } diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c index 53083df..fa99daf 100644 --- a/examples/performance-thread/l3fwd-thread/main.c +++ b/examples/performance-thread/l3fwd-thread/main.c @@ -909,7 +909,7 @@ static inline uint8_t get_ipv6_dst_port(void *ipv6_hdr, uint8_t portid, lookup6_struct_t *ipv6_l3fwd_lookup_struct) { - uint8_t next_hop; + uint32_t next_hop; return (uint8_t) ((rte_lpm6_lookup(ipv6_l3fwd_lookup_struct, ((struct ipv6_hdr *)ipv6_hdr)->dst_addr, &next_hop) == 0) ? @@ -1396,15 +1396,14 @@ rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype) static inline __attribute__((always_inline)) uint16_t get_dst_port(struct rte_mbuf *pkt, uint32_t dst_ipv4, uint8_t portid) { - uint32_t next_hop_ipv4; - uint8_t next_hop_ipv6; + uint32_t next_hop; struct ipv6_hdr *ipv6_hdr; struct ether_hdr *eth_hdr; if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) { return (uint16_t) ((rte_lpm_lookup( RTE_PER_LCORE(lcore_conf)->ipv4_lookup_struct, dst_ipv4, - &next_hop_ipv4) == 0) ? next_hop_ipv4 : portid); + &next_hop) == 0) ? next_hop : portid); } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) { @@ -1413,8 +1412,8 @@ get_dst_port(struct rte_mbuf *pkt, uint32_t dst_ipv4, uint8_t portid) return (uint16_t) ((rte_lpm6_lookup( RTE_PER_LCORE(lcore_conf)->ipv6_lookup_struct, - ipv6_hdr->dst_addr, &next_hop_ipv6) == 0) ? next_hop_ipv6 : - portid); + ipv6_hdr->dst_addr, &next_hop) == 0) ? + next_hop : portid); } diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c index 32fdba0..9cc7be7 100644 --- a/lib/librte_lpm/rte_lpm6.c +++ b/lib/librte_lpm/rte_lpm6.c @@ -97,7 +97,7 @@ struct rte_lpm6_tbl_entry { /** Rules tbl entry structure. */ struct rte_lpm6_rule { uint8_t ip[RTE_LPM6_IPV6_ADDR_SIZE]; /**< Rule IP address. */ - uint8_t next_hop; /**< Rule next hop. */ + uint32_t next_hop; /**< Rule next hop. */ uint8_t depth; /**< Rule depth. */ }; @@ -297,7 +297,7 @@ rte_lpm6_free(struct rte_lpm6 *lpm) * the nexthop if so. Otherwise it adds a new rule if enough space is available. */ static inline int32_t -rule_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t next_hop, uint8_t depth) +rule_add(struct rte_lpm6 *lpm, uint8_t *ip, uint32_t next_hop, uint8_t depth) { uint32_t rule_index; @@ -340,7 +340,7 @@ rule_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t next_hop, uint8_t depth) */ static void expand_rule(struct rte_lpm6 *lpm, uint32_t tbl8_gindex, uint8_t depth, - uint8_t next_hop) + uint32_t next_hop) { uint32_t tbl8_group_end, tbl8_gindex_next, j; @@ -377,7 +377,7 @@ expand_rule(struct rte_lpm6 *lpm, uint32_t tbl8_gindex, uint8_t depth, static inline int add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, struct rte_lpm6_tbl_entry **tbl_next, uint8_t *ip, uint8_t bytes, - uint8_t first_byte, uint8_t depth, uint8_t next_hop) + uint8_t first_byte, uint8_t depth, uint32_t next_hop) { uint32_t tbl_index, tbl_range, tbl8_group_start, tbl8_group_end, i; int32_t tbl8_gindex; @@ -507,9 +507,17 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl, * Add a route */ int -rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, +rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, uint8_t next_hop) { + return rte_lpm6_add_v1705(lpm, ip, depth, next_hop); +} +VERSION_SYMBOL(rte_lpm6_add, _v20, 2.0); + +int +rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint32_t next_hop) +{ struct rte_lpm6_tbl_entry *tbl; struct rte_lpm6_tbl_entry *tbl_next; int32_t rule_index; @@ -560,6 +568,10 @@ rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, return status; } +BIND_DEFAULT_SYMBOL(rte_lpm6_add, _v1705, 17.05); +MAP_STATIC_SYMBOL(int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, + uint8_t depth, uint32_t next_hop), + rte_lpm6_add_v1705); /* * Takes a pointer to a table entry and inspect one level. @@ -569,7 +581,7 @@ rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, static inline int lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl, const struct rte_lpm6_tbl_entry **tbl_next, uint8_t *ip, - uint8_t first_byte, uint8_t *next_hop) + uint8_t first_byte, uint32_t *next_hop) { uint32_t tbl8_index, tbl_entry; @@ -589,7 +601,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl, return 1; } else { /* If not extended then we can have a match. */ - *next_hop = (uint8_t)tbl_entry; + *next_hop = ((uint32_t)tbl_entry & RTE_LPM6_TBL8_BITMASK); return (tbl_entry & RTE_LPM6_LOOKUP_SUCCESS) ? 0 : -ENOENT; } } @@ -598,7 +610,26 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl, * Looks up an IP */ int -rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop) +rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop) +{ + uint32_t next_hop32 = 0; + int32_t status; + + /* DEBUG: Check user input arguments. */ + if (next_hop == NULL) + return -EINVAL; + + status = rte_lpm6_lookup_v1705(lpm, ip, &next_hop32); + if (status == 0) + *next_hop = (uint8_t)next_hop32; + + return status; +} +VERSION_SYMBOL(rte_lpm6_lookup, _v20, 2.0); + +int +rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip, + uint32_t *next_hop) { const struct rte_lpm6_tbl_entry *tbl; const struct rte_lpm6_tbl_entry *tbl_next = NULL; @@ -625,20 +656,23 @@ rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop) return status; } +BIND_DEFAULT_SYMBOL(rte_lpm6_lookup, _v1705, 17.05); +MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, + uint32_t *next_hop), rte_lpm6_lookup_v1705); /* * Looks up a group of IP addresses */ int -rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm, +rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm, uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], int16_t * next_hops, unsigned n) { unsigned i; const struct rte_lpm6_tbl_entry *tbl; const struct rte_lpm6_tbl_entry *tbl_next = NULL; - uint32_t tbl24_index; - uint8_t first_byte, next_hop; + uint32_t tbl24_index, next_hop; + uint8_t first_byte; int status; /* DEBUG: Check user input arguments. */ @@ -664,11 +698,59 @@ rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm, if (status < 0) next_hops[i] = -1; else - next_hops[i] = next_hop; + next_hops[i] = (int16_t)next_hop; + } + + return 0; +} +VERSION_SYMBOL(rte_lpm6_lookup_bulk_func, _v20, 2.0); + +int +rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm, + uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], + int32_t *next_hops, unsigned int n) +{ + unsigned int i; + const struct rte_lpm6_tbl_entry *tbl; + const struct rte_lpm6_tbl_entry *tbl_next = NULL; + uint32_t tbl24_index, next_hop; + uint8_t first_byte; + int status; + + /* DEBUG: Check user input arguments. */ + if ((lpm == NULL) || (ips == NULL) || (next_hops == NULL)) + return -EINVAL; + + for (i = 0; i < n; i++) { + first_byte = LOOKUP_FIRST_BYTE; + tbl24_index = (ips[i][0] << BYTES2_SIZE) | + (ips[i][1] << BYTE_SIZE) | ips[i][2]; + + /* Calculate pointer to the first entry to be inspected */ + tbl = &lpm->tbl24[tbl24_index]; + + do { + /* Continue inspecting following levels + * until success or failure + */ + status = lookup_step(lpm, tbl, &tbl_next, ips[i], + first_byte++, &next_hop); + tbl = tbl_next; + } while (status == 1); + + if (status < 0) + next_hops[i] = -1; + else + next_hops[i] = (int32_t)next_hop; } return 0; } +BIND_DEFAULT_SYMBOL(rte_lpm6_lookup_bulk_func, _v1705, 17.05); +MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm, + uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], + int32_t *next_hops, unsigned int n), + rte_lpm6_lookup_bulk_func_v1705); /* * Finds a rule in rule table. @@ -698,8 +780,28 @@ rule_find(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth) * Look for a rule in the high-level rules table */ int -rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, -uint8_t *next_hop) +rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint8_t *next_hop) +{ + uint32_t next_hop32 = 0; + int32_t status; + + /* DEBUG: Check user input arguments. */ + if (next_hop == NULL) + return -EINVAL; + + status = rte_lpm6_is_rule_present_v1705(lpm, ip, depth, &next_hop32); + if (status > 0) + *next_hop = (uint8_t)next_hop32; + + return status; + +} +VERSION_SYMBOL(rte_lpm6_is_rule_present, _v20, 2.0); + +int +rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint32_t *next_hop) { uint8_t ip_masked[RTE_LPM6_IPV6_ADDR_SIZE]; int32_t rule_index; @@ -724,6 +826,10 @@ uint8_t *next_hop) /* If rule is not found return 0. */ return 0; } +BIND_DEFAULT_SYMBOL(rte_lpm6_is_rule_present, _v1705, 17.05); +MAP_STATIC_SYMBOL(int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, + uint8_t *ip, uint8_t depth, uint32_t *next_hop), + rte_lpm6_is_rule_present_v1705); /* * Delete a rule from the rule table. diff --git a/lib/librte_lpm/rte_lpm6.h b/lib/librte_lpm/rte_lpm6.h index 13d027f..3a3342d 100644 --- a/lib/librte_lpm/rte_lpm6.h +++ b/lib/librte_lpm/rte_lpm6.h @@ -39,6 +39,7 @@ */ #include +#include #ifdef __cplusplus extern "C" { @@ -123,7 +124,13 @@ rte_lpm6_free(struct rte_lpm6 *lpm); */ int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint32_t next_hop); +int +rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, uint8_t next_hop); +int +rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint32_t next_hop); /** * Check if a rule is present in the LPM table, @@ -142,7 +149,13 @@ rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, */ int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, -uint8_t *next_hop); + uint32_t *next_hop); +int +rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint8_t *next_hop); +int +rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth, + uint32_t *next_hop); /** * Delete a rule from the LPM table. @@ -199,7 +212,12 @@ rte_lpm6_delete_all(struct rte_lpm6 *lpm); * -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit */ int -rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop); +rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint32_t *next_hop); +int +rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop); +int +rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip, + uint32_t *next_hop); /** * Lookup multiple IP addresses in an LPM table. @@ -220,7 +238,15 @@ rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop); int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm, uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], - int16_t * next_hops, unsigned n); + int32_t *next_hops, unsigned int n); +int +rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm, + uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], + int16_t *next_hops, unsigned int n); +int +rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm, + uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE], + int32_t *next_hops, unsigned int n); #ifdef __cplusplus } diff --git a/lib/librte_lpm/rte_lpm_version.map b/lib/librte_lpm/rte_lpm_version.map index 239b371..90beac8 100644 --- a/lib/librte_lpm/rte_lpm_version.map +++ b/lib/librte_lpm/rte_lpm_version.map @@ -34,3 +34,13 @@ DPDK_16.04 { rte_lpm_delete_all; } DPDK_2.0; + +DPDK_17.05 { + global: + + rte_lpm6_add; + rte_lpm6_is_rule_present; + rte_lpm6_lookup; + rte_lpm6_lookup_bulk_func; + +} DPDK_16.04; diff --git a/lib/librte_table/rte_table_lpm_ipv6.c b/lib/librte_table/rte_table_lpm_ipv6.c index 836f4cf..1e1a173 100644 --- a/lib/librte_table/rte_table_lpm_ipv6.c +++ b/lib/librte_table/rte_table_lpm_ipv6.c @@ -211,9 +211,8 @@ rte_table_lpm_ipv6_entry_add( struct rte_table_lpm_ipv6 *lpm = (struct rte_table_lpm_ipv6 *) table; struct rte_table_lpm_ipv6_key *ip_prefix = (struct rte_table_lpm_ipv6_key *) key; - uint32_t nht_pos, nht_pos0_valid; + uint32_t nht_pos, nht_pos0, nht_pos0_valid; int status; - uint8_t nht_pos0; /* Check input parameters */ if (lpm == NULL) { @@ -256,7 +255,7 @@ rte_table_lpm_ipv6_entry_add( /* Add rule to low level LPM table */ if (rte_lpm6_add(lpm->lpm, ip_prefix->ip, ip_prefix->depth, - (uint8_t) nht_pos) < 0) { + nht_pos) < 0) { RTE_LOG(ERR, TABLE, "%s: LPM IPv6 rule add failed\n", __func__); return -1; } @@ -280,7 +279,7 @@ rte_table_lpm_ipv6_entry_delete( struct rte_table_lpm_ipv6 *lpm = (struct rte_table_lpm_ipv6 *) table; struct rte_table_lpm_ipv6_key *ip_prefix = (struct rte_table_lpm_ipv6_key *) key; - uint8_t nht_pos; + uint32_t nht_pos; int status; /* Check input parameters */ @@ -356,7 +355,7 @@ rte_table_lpm_ipv6_lookup( uint8_t *ip = RTE_MBUF_METADATA_UINT8_PTR(pkt, lpm->offset); int status; - uint8_t nht_pos; + uint32_t nht_pos; status = rte_lpm6_lookup(lpm->lpm, ip, &nht_pos); if (status == 0) { -- 2.1.4