DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev]  [PATCH 2/2] librte_ip_frag: add mbuf counter
@ 2018-05-16 11:04 Alex Kiselev
  0 siblings, 0 replies; 3+ messages in thread
From: Alex Kiselev @ 2018-05-16 11:04 UTC (permalink / raw)
  To: dev, Burakov, Anatoly

add new function rte_frag_table_mbuf_count() that returns
number of mbufs holded in the fragmentation table.

There might be situations (kind of attack when a lot of
fragmented packets are sent to a dpdk application in order
to flood the fragmentation table) when no additional mbufs
must be added to the fragmentations table since it already
contains to many of them. Currently there is no way to
determine the number of mbufs holded int the fragmentation
table. This patch allows to keep track of the number of mbufs
holded in the fragmentation table.

Signed-off-by: Alex Kiselev <alex@therouter.net>
---
 lib/librte_ip_frag/ip_frag_common.h        | 12 +++++++-----
 lib/librte_ip_frag/ip_frag_internal.c      | 15 +++++++++------
 lib/librte_ip_frag/rte_ip_frag.h           | 16 ++++++++++++++++
 lib/librte_ip_frag/rte_ip_frag_common.c    |  1 +
 lib/librte_ip_frag/rte_ip_frag_version.map |  1 +
 lib/librte_ip_frag/rte_ipv4_reassembly.c   |  2 +-
 lib/librte_ip_frag/rte_ipv6_reassembly.c   |  2 +-
 7 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h
index 0fdcc7d0f..d04e69de6 100644
--- a/lib/librte_ip_frag/ip_frag_common.h
+++ b/lib/librte_ip_frag/ip_frag_common.h
@@ -32,9 +32,9 @@
 #endif /* IP_FRAG_TBL_STAT */
 
 /* internal functions declarations */
-struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp,
-		struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
-		uint16_t ofs, uint16_t len, uint16_t more_frags);
+struct rte_mbuf * ip_frag_process(struct rte_ip_frag_tbl *tbl, 
+	struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr, 
+	struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags);
 
 struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl,
 		struct rte_ip_frag_death_row *dr,
@@ -91,7 +91,8 @@ ip_frag_key_cmp(const struct ip_frag_key * k1, const struct ip_frag_key * k2)
 
 /* put fragment on death row */
 static inline void
-ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
+ip_frag_free(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp, 
+	struct rte_ip_frag_death_row *dr)
 {
 	uint32_t i, k;
 
@@ -100,6 +101,7 @@ ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
 		if (fp->frags[i].mb != NULL) {
 			dr->row[k++] = fp->frags[i].mb;
 			fp->frags[i].mb = NULL;
+			tbl->nb_mbufs --;
 		}
 	}
 
@@ -160,7 +162,7 @@ static inline void
 ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
 	struct ip_frag_pkt *fp)
 {
-	ip_frag_free(fp, dr);
+	ip_frag_free(tbl, fp, dr);
 	ip_frag_key_invalidate(&fp->key);
 	TAILQ_REMOVE(&tbl->lru, fp, lru);
 	tbl->use_entries--;
diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/ip_frag_internal.c
index 97470a872..eea871b7e 100644
--- a/lib/librte_ip_frag/ip_frag_internal.c
+++ b/lib/librte_ip_frag/ip_frag_internal.c
@@ -29,14 +29,13 @@ static inline void
 ip_frag_tbl_reuse(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
 	struct ip_frag_pkt *fp, uint64_t tms)
 {
-	ip_frag_free(fp, dr);
+	ip_frag_free(tbl, fp, dr);
 	ip_frag_reset(fp, tms);
 	TAILQ_REMOVE(&tbl->lru, fp, lru);
 	TAILQ_INSERT_TAIL(&tbl->lru, fp, lru);
 	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, reuse_num, 1);
 }
 
-
 static inline void
 ipv4_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
 {
@@ -88,8 +87,9 @@ ipv6_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
 }
 
 struct rte_mbuf *
-ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
-	struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags)
+ip_frag_process(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp,
+	struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, uint16_t ofs,
+	uint16_t len, uint16_t more_frags)
 {
 	uint32_t idx;
 
@@ -147,7 +147,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
 				fp->frags[IP_LAST_FRAG_IDX].len);
 
 		/* free all fragments, invalidate the entry. */
