[dpdk-dev] [PATCH] ip_frag: add function rte_ip_frag_sweep_table()

Ananyev, Konstantin konstantin.ananyev at intel.com
Fri Jun 29 18:47:10 CEST 2018


Hi

> 
> Function rte_ip_frag_sweep_table() enables callers to
> incrementally sweep IP frament tables for incomplete, expired fragments.
> 
> rte_ip_frag_sweep_table() is needed to identify
> never-to-be-completed fragments during DDoS attacks.

There is a patch from Alex Kiselev:
http://patches.dpdk.org/patch/40601/
doing the same thing,  and I think in a better way
(as it goes through LRU list, not entire table).
So I'd suggest we go ahead with Alex one.
Thanks
Konstantin

> 
> Signed-off-by: Qiaobin Fu <qiaobinf at bu.edu>
> Reviewed-by: Cody Doucette <doucette at bu.edu>
> Reviewed-by: Michel Machado <michel at digirati.com.br>
> ---
>  lib/librte_ip_frag/ip_frag_common.h     | 18 +++++++++++++++++
>  lib/librte_ip_frag/ip_frag_internal.c   | 18 -----------------
>  lib/librte_ip_frag/rte_ip_frag.h        | 17 ++++++++++++++++
>  lib/librte_ip_frag/rte_ip_frag_common.c | 26 +++++++++++++++++++++++++
>  4 files changed, 61 insertions(+), 18 deletions(-)
> 
> diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_frag_common.h
> index 197acf8d8..ef869182d 100644
> --- a/lib/librte_ip_frag/ip_frag_common.h
> +++ b/lib/librte_ip_frag/ip_frag_common.h
> @@ -25,6 +25,12 @@
>  #define IPv6_KEY_BYTES_FMT \
>  	"%08" PRIx64 "%08" PRIx64 "%08" PRIx64 "%08" PRIx64
> 
> +#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> +#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	((s)->f += (v))
> +#else
> +#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	do {} while (0)
> +#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,
> @@ -149,4 +155,16 @@ ip_frag_reset(struct ip_frag_pkt *fp, uint64_t tms)
>  	fp->frags[IP_FIRST_FRAG_IDX] = zero_frag;
>  }
> 
> +/* frag table helper functions */
> +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_key_invalidate(&fp->key);
> +	TAILQ_REMOVE(&tbl->lru, fp, lru);
> +	tbl->use_entries--;
> +	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1);
> +}
> +
>  #endif /* _IP_FRAG_COMMON_H_ */
> diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/ip_frag_internal.c
> index 2560c7713..97470a872 100644
> --- a/lib/librte_ip_frag/ip_frag_internal.c
> +++ b/lib/librte_ip_frag/ip_frag_internal.c
> @@ -14,24 +14,6 @@
>  #define	IP_FRAG_TBL_POS(tbl, sig)	\
>  	((tbl)->pkt + ((sig) & (tbl)->entry_mask))
> 
> -#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> -#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	((s)->f += (v))
> -#else
> -#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	do {} while (0)
> -#endif /* IP_FRAG_TBL_STAT */
> -
> -/* local frag table helper functions */
> -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_key_invalidate(&fp->key);
> -	TAILQ_REMOVE(&tbl->lru, fp, lru);
> -	tbl->use_entries--;
> -	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1);
> -}
> -
>  static inline void
>  ip_frag_tbl_add(struct rte_ip_frag_tbl *tbl,  struct ip_frag_pkt *fp,
>  	const struct ip_frag_key *key, uint64_t tms)
> diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
> index b3f3f78df..79443096c 100644
> --- a/lib/librte_ip_frag/rte_ip_frag.h
> +++ b/lib/librte_ip_frag/rte_ip_frag.h
> @@ -146,6 +146,23 @@ struct rte_ip_frag_tbl * rte_ip_frag_table_create(uint32_t bucket_num,
>  		uint32_t bucket_entries,  uint32_t max_entries,
>  		uint64_t max_cycles, int socket_id);
> 
> +/**
> + * Sweep the IP fragmentation table for expired segments.
> + *
> + * @param tbl
> + *   Fragmentation table to sweep.
> + * @param dr
> + *   Death row to free buffers to
> + * @param next
> + *   Pointer to the bucket iterator.
> + *   Should be 0 to start sweeping the fragmentation table.
> + *   Bucket iterator is incremented after each call of this function.
> + * @return
> + *   0 if successful. -EINVAL if the parameters are invalid.
> + */
> +int rte_ip_frag_sweep_table(struct rte_ip_frag_tbl *tbl,
> +	struct rte_ip_frag_death_row *dr, uint32_t *next);
> +
>  /**
>   * Free allocated IP fragmentation table.
>   *
> diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag/rte_ip_frag_common.c
> index 659a17951..53325ddae 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_common.c
> +++ b/lib/librte_ip_frag/rte_ip_frag_common.c
> @@ -7,6 +7,7 @@
> 
>  #include <rte_memory.h>
>  #include <rte_log.h>
> +#include <rte_cycles.h>
> 
>  #include "ip_frag_common.h"
> 
> @@ -93,6 +94,31 @@ rte_ip_frag_table_destroy(struct rte_ip_frag_tbl *tbl)
>  	rte_free(tbl);
>  }
> 
> +/* Sweep the IP fragmentation table. */
> +int
> +rte_ip_frag_sweep_table(struct rte_ip_frag_tbl *tbl,
> +	struct rte_ip_frag_death_row *dr, uint32_t *next)
> +{
> +	uint32_t i;
> +	uint64_t cur_tsc = rte_rdtsc();
> +	struct ip_frag_pkt *pkt;
> +
> +	if (tbl == NULL || dr == NULL || next == NULL ||
> +			(*next * tbl->bucket_entries >= tbl->nb_entries))
> +		return -EINVAL;
> +
> +	pkt = tbl->pkt + *next * tbl->bucket_entries;
> +	for (i = 0; i < tbl->bucket_entries; i++) {
> +		if (tbl->max_cycles + pkt[i].start < cur_tsc)
> +			ip_frag_tbl_del(tbl, dr, pkt + i);
> +	}
> +
> +	*next = (*next + 1) * tbl->bucket_entries >= tbl->nb_entries ?
> +		0 : *next + 1;
> +
> +	return 0;
> +}
> +
>  /* dump frag table statistics to file */
>  void
>  rte_ip_frag_table_statistics_dump(FILE *f, const struct rte_ip_frag_tbl *tbl)
> --
> 2.17.1



More information about the dev mailing list