1
2
3
4
5#ifndef _IP_FRAG_COMMON_H_
6#define _IP_FRAG_COMMON_H_
7
8#include "rte_ip_frag.h"
9
10
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
16
17#define IPV4_KEYLEN 1
18#define IPV6_KEYLEN 4
19
20
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
33
34
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
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
55
56
57
58static inline int
59ip_frag_key_is_empty(const struct ip_frag_key * key)
60{
61 return (key->key_len == 0);
62}
63
64
65static inline void
66ip_frag_key_invalidate(struct ip_frag_key * key)
67{
68 key->key_len = 0;
69}
70
71
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
85
86
87
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
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
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
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
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
166