From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0046.outbound.protection.outlook.com [104.47.34.46]) by dpdk.org (Postfix) with ESMTP id 1E6C75320 for ; Sun, 19 Feb 2017 18:15:41 +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=NvkXbNvvEWweuB92u5lAlCKQBz8JkmaYcLJDqhX8/y0=; b=Pyid2hVWbfbqcdb0PCHethccAfINgJhUJfFeUJoZR0ZZfy8CJJ50mjhPKghh43u1GGz5FxsAhGwXfEilP79CRbvVHjTSqdo/6DeNL7qVA3LTz3pwsFqzrQsECn5BF0fOusjrCN9CRoIZ0DbXDknfle9pKl7lnMzembsi4ebZP9c= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Vladyslav.Buslov@harmonicinc.com; Received: from kms.harmonicinc.com (62.205.135.152) by MWHPR11MB1360.namprd11.prod.outlook.com (10.169.235.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.919.13; Sun, 19 Feb 2017 17:15:37 +0000 From: Vladyslav Buslov To: CC: Date: Sun, 19 Feb 2017 19:14:59 +0200 Message-ID: <1487524499-9570-1-git-send-email-vladyslav.buslov@harmonicinc.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [62.205.135.152] X-ClientProxiedBy: MWHPR1301CA0001.namprd13.prod.outlook.com (10.174.164.142) To MWHPR11MB1360.namprd11.prod.outlook.com (10.169.235.22) X-MS-Office365-Filtering-Correlation-Id: 1906186a-58c2-40e3-b23f-08d458eaed05 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:MWHPR11MB1360; X-Microsoft-Exchange-Diagnostics: 1; MWHPR11MB1360; 3:6oNBHgf8bPDKt3FVay1lCjmViOEdf3sUzS2xGTbAXLPu8Xs/C1QTWa7XFIh+BVjpYVml6hS123cWoMoJJRrZFZc06G2gZ5a56xpo0Mjnu5gBKDKgVKHJHqqsnuuiAdr/Rwg5d1ZSHGMDxBXfztVyApFQVMldKh9ka3o6kW5DzeeM+StrGm0NUYaYbPvZDhZupVfgBaSUTxV9ZiqlsfCiMCgTAvLBjSQ7nLfAU8AzmaHFsr8idMH7K4pkNx4TamM8wPl8S00lrbL5ELeWYYUYvvlYMjeZNDI9p7jR0YyZovE=; 25:C1utLXHUyMB/k+Y7U1f6v1jonlmZYPT6G42k5/ETBn41SnyUn3sm9ryYrhEbQynFN85XI5MIiuEZDiu/kcwKRlX+Tj4MraLOQKjR3U9idNPrcd7O+oSudSaJ1RQ3sG5WRRNcmO/wK62AWMUfEDRrL4wYb2vm5G67Yk8BIgpibM/IsNdC07MSUrMeX0l+T46AkjhUXQ/qik9CYfLbjf+M0lqCFLt0EWKkCkUDZ6+dB/L0xcrR0TN0DRF3CZgatc9ttofCS/eZktjlcdLRqTM5O7PXhL7A8HvL4ipAuk8D6C4RtOxtcAPa5qxPrmlmYF+9NAH7vxBTqwckbsWScXXHErk/U0VAqyxN/vUFBRtzpMzr3uxjl6/XMohbSzuaNfwNRTTeUkpr4IO8EeLCYOFAfc+ql5R+21lu0eFFH3cI8zvZoFfhGKD50V5di0Z3eR4NMchtfaZdgpUCD+1vniCZBA== X-Microsoft-Exchange-Diagnostics: 1; MWHPR11MB1360; 31:NfL/2zwDfcwp9DdHadxDjvo2oUzDlokIEa0T325TxArPuLJIMPg82rp7hM1ATKh5Mx497Z6I1IV052PTlieZffQtftdTyp61cr3zjtK3RWU552eiRAYaAY99LCokECxrtf0cS0wX4ivcF4/uKmXRyWgHm26Fl2XlV72rd9bFyGFOR8mFlAx9ofk5nZ6Mank77v4LJebQDaT9X5mq0y7qGK6/wzlPL4eHtJHwV41QpICDg+0Z+rI+7Le6luakzH8BUafUnSDFZUAs+ZTfZaIkQg==; 20:pp0eH2L/UYaSihqF18zcz4/DrV6f3zP6aP5M+9yfn5wKMPXoxpeZwCoNa5heMaLiwECzgUxvuRrOi6QS4sRfy/6aqo9eFw1MDvaP+auQh4wpbjbvLtcSH6GyB93wNHVdsOqMPCZIoVmDufZQavl1oTWdE6EoTRqedJBxzzedADZ1K8TXqXlsoN6dJiOcYpr2sexURR+tRp5lHbW3I5W369w8pMfr0oTe8Yx7emUhBD7QtQUH9GBUa9APT8z3XKPjVnXw/irNxq1jhB2NK10ceEiWQ7gMgg4DS/PX6ToRRsJo26loU+Lk0mI7TgSFtEd18w9u5Sieg6PL01Sl1f90JwmW0eb6c6Imbfvu+a7/cL5L2IAn71g8CQi059IfuUy3iroSACkNE789y70NmsQqoHd0cEl7EDmIrZBt2shfFAQRIVN69YnGXFgFoQENtKvVWNUR+1SdpvYe1pyPD6pXzZm6jlNV8ALi0OzlvlP5nL9fuoc6/BAC0QtKAk05UYg9 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)(20161123560025)(20161123558025)(20161123555025)(20161123564025)(20161123562025)(6072148); SRVR:MWHPR11MB1360; BCL:0; PCL:0; RULEID:; SRVR:MWHPR11MB1360; X-Microsoft-Exchange-Diagnostics: 1; MWHPR11MB1360; 4:JZN+n5beFaYIrUycZ0quyH9GeKXULVD10LIiOeF4uXSpDDFfSAFF8w0KtviM9vVLEaglC0royKh/wbbSX0xz8s0JDhyJUb3iX+94kgjTYxkRBSOVxADwc+/BUFEhHgT/eeRwwkpF/9h3thjkWuPS1yj2OFz62t4RGb9zkQWck+J580pD+dhYHYtGj17qxDTWY6AcvJ0SuG2Dv6sJ9THZDmZz/DKWNybU6Lo4SQtd4NDT6Aj6kfkiQCuUZZcC7HhKeS+OPpoRcaIbRmPz8QiX+RfAZb9vrQSi9MHvuzj1bFkbBZctTzhc7viT/w3TtyAmYdOYLi9hy6TaTAZvHUZA+sl1NE/T/iJSzCLS92T9DXHIw1HrMxlmgrkoRb993fMDIk+4TpPIvkHmXXl7u3kHt290tqDHv8x4B7BwYOclZftkLpr450us4e3Jbn0toCy5BwdPHF3S35uAfjD2yKXJ55RN9cSbUPEYAHQYTT49dKlntWR3kugHtzWCWm50Wpbn6SB+ra2q51qx9iMRCIznwnPQASy/BAUoGWYUMy6mr3Vpd9Rt3Ja3ol+n2cuzKxBLv3hU80EigS/qBH3+HG6FGcTrtJh8PlarflRtSwi+ESl5KLwdcQFVJgvt6mPz/6sZVTgf5Kng17feB7KdpWdpYLeBvmYWY63tqv/3c98DDZc= X-Forefront-PRVS: 02234DBFF6 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(39850400002)(39450400003)(39840400002)(39410400002)(199003)(189002)(38730400002)(110136004)(66066001)(86362001)(6666003)(48376002)(5003940100001)(5660300001)(50226002)(42186005)(2351001)(33646002)(106356001)(36756003)(7736002)(81156014)(53936002)(105586002)(6916009)(305945005)(4326007)(53946003)(6116002)(50986999)(81166006)(68736007)(2906002)(8676002)(47776003)(50466002)(6486002)(97736004)(53416004)(101416001)(92566002)(3846002)(25786008)(69596002)(189998001); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR11MB1360; H:kms.harmonicinc.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX: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; MWHPR11MB1360; 23:WOJ4OIIeN9WZftxmfs0JGYEw33kWE2l1VcwJSiCJ8?= =?us-ascii?Q?cjlwnVRfdfI+Z1mBa6kq4YPxIui4OaDY1ZlnNlFpf9MQ4EdQWMT710phOMJu?= =?us-ascii?Q?UQjUhQzLgZqMnvsdetixhJNcSmPex4Qi8YHXM2EEWOnxHqISxW9OsJX1Okif?= =?us-ascii?Q?wK3eEBy1/3Nz7NcE6T22JKDHbA8LeO6XI2G3w2f48Pmg8lZXzqn1CB6NMOm2?= =?us-ascii?Q?jQ/fGnqSpQh0J5Yl8/5X8XLZkYYZ863yg8DBZ829PvfHBk5Gw/BF/HjAOoaf?= =?us-ascii?Q?rFs8xEZAJdO1JQP8Sj9Oyk2olnos4u47hSPKgwt5hw7iL15JU+kZq9uD4jrr?= =?us-ascii?Q?MjJad1xgm71yjEuEmnvfE0XFVHalGkKAmmMdxwXwtu11X8geL/YAcfC2JzQY?= =?us-ascii?Q?Mgwom3vQdLLLiAFmkG024NZQRysSxCIt6x8dQO8p63LI9maPdlIZH0YXm2Qs?= =?us-ascii?Q?X/VcEy0chCJZlCg2cdDaByR7HDTP7cLnVqLlILBYLIdUzXT+aa1ohfUzwMEP?= =?us-ascii?Q?gVVpAsbvYdGbuUMxwnCQRYe+pyhRH6hUgGQaGkCr13+F0pYt0NiGM0U+vwHe?= =?us-ascii?Q?NpzB/7uo4lCuHCGSkfhT7OkoLMw9uEKzLY7iLPqYv5UzZiNIXORIwWyQ5cf5?= =?us-ascii?Q?DYQo0cjw2dTqGdtaVHYgr942F/iACRLmIqg2QNdZMm57/R9AE2uX3VqX8eeU?= =?us-ascii?Q?9zaMgxyPvBFlOytJL3u4qgxCwvT/6wPgYeLUqz60P61gtQrUCZ6baWYFHq3E?= =?us-ascii?Q?epui2LQl5L6IUDfjgitjemHG9kxDxmOyNlvil8vdILaE6H1EMAUzKCz7XTXo?= =?us-ascii?Q?CYU/4tcHf7fZ9X38SNOWFYfleFbIEED4rWYfGb3xxUlQyAqWVyFisQY95KUa?= =?us-ascii?Q?RIF2a94rWwuHXjf6SoJYpIyBYEDahs+/IqNzP2V+5+xW8yOxCggGhi0DQEg/?= =?us-ascii?Q?LWzmUlBPIjrOpARC7mGG6XY/8d3oHmje4bw5DBpmRc99rZBBeutimL+/3waz?= =?us-ascii?Q?6hygZFCw4YyIhcF+3vh0XBQ7sq7tOor7vwqTDqTTAyxzboWLeGBWvhSMSOAH?= =?us-ascii?Q?J2IuCNcl6EppUSnFN8I67IbnLb+GhlRb3Rr+wV4JzJHJGG8AttXYWmsmUK7S?= =?us-ascii?Q?szvn7gfltu6WSPFhnB46qaY3qU41xjFCQqYebHBU32SSOPd6UXkx4O/8JaL8?= =?us-ascii?Q?PUI3741gVcJxrQ=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR11MB1360; 6:4c2ryLWpAWBDNlCPNxxLFT5GH3XCFmU9rSFPDf1aTGI9SqnHOCioZr6wYe7V9YaO0DQWYkReb0zZinhYm8dQiR/j65Dm2VHov/sVHtGn18530Wao+Y5zYJRb6MKyas+y9vFEPe98mTsjskRr1LUz42NEiPlcvxJV0uwMNGdQaoRYxdRQMBjmKzYk55fcnkfHXweDOU/+uur+q5IrY2yXXRDn/inaep5QYE1l0iowQWbvEpY7J6RTAlCr+Ow6WTcam7sZDXQhK76usfyl3VHr6Z4X6je5iTl/vRW6EOnFdLkT4VLsg15xKyHyyZiMyFuTyBISBsF6noSAcNqr3N5qfglO0+qMrPsIsXaMrE7pbNCI8ReYJ8+b2UUu4M4z5Pbnrq63OLx7A1x9n7CTxpOBZiGVGpkk2DwNJhw4sQxmdOM=; 5:aG22AJi/eHtKtdhQbllHVSzwTypxfLo8vYEFLc9Iz/u5pKs7xc0CucI3WLsFmE2eKVyzcK68rY/5w9jhibjZ3jb05DhDpeSNQaN5aHgFzBX4rrxCMR5yoNAjf6F1ZKkDFkwUm1ukYq5aioj4tgju/mHN+GU4W0xiQmOVke5MKJw=; 24:L/pQoioMvyllTdwFdWDZ3nB7oBR694swn2YTRhgGdS7XJmkI+w/hl5Yxlkh4Qc0HZFb9g42Q8paL8D1w1cSMjY0UAjIKfZrF84lMGi/XV80= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR11MB1360; 7:n01RzwPk66QV9TbqMvmEIevt2uZOR3/UWR/NwDAf6SSVv56RE1aF9+b6OW3Ww69LdB8802tq4dugfeWHvBX7p6U7MWzRbrDgEP6ckB2ydzr5RGhevDgaY08MoCvqu01xaNbHS4Xt7tv4HPuxhh7iYNvJ0k+y4fN+BHcP4rdMfTvAJoMUerh5ilm0xHqPfld4LKSKhhxx5DQGxyY0waJ982r4l75OQvXuv+sQKm2/ZMJ/a0xyPFSUTaZcBlZWkeNdL5POr/EGhzIMbLIQoxz67aHUCDTWsIOvMc7ZGiRnRgMBjW1vDt/PsXTx4BE0tCCcm61L+NUCjD3jB9EoRuRxrg==; 20:jYEh7HjRLzFEyZGYnrUVkCwyTALbB9vEd3XTNNYbX3GMFxUTsPOKrN34hGEn9HEWuAngBKjL2iGggspSrQqJQa9t6uoOjVOu38n0nUkHDw9bu1w37drVhya8cGiAi36txSO1HEw4Z8amPbXxrsLtBBr2v7OreJYD+E9ywEwechA= X-OriginatorOrg: harmonicinc.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Feb 2017 17:15:37.4155 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR11MB1360 Subject: [dpdk-dev] [PATCH] 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: Sun, 19 Feb 2017 17:15:43 -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 | 114 ++++++++++++++------ 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 | 16 +-- examples/ip_reassembly/main.c | 16 +-- examples/ipsec-secgw/ipsec-secgw.c | 2 +- examples/l3fwd/l3fwd_lpm_sse.h | 20 ++-- examples/performance-thread/l3fwd-thread/main.c | 9 +- lib/librte_lpm/rte_lpm6.c | 133 +++++++++++++++++++++--- lib/librte_lpm/rte_lpm6.h | 29 +++++- lib/librte_lpm/rte_lpm_version.map | 10 ++ lib/librte_table/rte_table_lpm_ipv6.c | 9 +- 13 files changed, 282 insertions(+), 87 deletions(-) diff --git a/app/test/test_lpm6.c b/app/test/test_lpm6.c index 61134f7..2950aae 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,41 @@ 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..51035f5 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,9 @@ 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..50730a2 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,9 @@ 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..1ef70d3 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; @@ -52,8 +51,8 @@ lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt, 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); + 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 +60,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 +77,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 +91,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..510d6e8 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,7 +1412,7 @@ 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 : + 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..8915fff 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,9 @@ 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 +580,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 +600,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 +609,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 +655,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 +697,58 @@ 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 n) +{ + unsigned 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 n), + rte_lpm6_lookup_bulk_func_v1705); /* * Finds a rule in rule table. @@ -698,8 +778,29 @@ 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 +825,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..0ab54d4 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,11 @@ 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 +237,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], + int32_t * next_hops, unsigned 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 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 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