]> git.droids-corp.org - dpdk.git/commitdiff
lpm6: extend next hop field
authorVladyslav Buslov <vladyslav.buslov@harmonicinc.com>
Tue, 14 Mar 2017 17:17:38 +0000 (19:17 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 15 Mar 2017 17:49:41 +0000 (18:49 +0100)
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 <vladyslav.buslov@harmonicinc.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
14 files changed:
doc/guides/prog_guide/lpm6_lib.rst
doc/guides/rel_notes/release_17_05.rst
examples/ip_fragmentation/main.c
examples/ip_reassembly/main.c
examples/ipsec-secgw/ipsec-secgw.c
examples/l3fwd/l3fwd_lpm.h
examples/l3fwd/l3fwd_lpm_sse.h
examples/performance-thread/l3fwd-thread/main.c
lib/librte_lpm/rte_lpm6.c
lib/librte_lpm/rte_lpm6.h
lib/librte_lpm/rte_lpm_version.map
lib/librte_table/rte_table_lpm_ipv6.c
test/test/test_lpm6.c
test/test/test_lpm6_perf.c

index 0aea5c5c30b573ab92e7381439d8363bacd29b68..f7915073364f2d7af968c5f7e029799334239f1d 100644 (file)
@@ -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.
 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:
 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:
index 4b90036ef24900c5e4164ede6346ce24a5ac84d6..918f4839680ffdfd28aae8a22ed67e4b74d0c9a4 100644 (file)
@@ -41,6 +41,9 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
      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.
 
 * **Added powerpc support in pci probing for vfio-pci devices.**
 
 
 * **Added powerpc support in pci probing for vfio-pci devices.**
 
@@ -114,6 +117,8 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
    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
 -----------
 
 ABI Changes
 -----------
index 9e9ecaefb9c09409c4eb64773ab2c36cfae29f29..1b005b5fd671ff8a1370c95d9168f7a28664f1d7 100644 (file)
@@ -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;
                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;
        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 */
                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;
 
                        /* 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 */
                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;
 
                        /* Build transmission burst for new port */
                        len = qconf->tx_mbufs[port_out].len;
index e62674c5d05d153a4a2b868457c20f74224592fc..b641576fc90196808f092a19b695f39a7671bc3a 100644 (file)
@@ -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;
        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];
 
 
        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 */
                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);
                }
 
                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 */
                }
 
                /* 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);
                }
 
                eth_hdr->ether_type = rte_be_to_cpu_16(ETHER_TYPE_IPv6);
index 685feec1fdca253c25613f3daa3608de85b9b720..d3c229abb6dd33899c1562cd3410d6adafd8e3a2 100644 (file)
@@ -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)
 {
 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;
        uint8_t dst_ip[MAX_PKT_BURST * 2][16];
        uint8_t *ip6_dst;
        uint16_t i, offset;
index a43c50703f06308f2ff48331c0bb8272dd251b92..258a82fec8858463f91a2d7e7d50f52c7b19b8e7 100644 (file)
@@ -49,7 +49,7 @@ lpm_get_ipv4_dst_port(void *ipv4_hdr,  uint8_t portid, void *lookup_struct)
 static inline uint8_t
 lpm_get_ipv6_dst_port(void *ipv6_hdr,  uint8_t portid, void *lookup_struct)
 {
 static inline uint8_t
 lpm_get_ipv6_dst_port(void *ipv6_hdr,  uint8_t portid, void *lookup_struct)
 {
-       uint8_t next_hop;
+       uint32_t next_hop;
        struct rte_lpm6 *ipv6_l3fwd_lookup_struct =
                (struct rte_lpm6 *)lookup_struct;
 
        struct rte_lpm6 *ipv6_l3fwd_lookup_struct =
                (struct rte_lpm6 *)lookup_struct;
 
index 538fe3d7602d26ee476b92e4d883687c79c156c6..aa06b6d34346ca98a8c263656583531660e3ec26 100644 (file)
@@ -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)
 {
 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;
        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);
 
                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)) {
 
 
        } 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 = (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)
 {
 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,
        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)) {
 
 
        } 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 = (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);
 
        }
 
 
        }
 
index 6845e28729cde1f4b27259bd15330aec593c1ffd..bf92582246614e5bd0932971ad9015f86a8c6259 100644 (file)
@@ -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)
 {
 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) ?
 
        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)
 {
 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,
        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)) {
 
 
        } 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,
 
                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);
 
        }
 
 
        }
 
index 32fdba01e8d532bf4007a41aac2e2adc55a22a0f..9cc7be77dd78446a7f998dc46ed6c96df3d448e3 100644 (file)
@@ -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. */
 /** 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. */
 };
 
        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
  * 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;
 
 {
        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,
  */
 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;
 
 {
        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,
 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;
 {
        uint32_t tbl_index, tbl_range, tbl8_group_start, tbl8_group_end, i;
        int32_t tbl8_gindex;
@@ -507,8 +507,16 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
  * Add a route
  */
 int
  * 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)
                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;
 {
        struct rte_lpm6_tbl_entry *tbl;
        struct rte_lpm6_tbl_entry *tbl_next;
@@ -560,6 +568,10 @@ rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
 
        return status;
 }
 
        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.
 
 /*
  * 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,
 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;
 
 {
        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. */
                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;
        }
 }
                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
  * 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;
 {
        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;
 }
 
        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
 
 /*
  * 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;
                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. */
        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
                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;
 }
        }
 
        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.
 
 /*
  * 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
  * 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;
 {
        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;
 }
        /* 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.
 
 /*
  * Delete a rule from the rule table.
index 13d027f95913feedbcb6248ba277cd3dabcce4fa..3a3342dacb726d03be28071d38909631b8aee5d3 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include <stdint.h>
  */
 
 #include <stdint.h>
