stream_table.h revision aa97dd1c
1/*
2 * Copyright (c) 2016  Intel Corporation.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef _STREAM_TABLE_H_
17#define _STREAM_TABLE_H_
18
19#include <rte_hash.h>
20#include "tcp_misc.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26/* current stbl entry contains packet. */
27#define	STE_PKT	1
28
29struct stbl_entry {
30	void *data;
31};
32
33struct shtbl {
34	uint32_t nb_ent;  /* max number of entries in the table. */
35	rte_spinlock_t l; /* lock to protect the hash table */
36	struct rte_hash *t;
37	struct stbl_entry *ent;
38} __rte_cache_aligned;
39
40struct stbl {
41	struct shtbl ht[TLE_VNUM];
42};
43
44struct stbl4_key {
45	union l4_ports port;
46	union ipv4_addrs addr;
47} __attribute__((__packed__));
48
49struct stbl6_key {
50	union l4_ports port;
51	union ipv6_addrs addr;
52} __attribute__((__packed__));
53
54struct stbl_key {
55	union l4_ports port;
56	union {
57		union ipv4_addrs addr4;
58		union ipv6_addrs addr6;
59	};
60} __attribute__((__packed__));
61
62extern void stbl_fini(struct stbl *st);
63
64extern int stbl_init(struct stbl *st, uint32_t num, int32_t socket);
65
66static inline void
67stbl_pkt_fill_key(struct stbl_key *k, const union pkt_info *pi, uint32_t type)
68{
69	static const struct stbl_key zero = {
70		.port.raw = 0,
71	};
72
73	k->port = pi->port;
74	if (type == TLE_V4)
75		k->addr4 = pi->addr4;
76	else if (type == TLE_V6)
77		k->addr6 = *pi->addr6;
78	else
79		*k = zero;
80}
81
82static inline void
83stbl_lock(struct stbl *st, uint32_t type)
84{
85	rte_spinlock_lock(&st->ht[type].l);
86}
87
88static inline void
89stbl_unlock(struct stbl *st, uint32_t type)
90{
91	rte_spinlock_unlock(&st->ht[type].l);
92}
93
94static inline struct stbl_entry *
95stbl_add_entry(struct stbl *st, const union pkt_info *pi)
96{
97	int32_t rc;
98	uint32_t type;
99	struct shtbl *ht;
100	struct stbl_key k;
101
102	type = pi->tf.type;
103	stbl_pkt_fill_key(&k, pi, type);
104	ht = st->ht + type;
105
106	rc = rte_hash_add_key(ht->t, &k);
107	if ((uint32_t)rc >= ht->nb_ent)
108		return NULL;
109	return ht->ent + rc;
110}
111
112static inline struct stbl_entry *
113stbl_add_pkt(struct stbl *st, const union pkt_info *pi, const void *pkt)
114{
115	struct stbl_entry *se;
116
117	se = stbl_add_entry(st, pi);
118	if (se != NULL)
119		se->data = (void *)((uintptr_t)pkt | STE_PKT);
120	return se;
121}
122
123static inline struct stbl_entry *
124stbl_find_entry(struct stbl *st, const union pkt_info *pi)
125{
126	int32_t rc;
127	uint32_t type;
128	struct shtbl *ht;
129	struct stbl_key k;
130
131	type = pi->tf.type;
132	stbl_pkt_fill_key(&k, pi, type);
133	ht = st->ht + type;
134
135	rc = rte_hash_lookup(ht->t, &k);
136	if ((uint32_t)rc >= ht->nb_ent)
137		return NULL;
138	return ht->ent + rc;
139}
140
141static inline int
142stbl_data_pkt(const void *p)
143{
144	return ((uintptr_t)p & STE_PKT);
145}
146
147static inline void *
148stbl_get_pkt(const struct stbl_entry *se)
149{
150	return (void *)((uintptr_t)se->data ^ STE_PKT);
151}
152
153static inline void *
154stbl_find_data(struct stbl *st, const union pkt_info *pi)
155{
156	struct stbl_entry *ent;
157
158	ent = stbl_find_entry(st, pi);
159	return (ent == NULL) ? NULL : ent->data;
160}
161
162static inline void
163stbl_del_pkt(struct stbl *st, struct stbl_entry *se, const union pkt_info *pi)
164{
165	uint32_t type;
166	struct stbl_key k;
167
168	se->data = NULL;
169
170	type = pi->tf.type;
171	stbl_pkt_fill_key(&k, pi, type);
172	rte_hash_del_key(st->ht[type].t, &k);
173}
174
175static inline void
176stbl_del_pkt_lock(struct stbl *st, struct stbl_entry *se,
177	const union pkt_info *pi)
178{
179	uint32_t type;
180	struct stbl_key k;
181
182	se->data = NULL;
183
184	type = pi->tf.type;
185	stbl_pkt_fill_key(&k, pi, type);
186	stbl_lock(st, type);
187	rte_hash_del_key(st->ht[type].t, &k);
188	stbl_unlock(st, type);
189}
190
191#include "tcp_stream.h"
192
193static inline void
194stbl_stream_fill_key(struct stbl_key *k, const struct tle_stream *s,
195	uint32_t type)
196{
197	static const struct stbl_key zero = {
198		.port.raw = 0,
199	};
200
201	k->port = s->port;
202	if (type == TLE_V4)
203		k->addr4 = s->ipv4.addr;
204	else if (type == TLE_V6)
205		k->addr6 = s->ipv6.addr;
206	else
207		*k = zero;
208}
209
210static inline struct stbl_entry *
211stbl_add_stream_lock(struct stbl *st, const struct tle_tcp_stream *s)
212{
213	uint32_t type;
214	struct stbl_key k;
215	struct stbl_entry *se;
216	struct shtbl *ht;
217	int32_t rc;
218
219	type = s->s.type;
220	stbl_stream_fill_key(&k, &s->s, type);
221	ht = st->ht + type;
222
223	stbl_lock(st, type);
224	rc = rte_hash_add_key(ht->t, &k);
225	stbl_unlock(st, type);
226
227	if ((uint32_t)rc >= ht->nb_ent)
228		return NULL;
229
230	se = ht->ent + rc;
231	if (se != NULL)
232		se->data = (void *)(uintptr_t)s;
233
234	return se;
235}
236
237static inline void
238stbl_del_stream_lock(struct stbl *st, struct stbl_entry *se,
239	const struct tle_tcp_stream *s)
240{
241	uint32_t type;
242	struct stbl_key k;
243
244	if (se == NULL)
245		return;
246
247	se->data = NULL;
248
249	type = s->s.type;
250	stbl_stream_fill_key(&k, &s->s, type);
251	stbl_lock(st, type);
252	rte_hash_del_key(st->ht[type].t, &k);
253	stbl_unlock(st, type);
254}
255
256#ifdef __cplusplus
257}
258#endif
259
260#endif /* _STREAM_TABLE_H_ */
261