dpdk/lib/ip_frag/ip_frag_common.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2010-2014 Intel Corporation
   3 */
   4
   5#ifndef _IP_FRAG_COMMON_H_
   6#define _IP_FRAG_COMMON_H_
   7
   8#include "rte_ip_frag.h"
   9
  10/* logging macros. */
  11#ifdef RTE_LIBRTE_IP_FRAG_DEBUG
  12#define IP_FRAG_LOG(lvl, fmt, args...)  RTE_LOG(lvl, USER1, fmt, ##args)
  13#else
  14#define IP_FRAG_LOG(lvl, fmt, args...)  do {} while(0)
  15#endif /* IP_FRAG_DEBUG */
  16
  17#define IPV4_KEYLEN 1
  18#define IPV6_KEYLEN 4
  19
  20/* helper macros */
  21#define IP_FRAG_MBUF2DR(dr, mb) ((dr)->row[(dr)->cnt++] = (mb))
  22
  23#define IPv6_KEY_BYTES(key) \
  24        (key)[0], (key)[1], (key)[2], (key)[3]
  25#define IPv6_KEY_BYTES_FMT \
  26        "%08" PRIx64 "%08" PRIx64 "%08" PRIx64 "%08" PRIx64
  27
  28#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
  29#define IP_FRAG_TBL_STAT_UPDATE(s, f, v)        ((s)->f += (v))
  30#else
  31#define IP_FRAG_TBL_STAT_UPDATE(s, f, v)        do {} while (0)
  32#endif /* IP_FRAG_TBL_STAT */
  33
  34/* internal functions declarations */
  35struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp,
  36                struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
  37                uint16_t ofs, uint16_t len, uint16_t more_frags);
  38
  39struct ip_frag_pkt * ip_frag_find(struct rte_ip_frag_tbl *tbl,
  40                struct rte_ip_frag_death_row *dr,
  41                const struct ip_frag_key *key, uint64_t tms);
  42
  43struct ip_frag_pkt * ip_frag_lookup(struct rte_ip_frag_tbl *tbl,
  44        const struct ip_frag_key *key, uint64_t tms,
  45        struct ip_frag_pkt **free, struct ip_frag_pkt **stale);
  46
  47/* these functions need to be declared here as ip_frag_process relies on them */
  48struct rte_mbuf *ipv4_frag_reassemble(struct ip_frag_pkt *fp);
  49struct rte_mbuf *ipv6_frag_reassemble(struct ip_frag_pkt *fp);
  50
  51
  52
  53/*
  54 * misc frag key functions
  55 */
  56
  57/* check if key is empty */
  58static inline int
  59ip_frag_key_is_empty(const struct ip_frag_key * key)
  60{
  61        return (key->key_len == 0);
  62}
  63
  64/* invalidate the key */
  65static inline void
  66ip_frag_key_invalidate(struct ip_frag_key * key)
  67{
  68        key->key_len = 0;
  69}
  70
  71/* compare two keys */
  72static inline uint64_t
  73ip_frag_key_cmp(const struct ip_frag_key * k1, const struct ip_frag_key * k2)
  74{
  75        uint32_t i;
  76        uint64_t val;
  77        val = k1->id_key_len ^ k2->id_key_len;
  78        for (i = 0; i < k1->key_len; i++)
  79                val |= k1->src_dst[i] ^ k2->src_dst[i];
  80        return val;
  81}
  82
  83/*
  84 * misc fragment functions
  85 */
  86
  87/* put fragment on death row */
  88static inline void
  89ip_frag_free(struct ip_frag_pkt *fp, struct rte_ip_frag_death_row *dr)
  90{
  91        uint32_t i, k;
  92
  93        k = dr->cnt;
  94        for (i = 0; i != fp->last_idx; i++) {
  95                if (fp->frags[i].mb != NULL) {
  96                        dr->row[k++] = fp->frags[i].mb;
  97                        fp->frags[i].mb = NULL;
  98                }
  99        }
 100
 101        fp->last_idx = 0;
 102        dr->cnt = k;
 103}
 104
 105/* delete fragment's mbufs immediately instead of using death row */
 106static inline void
 107ip_frag_free_immediate(struct ip_frag_pkt *fp)
 108{
 109        uint32_t i;
 110
 111        for (i = 0; i < fp->last_idx; i++) {
 112                if (fp->frags[i].mb != NULL) {
 113                        IP_FRAG_LOG(DEBUG, "%s:%d\n"
 114                            "mbuf: %p, tms: %" PRIu64", key: <%" PRIx64 ", %#x>\n",
 115                            __func__, __LINE__, fp->frags[i].mb, fp->start,
 116                            fp->key.src_dst[0], fp->key.id);
 117                        rte_pktmbuf_free(fp->frags[i].mb);
 118                        fp->frags[i].mb = NULL;
 119                }
 120        }
 121
 122        fp->last_idx = 0;
 123}
 124
 125/* if key is empty, mark key as in use */
 126static inline void
 127ip_frag_inuse(struct rte_ip_frag_tbl *tbl, const struct  ip_frag_pkt *fp)
 128{
 129        if (ip_frag_key_is_empty(&fp->key)) {
 130                TAILQ_REMOVE(&tbl->lru, fp, lru);
 131                tbl->use_entries--;
 132        }
 133}
 134
 135/* reset the fragment */
 136static inline void
 137ip_frag_reset(struct ip_frag_pkt *fp, uint64_t tms)
 138{
 139        static const struct ip_frag zero_frag = {
 140                .ofs = 0,
 141                .len = 0,
 142                .mb = NULL,
 143        };
 144
 145        fp->start = tms;
 146        fp->total_size = UINT32_MAX;
 147        fp->frag_size = 0;
 148        fp->last_idx = IP_MIN_FRAG_NUM;
 149        fp->frags[IP_LAST_FRAG_IDX] = zero_frag;
 150        fp->frags[IP_FIRST_FRAG_IDX] = zero_frag;
 151}
 152
 153/* local frag table helper functions */
 154static inline void
 155ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *dr,
 156        struct ip_frag_pkt *fp)
 157{
 158        ip_frag_free(fp, dr);
 159        ip_frag_key_invalidate(&fp->key);
 160        TAILQ_REMOVE(&tbl->lru, fp, lru);
 161        tbl->use_entries--;
 162        IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1);
 163}
 164
 165#endif /* _IP_FRAG_COMMON_H_ */
 166