From patchwork Mon Jun 4 10:13:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Kiselev X-Patchwork-Id: 40602 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 64FD85587; Mon, 4 Jun 2018 12:13:23 +0200 (CEST) Received: from relay-out5.mail.masterhost.ru (relay-out5.mail.masterhost.ru [83.222.12.15]) by dpdk.org (Postfix) with ESMTP id 220BF5A3E for ; Mon, 4 Jun 2018 12:13:22 +0200 (CEST) Received: from [37.139.80.50] (helo=h5.therouter.net) by relay5.mail.masterhost.ru with esmtpa envelope from authenticated with alex@therouter.net message id 1fPmUI-0000qd-Su; Mon, 04 Jun 2018 13:13:20 +0300 Received: by h5.therouter.net (sSMTP sendmail emulation); Mon, 04 Jun 2018 13:13:18 +0300 Date: Mon, 04 Jun 2018 13:13:18 +0300 To: "Ananyev, Konstantin" , "dev@dpdk.org" , "Burakov, Anatoly" From: Alex Kiselev X-KLMS-Rule-ID: 1 X-KLMS-Message-Action: clean X-KLMS-AntiSpam-Lua-Profiles: 125489 [Jun 04 2018] X-KLMS-AntiSpam-Version: 5.8.1.0 X-KLMS-AntiSpam-Envelope-From: alex@therouter.net X-KLMS-AntiSpam-Rate: 0 X-KLMS-AntiSpam-Status: not_detected X-KLMS-AntiSpam-Method: none X-KLMS-AntiSpam-Info: LuaCore: 134 134 bf736bd29cf824f413cc89f4fc133294deb98473, {rep_avail}, {msgid_missed_heavy}, DmarcAF: none X-MS-Exchange-Organization-SCL: -1 X-KLMS-AntiSpam-Interceptor-Info: scan successful X-KLMS-AntiPhishing: not scanned, disabled by settings X-KLMS-AntiVirus: Kaspersky Security for Linux Mail Server, version 8.0.2.16, not scanned, license restriction Subject: [dpdk-dev] [PATCH v2 2/2] librte_ip_frag: add mbuf counter X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Message-Id: <20180604101323.64FD85587@dpdk.org> 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 --- lib/librte_ip_frag/ip_frag_common.h | 16 +++++++++------- lib/librte_ip_frag/ip_frag_internal.c | 16 +++++++++------- lib/librte_ip_frag/rte_ip_frag.h | 18 +++++++++++++++++- 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, 39 insertions(+), 17 deletions(-) diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h index 0fdcc7d0f..9fe5c0559 100644 --- a/lib/librte_ip_frag/ip_frag_common.h +++ b/lib/librte_ip_frag/ip_frag_common.h @@ -32,15 +32,15 @@ #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 ip_frag_pkt *ip_frag_find(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr, const struct ip_frag_key *key, uint64_t tms); -struct ip_frag_pkt * ip_frag_lookup(struct rte_ip_frag_tbl *tbl, +struct ip_frag_pkt *ip_frag_lookup(struct rte_ip_frag_tbl *tbl, const struct ip_frag_key *key, uint64_t tms, struct ip_frag_pkt **free, struct ip_frag_pkt **stale); @@ -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..4c47d3fb4 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,9 @@ 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 7f425f610..623934d87 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. */ @@ -329,8 +330,23 @@ void rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl); /** - * Delete expired fragments + * 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 + * * @param tbl * Table to delete expired fragments from * @param dr diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag/rte_ip_frag_common.c index a23f6f24f..46c2df84a 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);