-		ip_frag_free(fp, dr);
+		ip_frag_free(tbl, fp, dr);
 		ip_frag_key_invalidate(&fp->key);
 		IP_FRAG_MBUF2DR(dr, mb);
 
@@ -157,6 +157,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
 	fp->frags[idx].ofs = ofs;
 	fp->frags[idx].len = len;
 	fp->frags[idx].mb = mb;
+	tbl->nb_mbufs++;
 
 	mb = NULL;
 
@@ -205,8 +206,10 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
 				fp->frags[IP_LAST_FRAG_IDX].len);
 
 		/* free associated resources. */
-		ip_frag_free(fp, dr);
+		ip_frag_free(tbl, fp, dr);
 	}
+	else
+		tbl->nb_mbufs -= fp->last_idx;
 
 	/* we are done with that entry, invalidate it. */
 	ip_frag_key_invalidate(&fp->key);
diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
index 3c694df92..4aba8a064 100644
--- a/lib/librte_ip_frag/rte_ip_frag.h
+++ b/lib/librte_ip_frag/rte_ip_frag.h
@@ -96,6 +96,7 @@ struct rte_ip_frag_tbl {
 	uint32_t             bucket_entries;  /**< hash associativity. */
 	uint32_t             nb_entries;      /**< total size of the table. */
 	uint32_t             nb_buckets;      /**< num of associativity lines. */
+	uint32_t             nb_mbufs;        /**< num of mbufs holded in the tbl. */
 	struct ip_frag_pkt *last;         /**< last used entry. */
 	struct ip_pkt_list lru;           /**< LRU list for table entries. */
 	struct ip_frag_tbl_stat stat;     /**< statistics counters. */
@@ -328,6 +329,21 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
 void
 rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
 
+/**
+ * Number of mbufs holded in the fragmentation table.
+ *
+ * @param tbl
+ *   Fragmentation table
+ * 
+ * @return
+ *   Number of mbufs holded in the fragmentation table.
+ */
+static inline uint32_t __rte_experimental
+rte_frag_table_mbuf_count(const struct rte_ip_frag_tbl *tbl)
+{
+	return tbl->nb_mbufs;
+}
+
 /**
  * Delete expired fragments
  * 
diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag/rte_ip_frag_common.c
index f62b5d169..6e7aaac45 100644
--- a/lib/librte_ip_frag/rte_ip_frag_common.c
+++ b/lib/librte_ip_frag/rte_ip_frag_common.c
@@ -75,6 +75,7 @@ rte_ip_frag_table_create(uint32_t bucket_num, uint32_t bucket_entries,
 	tbl->nb_buckets = bucket_num;
 	tbl->bucket_entries = bucket_entries;
 	tbl->entry_mask = (tbl->nb_entries - 1) & ~(tbl->bucket_entries  - 1);
+	tbl->nb_mbufs = 0;
 
 	TAILQ_INIT(&(tbl->lru));
 	return tbl;
diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
index d40d5515f..f4700f460 100644
--- a/lib/librte_ip_frag/rte_ip_frag_version.map
+++ b/lib/librte_ip_frag/rte_ip_frag_version.map
@@ -23,4 +23,5 @@ EXPERIMENTAL {
 	global:
 
 	rte_frag_table_del_expired_entries;
+	rte_frag_table_mbuf_count;
 };
diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c
index 4956b99ea..fbdfd860a 100644
--- a/lib/librte_ip_frag/rte_ipv4_reassembly.c
+++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c
@@ -146,7 +146,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,
 
 
 	/* process the fragmented packet. */
-	mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len, ip_flag);
+	mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len, ip_flag);
 	ip_frag_inuse(tbl, fp);
 
 	IP_FRAG_LOG(DEBUG, "%s:%d:\n"
diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c
index db249fe60..dda5a57b7 100644
--- a/lib/librte_ip_frag/rte_ipv6_reassembly.c
+++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c
@@ -186,7 +186,7 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,
 
 
 	/* process the fragmented packet. */
-	mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len,
+	mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len,
 			MORE_FRAGS(frag_hdr->frag_data));
 	ip_frag_inuse(tbl, fp);
 