+#include <rte_compat.h>
 
 #ifdef __cplusplus
 extern "C" {
 
 #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,
  */
 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);
                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,
 
 /**
  * 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,
  */
 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.
 
 /**
  * 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
  *   -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.
 
 /**
  * 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],
 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
 }
 
 #ifdef __cplusplus
 }
index 239b371e28d87577c71154b5e1d6fc9344c798a1..90beac853d2e0aedf2f7650d602add5959e9e86d 100644 (file)
@@ -34,3 +34,13 @@ DPDK_16.04 {
        rte_lpm_delete_all;
 
 } DPDK_2.0;
        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;
index 836f4cf6c5602a6f4c76f49f1b7c0d79afd44748..1e1a173a9e41f6877992b86abf19b57964976123 100644 (file)
@@ -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;
        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;
        int status;
-       uint8_t nht_pos0;
 
        /* Check input parameters */
        if (lpm == NULL) {
 
        /* 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,
 
        /* 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;
        }
                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;
        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 */
        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 *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) {
 
                        status = rte_lpm6_lookup(lpm->lpm, ip, &nht_pos);
                        if (status == 0) {
index 61134f70034450730372fb87ccc0dd3b6f281664..e0e7bf0212d8a25e10e7350e14669d261d5ffe91 100644 (file)
@@ -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 test25(void);
 static int32_t test26(void);
 static int32_t test27(void);
+static int32_t test28(void);
 
 rte_lpm6_test tests6[] = {
 /* Test Cases */
 
 rte_lpm6_test tests6[] = {
 /* Test Cases */
@@ -110,6 +111,7 @@ rte_lpm6_test tests6[] = {
        test25,
        test26,
        test27,
        test25,
        test26,
        test27,
+       test28,
 };
 
 #define NUM_LPM6_TESTS                (sizeof(tests6)/sizeof(tests6[0]))
 };
 
 #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};
        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;
        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];
        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;
        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};
        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;
 
        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};
        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;
 
        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};
        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;
        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};
        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;
        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};
        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;
        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};
        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;
 
        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};
        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;
        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};
        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;
        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 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;
        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--) {
 
        /* 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);
 
                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];
        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;
        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];
        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;
        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];
        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;
        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];
        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;
        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];
        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;
        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];
        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;
        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;
        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;
        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 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;
        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);
                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);
 
        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);
                        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);
 
        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);
                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);
 
        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};
                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;
 
                int32_t status = 0;
                int i, j;
 
@@ -1745,6 +1764,42 @@ test27(void)
                return PASS;
 }
 
                return PASS;
 }
 
+/*
+ * 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.
  */
 /*
  * Do all unit tests.
  */
index 0723081bb5f8c1194d8c2e2093c22d92d1e9ecdd..30be430f7c519911db77cf80abc4e91f5fb45c8b 100644 (file)
@@ -86,7 +86,7 @@ test_lpm6_perf(void)
        struct rte_lpm6_config config;
        uint64_t begin, total_time;
        unsigned i, j;
        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;
 
        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];
        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);
 
        for (i = 0; i < NUM_IPS_ENTRIES; i++)
                memcpy(ip_batch[i], large_ips_table[i].ip, 16);