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:
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.**
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
-----------
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;
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;
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;
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];
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);
}
/* 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);
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;
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;
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;
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)) {
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);
}
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)) {
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);
}
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) ?
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)) {
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);
}
/** 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. */
};
* 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;
*/
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;
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;
* 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;
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.
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;
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;
}
}
* 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;
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. */
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.
* 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;
/* 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.
*/
#include <stdint.h>
+#include <rte_compat.h>
#ifdef __cplusplus
extern "C" {
*/
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,
*/
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.
* -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.
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
}
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;
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) {
/* 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;
}
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 */
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) {
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 */
test25,
test26,
test27,
+ test28,
};
#define NUM_LPM6_TESTS (sizeof(tests6)/sizeof(tests6[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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
/* 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);
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;
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;
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;
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;
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;
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;
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;
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;
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);
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);
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);
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;
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.
*/
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;
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);