-- 
2.16.1.windows.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] librte_ip_frag: add mbuf counter
  2018-05-31 13:19 ` Ananyev, Konstantin
@ 2018-05-31 14:29   ` Alex Kiselev
  0 siblings, 0 replies; 3+ messages in thread
From: Alex Kiselev @ 2018-05-31 14:29 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev, Burakov, Anatoly

Hi Konstantin.

>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Alex Kiselev
>> Sent: Wednesday, May 16, 2018 12:04 PM
>> To: dev@dpdk.org; Burakov, Anatoly <anatoly.burakov@intel.com>
>> Subject: [dpdk-dev] [PATCH 2/2] librte_ip_frag: add mbuf counter

>> add new function rte_frag_table_mbuf_count() that returns
>> number of mbufs holded in the fragmentation table.

>> There might be situations (kind of attack when a lot of
>> fragmented packets are sent to a dpdk application in order
>> to flood the fragmentation table) when no additional mbufs
>> must be added to the fragmentations table since it already
>> contains to many of them. Currently there is no way to
>> determine the number of mbufs holded int the fragmentation
>> table. This patch allows to keep track of the number of mbufs
>> holded in the fragmentation table.

>> Signed-off-by: Alex Kiselev <alex@therouter.net>
>> ---
>>  lib/librte_ip_frag/ip_frag_common.h        | 12 +++++++-----
>>  lib/librte_ip_frag/ip_frag_internal.c      | 15 +++++++++------
>>  lib/librte_ip_frag/rte_ip_frag.h           | 16 ++++++++++++++++
>>  lib/librte_ip_frag/rte_ip_frag_common.c    |  1 +
>>  lib/librte_ip_frag/rte_ip_frag_version.map |  1 +
>>  lib/librte_ip_frag/rte_ipv4_reassembly.c   |  2 +-
>>  lib/librte_ip_frag/rte_ipv6_reassembly.c   |  2 +-
>>  7 files changed, 36 insertions(+), 13 deletions(-)

> Do we really need it?
> It's quite significant code changes and the advantage looks quite small to me...
Most of the changes are just movements of some internal functions in order
to reuse them in the new code. Basically, the only change I propose is adding one
additional counter.

> We already have use_entries, right?
Let's say for example that there are 8 fragmentation tables, 
one table per lcore, since it doesn't support concurrent operations.
use_entries variable indicates that 1000 entries are in use. Each entry 
can hold from 1 to 4 mbufs (RTE_LIBRTE_IP_FRAG_MAX_FRAG).
So, you can't tell whether a fragmentation table holds 1000 mbufs or 4000,
then if we multiply this number to 8 fragmentation tables the estimation
would be even more incorrect. That estimation error might be critical under 
DOS attacks since mbufs is a pretty much limited resource.

> That can be used to get some estimation for a number of mbufs in the table.
> Konstantin


>> diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h
>> index 0fdcc7d0f..d04e69de6 100644
>> --- a/lib/librte_ip_frag/ip_frag_common.h
>> +++ b/lib/librte_ip_frag/ip_frag_common.h
>> @@ -32,9 +32,9 @@
>>  #endif /* IP_FRAG_TBL_STAT */

>>  /* internal functions declarations */
>> -struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp,
>> -             struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
>> -             uint16_t ofs, uint16_t len, uint16_t more_frags);
>> +struct rte_mbuf * ip_frag_process(struct rte_ip_frag_tbl *tbl,
>> +     struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>> +     struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags);

>>  struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl,
>>               struct rte_ip_frag_death_row *dr,
>> @@ -91,7 +91,8 @@ ip_frag_key_cmp(const struct ip_frag_key * k1, const struct ip_frag_key * k2)

>>  /* put fragment on death row */
>>  static inline void
>> -ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
>> +ip_frag_free(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp,
>> +     struct rte_ip_frag_death_row *dr)
>>  {
>>       uint32_t i, k;

>> @@ -100,6 +101,7 @@ ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
>>               if (fp->frags[i].mb != NULL) {
>>                       dr->row[k++] = fp->frags[i].mb;
>>                       fp->frags[i].mb = NULL;
>> +                     tbl->nb_mbufs --;
>>               }
>>       }

