ip_frag: free mbufs on reassembly table destroy

The rte_ip_frag_table_destroy procedure simply releases the memory for the
table without freeing the packet buffers that may be referenced in the hash
table for in-flight or incomplete packet reassembly operations.  To prevent
leaked mbufs go through the list of fragments and free each one
individually.

Fixes: 416707812c03 ("ip_frag: refactor reassembly code into a proper library")
Cc: stable@dpdk.org

Reported-by: Matt Peters <matt.peters@windriver.com>
Signed-off-by: Allain Legacy <allain.legacy@windriver.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
This commit is contained in:
Dahir Osman 2017-06-05 11:49:01 -04:00 committed by Thomas Monjalon
parent 13916d5e7c
commit 95908f5239
4 changed files with 42 additions and 5 deletions

View File

@ -130,6 +130,26 @@ ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
dr->cnt = k;
}
/* delete fragment's mbufs immediately instead of using death row */
static inline void
ip_frag_free_immediate(struct ip_frag_pkt *fp)
{
uint32_t i;
for (i = 0; i < fp->last_idx; i++) {
if (fp->frags[i].mb != NULL) {
IP_FRAG_LOG(DEBUG, "%s:%d\n"
"mbuf: %p, tms: %" PRIu64", key: <%" PRIx64 ", %#x>\n",
__func__, __LINE__, fp->frags[i].mb, fp->start,
fp->key.src_dst[0], fp->key.id);
rte_pktmbuf_free(fp->frags[i].mb);
fp->frags[i].mb = NULL;
}
}
fp->last_idx = 0;
}
/* if key is empty, mark key as in use */
static inline void
ip_frag_inuse(struct rte_ip_frag_tbl *tbl, const struct ip_frag_pkt *fp)

View File

@ -180,11 +180,8 @@ struct rte_ip_frag_tbl * rte_ip_frag_table_create(uint32_t bucket_num,
* @param tbl
* Fragmentation table to free.
*/
static inline void
rte_ip_frag_table_destroy(struct rte_ip_frag_tbl *tbl)
{
rte_free(tbl);
}
void
rte_ip_frag_table_destroy(struct rte_ip_frag_tbl *tbl);
/**
* This function implements the fragmentation of IPv6 packets.

View File

@ -109,6 +109,19 @@ rte_ip_frag_table_create(uint32_t bucket_num, uint32_t bucket_entries,
return tbl;
}
/* delete fragmentation table */
void
rte_ip_frag_table_destroy(struct rte_ip_frag_tbl *tbl)
{
struct ip_frag_pkt *fp;
TAILQ_FOREACH(fp, &tbl->lru, lru) {
ip_frag_free_immediate(fp);
}
rte_free(tbl);
}
/* dump frag table statistics to file */
void
rte_ip_frag_table_statistics_dump(FILE *f, const struct rte_ip_frag_tbl *tbl)

View File

@ -11,3 +11,10 @@ DPDK_2.0 {
local: *;
};
DPDK_17.08 {
global:
rte_ip_frag_table_destroy;
} DPDK_2.0;