[dpdk-dev,v1,0/3] lpm: increase number of next hops for lpm (ipv4)

Message ID 562B209A.6030507@mhcomputing.net (mailing list archive)
State Not Applicable, archived
Headers

Commit Message

Matthew Hall Oct. 24, 2015, 6:09 a.m. UTC
  On 10/23/15 9:20 AM, Matthew Hall wrote:
> On Fri, Oct 23, 2015 at 03:51:48PM +0200, Michal Jastrzebski wrote:
>> From: Michal Kobylinski  <michalx.kobylinski@intel.com>
>>
>> The current DPDK implementation for LPM for IPv4 and IPv6 limits the
>> number of next hops to 256, as the next hop ID is an 8-bit long field.
>> Proposed extension increase number of next hops for IPv4 to 2^24 and
>> also allows 32-bits read/write operations.
>>
>> This patchset requires additional change to rte_table library to meet
>> ABI compatibility requirements. A v2 will be sent next week.
>
> I also have a patchset for this.
>
> I will send it out as well so we could compare.
>
> Matthew.

Sorry about the delay; I only work on DPDK in personal time and not as 
part of a job. My patchset is attached to this email.

One possible advantage with my patchset, compared to others, is that the 
space problem is fixed in both IPV4 and in IPV6, to prevent asymmetry 
between these two standards, which is something I try to avoid as much 
as humanly possible.

This is because my application code is green-field, so I absolutely 
don't want to put any ugly hacks or incompatibilities in this code if I 
can possibly avoid it.

Otherwise, I am not necessarily as expert about rte_lpm as some of the 
full-time guys, but I think with four or five of us in the thread 
hammering out patches we will be able to create something amazing 
together and I am very very very very very happy about this.

Matthew.
From 6a8e3428344ed11af8a1999dcec5c31c10f37c3a Mon Sep 17 00:00:00 2001
From: Matthew Hall <mhall@mhcomputing.net>
Date: Sat, 27 Jun 2015 22:49:46 +0000
Subject: [PATCH 1/8] rte_lpm.h: use 24 bit extended next hop

Signed-off-by: Matthew Hall <mhall@mhcomputing.net>
---
 lib/librte_lpm/rte_lpm.h | 46 +++++++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 17 deletions(-)
  

Comments

Michal Jastrzebski Oct. 26, 2015, 12:13 p.m. UTC | #1
> -----Original Message-----
> From: Matthew Hall [mailto:mhall@mhcomputing.net]
> Sent: Saturday, October 24, 2015 8:10 AM
> To: Jastrzebski, MichalX K; Kobylinski, MichalX
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v1 0/3] lpm: increase number of next hops
> for lpm (ipv4)
> 
> On 10/23/15 9:20 AM, Matthew Hall wrote:
> > On Fri, Oct 23, 2015 at 03:51:48PM +0200, Michal Jastrzebski wrote:
> >> From: Michal Kobylinski  <michalx.kobylinski@intel.com>
> >>
> >> The current DPDK implementation for LPM for IPv4 and IPv6 limits the
> >> number of next hops to 256, as the next hop ID is an 8-bit long field.
> >> Proposed extension increase number of next hops for IPv4 to 2^24 and
> >> also allows 32-bits read/write operations.
> >>
> >> This patchset requires additional change to rte_table library to meet
> >> ABI compatibility requirements. A v2 will be sent next week.
> >
> > I also have a patchset for this.
> >
> > I will send it out as well so we could compare.
> >
> > Matthew.
> 
> Sorry about the delay; I only work on DPDK in personal time and not as
> part of a job. My patchset is attached to this email.
> 
> One possible advantage with my patchset, compared to others, is that the
> space problem is fixed in both IPV4 and in IPV6, to prevent asymmetry
> between these two standards, which is something I try to avoid as much
> as humanly possible.
> 
> This is because my application code is green-field, so I absolutely
> don't want to put any ugly hacks or incompatibilities in this code if I
> can possibly avoid it.
> 
> Otherwise, I am not necessarily as expert about rte_lpm as some of the
> full-time guys, but I think with four or five of us in the thread
> hammering out patches we will be able to create something amazing
> together and I am very very very very very happy about this.
> 
> Matthew.