>> @@ -160,7 +162,7 @@ static inline void
>>  ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
>>       struct ip_frag_pkt *fp)
>>  {
>> -     ip_frag_free(fp, dr);
>> +     ip_frag_free(tbl, fp, dr);
>>       ip_frag_key_invalidate(&fp->key);
>>       TAILQ_REMOVE(&tbl->lru, fp, lru);
>>       tbl->use_entries--;
>> diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/ip_frag_internal.c
>> index 97470a872..eea871b7e 100644
>> --- a/lib/librte_ip_frag/ip_frag_internal.c
>> +++ b/lib/librte_ip_frag/ip_frag_internal.c
>> @@ -29,14 +29,13 @@ static inline void
>>  ip_frag_tbl_reuse(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
>>       struct ip_frag_pkt *fp, uint64_t tms)
>>  {
>> -     ip_frag_free(fp, dr);
>> +     ip_frag_free(tbl, fp, dr);
>>       ip_frag_reset(fp, tms);
>>       TAILQ_REMOVE(&tbl->lru, fp, lru);
>>       TAILQ_INSERT_TAIL(&tbl->lru, fp, lru);
>>       IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, reuse_num, 1);
>>  }

>> -
>>  static inline void
>>  ipv4_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
>>  {
>> @@ -88,8 +87,9 @@ ipv6_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
>>  }

>>  struct rte_mbuf *
>> -ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>> -     struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags)
>> +ip_frag_process(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp,
>> +     struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, uint16_t ofs,
>> +     uint16_t len, uint16_t more_frags)
>>  {
>>       uint32_t idx;

>> @@ -147,7 +147,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>>                               fp->frags[IP_LAST_FRAG_IDX].len);

>>               /* free all fragments, invalidate the entry. */
>> -             ip_frag_free(fp, dr);
>> +             ip_frag_free(tbl, fp, dr);
>>               ip_frag_key_invalidate(&fp->key);
>>               IP_FRAG_MBUF2DR(dr, mb);

>> @@ -157,6 +157,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>>       fp->frags[idx].ofs = ofs;
>>       fp->frags[idx].len = len;
>>       fp->frags[idx].mb = mb;
>> +     tbl->nb_mbufs++;

>>       mb = NULL;

>> @@ -205,8 +206,10 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>>                               fp->frags[IP_LAST_FRAG_IDX].len);

>>               /* free associated resources. */
>> -             ip_frag_free(fp, dr);
>> +             ip_frag_free(tbl, fp, dr);
>>       }
>> +     else
>> +             tbl->nb_mbufs -= fp->last_idx;

>>       /* we are done with that entry, invalidate it. */
>>       ip_frag_key_invalidate(&fp->key);
>> diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
>> index 3c694df92..4aba8a064 100644
>> --- a/lib/librte_ip_frag/rte_ip_frag.h
>> +++ b/lib/librte_ip_frag/rte_ip_frag.h
>> @@ -96,6 +96,7 @@ struct rte_ip_frag_tbl {
>>       uint32_t             bucket_entries;  /**< hash associativity. */
>>       uint32_t             nb_entries;      /**< total size of the table. */
>>       uint32_t             nb_buckets;      /**< num of associativity lines. */
>> +     uint32_t             nb_mbufs;        /**< num of mbufs holded in the tbl. */
>>       struct ip_frag_pkt *last;         /**< last used entry. */
>>       struct ip_pkt_list lru;           /**< LRU list for table entries. */
>>       struct ip_frag_tbl_stat stat;     /**< statistics counters. */
>> @@ -328,6 +329,21 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
>>  void
>>  rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);

>> +/**
>> + * Number of mbufs holded in the fragmentation table.
>> + *
>> + * @param tbl
>> + *   Fragmentation table
>> + *
>> + * @return
>> + *   Number of mbufs holded in the fragmentation table.
>> + */
>> +static inline uint32_t __rte_experimental
>> +rte_frag_table_mbuf_count(const struct rte_ip_frag_tbl *tbl)
>> +{
>> +     return tbl->nb_mbufs;
>> +}
>> +
>>  /**
>>   * Delete expired fragments
>>   *
>> diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag/rte_ip_frag_common.c
>> index f62b5d169..6e7aaac45 100644
>> --- a/lib/librte_ip_frag/rte_ip_frag_common.c
>> +++ b/lib/librte_ip_frag/rte_ip_frag_common.c
>> @@ -75,6 +75,7 @@ rte_ip_frag_table_create(uint32_t bucket_num, uint32_t bucket_entries,
>>       tbl->nb_buckets = bucket_num;
>>       tbl->bucket_entries = bucket_entries;
>>       tbl->entry_mask = (tbl->nb_entries - 1) & ~(tbl->bucket_entries  - 1);
>> +     tbl->nb_mbufs = 0;

>>       TAILQ_INIT(&(tbl->lru));
>>       return tbl;
>> diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
>> index d40d5515f..f4700f460 100644
>> --- a/lib/librte_ip_frag/rte_ip_frag_version.map
>> +++ b/lib/librte_ip_frag/rte_ip_frag_version.map
>> @@ -23,4 +23,5 @@ EXPERIMENTAL {
>>       global:

>>       rte_frag_table_del_expired_entries;
>> +     rte_frag_table_mbuf_count;
>>  };
>> diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c
>> index 4956b99ea..fbdfd860a 100644
>> --- a/lib/librte_ip_frag/rte_ipv4_reassembly.c
>> +++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c
>> @@ -146,7 +146,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,


>>       /* process the fragmented packet. */
>> -     mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len, ip_flag);
>> +     mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len, ip_flag);
>>       ip_frag_inuse(tbl, fp);

>>       IP_FRAG_LOG(DEBUG, "%s:%d:\n"
>> diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c
>> index db249fe60..dda5a57b7 100644
>> --- a/lib/librte_ip_frag/rte_ipv6_reassembly.c
>> +++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c
>> @@ -186,7 +186,7 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,


>>       /* process the fragmented packet. */
>> -     mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len,
>> +     mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len,
>>                       MORE_FRAGS(frag_hdr->frag_data));
>>       ip_frag_inuse(tbl, fp);

>> --
>> 2.16.1.windows.1




-- 
Alex

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-dev] [PATCH 2/2] librte_ip_frag: add mbuf counter
       [not found] <20180516110425.D01821B219@dpdk.org>
@ 2018-05-31 13:19 ` Ananyev, Konstantin
  2018-05-31 14:29   ` Alex Kiselev
  0 siblings, 1 reply; 3+ messages in thread
From: Ananyev, Konstantin @ 2018-05-31 13:19 UTC (permalink / raw)
  To: Alex Kiselev, dev, Burakov, Anatoly



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Alex Kiselev
> Sent: Wednesday, May 16, 2018 12:04 PM
> To: dev@dpdk.org; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH 2/2] librte_ip_frag: add mbuf counter
> 
> add new function rte_frag_table_mbuf_count() that returns
> number of mbufs holded in the fragmentation table.
> 
> There might be situations (kind of attack when a lot of
> fragmented packets are sent to a dpdk application in order
> to flood the fragmentation table) when no additional mbufs
> must be added to the fragmentations table since it already
> contains to many of them. Currently there is no way to
> determine the number of mbufs holded int the fragmentation
> table. This patch allows to keep track of the number of mbufs
> holded in the fragmentation table.
> 
> Signed-off-by: Alex Kiselev <alex@therouter.net>
> ---
>  lib/librte_ip_frag/ip_frag_common.h        | 12 +++++++-----
>  lib/librte_ip_frag/ip_frag_internal.c      | 15 +++++++++------
>  lib/librte_ip_frag/rte_ip_frag.h           | 16 ++++++++++++++++
>  lib/librte_ip_frag/rte_ip_frag_common.c    |  1 +
>  lib/librte_ip_frag/rte_ip_frag_version.map |  1 +
>  lib/librte_ip_frag/rte_ipv4_reassembly.c   |  2 +-
>  lib/librte_ip_frag/rte_ipv6_reassembly.c   |  2 +-
>  7 files changed, 36 insertions(+), 13 deletions(-)

Do we really need it?
It's quite significant code changes and the advantage looks quite small to me...
We already have use_entries, right?
That can be used to get some estimation for a number of mbufs in the table.
Konstantin