Hi Matthew,
Thank You for a patch-set.
I can't apply patch 0001-... , could You check it please? 
I have the following error:

Checking patch lib/librte_lpm/rte_lpm.h...
error: while searching for:
#endif

/** @internal bitmask with valid and ext_entry/valid_group fields set */
#define RTE_LPM_VALID_EXT_ENTRY_BITMASK 0x0300

/** Bitmask used to indicate successful lookup */
#define RTE_LPM_LOOKUP_SUCCESS          0x0100

#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
struct rte_lpm_tbl24_entry {
        /* Stores Next hop or group index (i.e. gindex)into tbl8. */
        union {
                uint8_t next_hop;
                uint8_t tbl8_gindex;
        };
        /* Using single uint8_t to store 3 values. */
        uint8_t valid     :1; /**< Validation flag. */
        uint8_t ext_entry :1; /**< External entry. */
        uint8_t depth     :6; /**< Rule depth. */
};

/** @internal Tbl8 entry structure. */
struct rte_lpm_tbl8_entry {
        uint8_t next_hop; /**< next hop. */
        /* Using single uint8_t to store 3 values. */
        uint8_t valid       :1; /**< Validation flag. */
        uint8_t valid_group :1; /**< Group validation flag. */
        uint8_t depth       :6; /**< Rule depth. */
};
#else
struct rte_lpm_tbl24_entry {

error: patch failed: lib/librte_lpm/rte_lpm.h:82
error: lib/librte_lpm/rte_lpm.h: patch does not apply

Best regards,
Michal
  
Matthew Hall Oct. 26, 2015, 6:40 p.m. UTC | #2
> I can't apply patch 0001-... , could You check it please? 

I generated it from a rebase of my own copy of DPDK against DPDK upstream 
master.

So I'm not sure why it would not apply against latest DPDK master.

But I will try it and see what could be the reason.

Matthew.
  
Vladimir Medvedkin Oct. 27, 2015, 10:35 a.m. UTC | #3
Hi Michal,

Try patch below. I will send it via git.

Regards,
Vladimir

2015-10-26 21:40 GMT+03:00 Matthew Hall <mhall@mhcomputing.net>:

> > I can't apply patch 0001-... , could You check it please?
>
> I generated it from a rebase of my own copy of DPDK against DPDK upstream
> master.
>
> So I'm not sure why it would not apply against latest DPDK master.
>
> But I will try it and see what could be the reason.
>
> Matthew.
>
  
Matthew Hall Oct. 30, 2015, 7:17 a.m. UTC | #4
On Mon, Oct 26, 2015 at 11:40:46AM -0700, Matthew Hall wrote:
> > I can't apply patch 0001-... , could You check it please? 
> 
> I generated it from a rebase of my own copy of DPDK against DPDK upstream 
> master.
> 
> So I'm not sure why it would not apply against latest DPDK master.
> 
> But I will try it and see what could be the reason.
> 
> Matthew.

Hello Michal,

I rechecked it.

The patch does apply perfectly to the latest master branch from 
git://dpdk.org/dpdk using git apply.

Can you take a second look? I compile my DPDK with the clang compiler BTW.

Matthew.
  

Patch

diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index c299ce2..c677c4a 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -82,32 +82,36 @@  extern "C" {
 #endif
 
 /** @internal bitmask with valid and ext_entry/valid_group fields set */
-#define RTE_LPM_VALID_EXT_ENTRY_BITMASK 0x0300
+#define RTE_LPM_VALID_EXT_ENTRY_BITMASK 0x03000000
+
+/** @internal bitmask with next_hop field set */
+#define RTE_LPM_NEXT_HOP_BITMASK        0x00FFFFFF
 
 /** Bitmask used to indicate successful lookup */
-#define RTE_LPM_LOOKUP_SUCCESS          0x0100
+#define RTE_LPM_LOOKUP_SUCCESS          0x01000000
+
 
 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
 /** @internal Tbl24 entry structure. */
 struct rte_lpm_tbl24_entry {
-	/* Stores Next hop or group index (i.e. gindex)into tbl8. */
+	/* Stores Next hop or group index (i.e. gindex) into tbl8. */
 	union {
-		uint8_t next_hop;
-		uint8_t tbl8_gindex;
-	};
+		uint32_t next_hop    :24;
+		uint32_t tbl8_gindex :24;
+	} __attribute__((__packed__));
 	/* Using single uint8_t to store 3 values. */
-	uint8_t valid     :1; /**< Validation flag. */
-	uint8_t ext_entry :1; /**< External entry. */
-	uint8_t depth     :6; /**< Rule depth. */
+	uint32_t valid     :1; /**< Validation flag. */
+	uint32_t ext_entry :1; /**< External entry. */
+	uint32_t depth     :6; /**< Rule depth. */
 };
 