> 
> diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h
> index 0fdcc7d0f..d04e69de6 100644
> --- a/lib/librte_ip_frag/ip_frag_common.h
> +++ b/lib/librte_ip_frag/ip_frag_common.h
> @@ -32,9 +32,9 @@
>  #endif /* IP_FRAG_TBL_STAT */
> 
>  /* internal functions declarations */
> -struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp,
> -		struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
> -		uint16_t ofs, uint16_t len, uint16_t more_frags);
> +struct rte_mbuf * ip_frag_process(struct rte_ip_frag_tbl *tbl,
> +	struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
> +	struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags);
> 
>  struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl,
>  		struct rte_ip_frag_death_row *dr,
> @@ -91,7 +91,8 @@ ip_frag_key_cmp(const struct ip_frag_key * k1, const struct ip_frag_key * k2)
> 
>  /* put fragment on death row */
>  static inline void
> -ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
> +ip_frag_free(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp,
> +	struct rte_ip_frag_death_row *dr)
>  {
>  	uint32_t i, k;
> 
> @@ -100,6 +101,7 @@ ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
>  		if (fp->frags[i].mb != NULL) {
>  			dr->row[k++] = fp->frags[i].mb;
>  			fp->frags[i].mb = NULL;
> +			tbl->nb_mbufs --;
>  		}
>  	}
> 
> @@ -160,7 +162,7 @@ static inline void
>  ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
>  	struct ip_frag_pkt *fp)
>  {
> -	ip_frag_free(fp, dr);
> +	ip_frag_free(tbl, fp, dr);
>  	ip_frag_key_invalidate(&fp->key);
>  	TAILQ_REMOVE(&tbl->lru, fp, lru);
>  	tbl->use_entries--;
> diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/ip_frag_internal.c
> index 97470a872..eea871b7e 100644
> --- a/lib/librte_ip_frag/ip_frag_internal.c
> +++ b/lib/librte_ip_frag/ip_frag_internal.c
> @@ -29,14 +29,13 @@ static inline void
>  ip_frag_tbl_reuse(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
>  	struct ip_frag_pkt *fp, uint64_t tms)
>  {
> -	ip_frag_free(fp, dr);
> +	ip_frag_free(tbl, fp, dr);
>  	ip_frag_reset(fp, tms);
>  	TAILQ_REMOVE(&tbl->lru, fp, lru);
>  	TAILQ_INSERT_TAIL(&tbl->lru, fp, lru);
>  	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, reuse_num, 1);
>  }
> 
> -
>  static inline void
>  ipv4_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
>  {
> @@ -88,8 +87,9 @@ ipv6_frag_hash(const struct ip_frag_key *key, uint32_t *v1, uint32_t *v2)
>  }
> 
>  struct rte_mbuf *
> -ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
> -	struct rte_mbuf *mb, uint16_t ofs, uint16_t len, uint16_t more_frags)
> +ip_frag_process(struct rte_ip_frag_tbl *tbl, struct ip_frag_pkt *fp,
> +	struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb, uint16_t ofs,
> +	uint16_t len, uint16_t more_frags)
>  {
>  	uint32_t idx;
> 
> @@ -147,7 +147,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>  				fp->frags[IP_LAST_FRAG_IDX].len);
> 
>  		/* free all fragments, invalidate the entry. */
> -		ip_frag_free(fp, dr);
> +		ip_frag_free(tbl, fp, dr);
>  		ip_frag_key_invalidate(&fp->key);
>  		IP_FRAG_MBUF2DR(dr, mb);
> 
> @@ -157,6 +157,7 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>  	fp->frags[idx].ofs = ofs;
>  	fp->frags[idx].len = len;
>  	fp->frags[idx].mb = mb;
> +	tbl->nb_mbufs++;
> 
>  	mb = NULL;
> 
> @@ -205,8 +206,10 @@ ip_frag_process(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr,
>  				fp->frags[IP_LAST_FRAG_IDX].len);
> 
>  		/* free associated resources. */
> -		ip_frag_free(fp, dr);
> +		ip_frag_free(tbl, fp, dr);
>  	}
> +	else
> +		tbl->nb_mbufs -= fp->last_idx;
> 
>  	/* we are done with that entry, invalidate it. */
>  	ip_frag_key_invalidate(&fp->key);
> diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
> index 3c694df92..4aba8a064 100644
> --- a/lib/librte_ip_frag/rte_ip_frag.h
> +++ b/lib/librte_ip_frag/rte_ip_frag.h
> @@ -96,6 +96,7 @@ struct rte_ip_frag_tbl {
>  	uint32_t             bucket_entries;  /**< hash associativity. */
>  	uint32_t             nb_entries;      /**< total size of the table. */
>  	uint32_t             nb_buckets;      /**< num of associativity lines. */
> +	uint32_t             nb_mbufs;        /**< num of mbufs holded in the tbl. */
>  	struct ip_frag_pkt *last;         /**< last used entry. */
>  	struct ip_pkt_list lru;           /**< LRU list for table entries. */
>  	struct ip_frag_tbl_stat stat;     /**< statistics counters. */
> @@ -328,6 +329,21 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
>  void
>  rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
> 
> +/**
> + * Number of mbufs holded in the fragmentation table.
> + *
> + * @param tbl
> + *   Fragmentation table
> + *
> + * @return
> + *   Number of mbufs holded in the fragmentation table.
> + */
> +static inline uint32_t __rte_experimental
> +rte_frag_table_mbuf_count(const struct rte_ip_frag_tbl *tbl)
> +{
> +	return tbl->nb_mbufs;
> +}
> +
>  /**
>   * Delete expired fragments
>   *
> diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag/rte_ip_frag_common.c
> index f62b5d169..6e7aaac45 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_common.c
> +++ b/lib/librte_ip_frag/rte_ip_frag_common.c
> @@ -75,6 +75,7 @@ rte_ip_frag_table_create(uint32_t bucket_num, uint32_t bucket_entries,
>  	tbl->nb_buckets = bucket_num;
>  	tbl->bucket_entries = bucket_entries;
>  	tbl->entry_mask = (tbl->nb_entries - 1) & ~(tbl->bucket_entries  - 1);
> +	tbl->nb_mbufs = 0;
> 
>  	TAILQ_INIT(&(tbl->lru));
>  	return tbl;
> diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
> index d40d5515f..f4700f460 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_version.map
> +++ b/lib/librte_ip_frag/rte_ip_frag_version.map
> @@ -23,4 +23,5 @@ EXPERIMENTAL {
>  	global:
> 
>  	rte_frag_table_del_expired_entries;
> +	rte_frag_table_mbuf_count;
>  };
> diff --git a/lib/librte_ip_frag/rte_ipv4_reassembly.c b/lib/librte_ip_frag/rte_ipv4_reassembly.c
> index 4956b99ea..fbdfd860a 100644
> --- a/lib/librte_ip_frag/rte_ipv4_reassembly.c
> +++ b/lib/librte_ip_frag/rte_ipv4_reassembly.c
> @@ -146,7 +146,7 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,
> 
> 
>  	/* process the fragmented packet. */
> -	mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len, ip_flag);
> +	mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len, ip_flag);
>  	ip_frag_inuse(tbl, fp);
> 
>  	IP_FRAG_LOG(DEBUG, "%s:%d:\n"
> diff --git a/lib/librte_ip_frag/rte_ipv6_reassembly.c b/lib/librte_ip_frag/rte_ipv6_reassembly.c
> index db249fe60..dda5a57b7 100644
> --- a/lib/librte_ip_frag/rte_ipv6_reassembly.c
> +++ b/lib/librte_ip_frag/rte_ipv6_reassembly.c
> @@ -186,7 +186,7 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl *tbl,
> 
> 
>  	/* process the fragmented packet. */
> -	mb = ip_frag_process(fp, dr, mb, ip_ofs, ip_len,
> +	mb = ip_frag_process(tbl, fp, dr, mb, ip_ofs, ip_len,
>  			MORE_FRAGS(frag_hdr->frag_data));
>  	ip_frag_inuse(tbl, fp);
> 
> --
> 2.16.1.windows.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-05-31 14:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-16 11:04 [dpdk-dev] [PATCH 2/2] librte_ip_frag: add mbuf counter Alex Kiselev
     [not found] <20180516110425.D01821B219@dpdk.org>
2018-05-31 13:19 ` Ananyev, Konstantin
2018-05-31 14:29   ` Alex Kiselev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).