 /** @internal Tbl8 entry structure. */
 struct rte_lpm_tbl8_entry {
-	uint8_t next_hop; /**< next hop. */
+	uint32_t next_hop   :24; /**< next hop. */
 	/* Using single uint8_t to store 3 values. */
-	uint8_t valid       :1; /**< Validation flag. */
-	uint8_t valid_group :1; /**< Group validation flag. */
-	uint8_t depth       :6; /**< Rule depth. */
+	uint8_t valid       :1;  /**< Validation flag. */
+	uint8_t valid_group :1;  /**< Group validation flag. */
+	uint8_t depth       :6;  /**< Rule depth. */
 };
 #else
 struct rte_lpm_tbl24_entry {
@@ -130,8 +134,8 @@  struct rte_lpm_tbl8_entry {
 
 /** @internal Rule structure. */
 struct rte_lpm_rule {
-	uint32_t ip; /**< Rule IP address. */
-	uint8_t  next_hop; /**< Rule next hop. */
+	uint32_t ip;       /**< Rule IP address. */
+	uint32_t next_hop; /**< Rule next hop. */
 };
 
 /** @internal Contains metadata about the rules table. */
@@ -219,7 +223,7 @@  rte_lpm_free(struct rte_lpm *lpm);
  *   0 on success, negative value otherwise
  */
 int
-rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint8_t next_hop);
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop);
 
 /**
  * Check if a rule is present in the LPM table,
@@ -238,7 +242,7 @@  rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint8_t next_hop);
  */
 int
 rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop);
+uint32_t *next_hop);
 
 /**
  * Delete a rule from the LPM table.
@@ -301,6 +305,8 @@  rte_lpm_lookup(struct rte_lpm *lpm, uint32_t ip, uint8_t *next_hop)
 	*next_hop = (uint8_t)tbl_entry;
 	return (tbl_entry & RTE_LPM_LOOKUP_SUCCESS) ? 0 : -ENOENT;
 }
+int
+rte_lpm_lookup(struct rte_lpm *lpm, uint32_t ip, uint32_t *next_hop);
 
 /**
  * Lookup multiple IP addresses in an LPM table. This may be implemented as a
@@ -360,6 +366,9 @@  rte_lpm_lookup_bulk_func(const struct rte_lpm *lpm, const uint32_t * ips,
 
 /* Mask four results. */
 #define	 RTE_LPM_MASKX4_RES	UINT64_C(0x00ff00ff00ff00ff)
+int
+rte_lpm_lookup_bulk(const struct rte_lpm *lpm, const uint32_t * ips,
+		uint32_t * next_hops, const unsigned n);
 
 /**
  * Lookup four IP addresses in an LPM table.
@@ -472,6 +481,9 @@  rte_lpm_lookupx4(const struct rte_lpm *lpm, __m128i ip, uint16_t hop[4],
 	hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[2] : defv;
 	hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[3] : defv;
 }
+void
+rte_lpm_lookupx4(const struct rte_lpm *lpm, __m128i ip, uint32_t hop[4],
+	uint32_t defv);
 
 #ifdef __cplusplus
 }