1aa97dd1cSKonstantin Ananyev/*
27e18fa1bSKonstantin Ananyev * Copyright (c) 2016-2017  Intel Corporation.
3aa97dd1cSKonstantin Ananyev * Licensed under the Apache License, Version 2.0 (the "License");
4aa97dd1cSKonstantin Ananyev * you may not use this file except in compliance with the License.
5aa97dd1cSKonstantin Ananyev * You may obtain a copy of the License at:
6aa97dd1cSKonstantin Ananyev *
7aa97dd1cSKonstantin Ananyev *     http://www.apache.org/licenses/LICENSE-2.0
8aa97dd1cSKonstantin Ananyev *
9aa97dd1cSKonstantin Ananyev * Unless required by applicable law or agreed to in writing, software
10aa97dd1cSKonstantin Ananyev * distributed under the License is distributed on an "AS IS" BASIS,
11aa97dd1cSKonstantin Ananyev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12aa97dd1cSKonstantin Ananyev * See the License for the specific language governing permissions and
13aa97dd1cSKonstantin Ananyev * limitations under the License.
14aa97dd1cSKonstantin Ananyev */
15aa97dd1cSKonstantin Ananyev
16aa97dd1cSKonstantin Ananyev#ifndef _STREAM_TABLE_H_
17aa97dd1cSKonstantin Ananyev#define _STREAM_TABLE_H_
18aa97dd1cSKonstantin Ananyev
19aa97dd1cSKonstantin Ananyev#include <rte_hash.h>
20aa97dd1cSKonstantin Ananyev#include "tcp_misc.h"
21aa97dd1cSKonstantin Ananyev
22aa97dd1cSKonstantin Ananyev#ifdef __cplusplus
23aa97dd1cSKonstantin Ananyevextern "C" {
24aa97dd1cSKonstantin Ananyev#endif
25aa97dd1cSKonstantin Ananyev
26aa97dd1cSKonstantin Ananyevstruct stbl_entry {
27aa97dd1cSKonstantin Ananyev	void *data;
28aa97dd1cSKonstantin Ananyev};
29aa97dd1cSKonstantin Ananyev
30aa97dd1cSKonstantin Ananyevstruct shtbl {
31aa97dd1cSKonstantin Ananyev	uint32_t nb_ent;  /* max number of entries in the table. */
32aa97dd1cSKonstantin Ananyev	rte_spinlock_t l; /* lock to protect the hash table */
33aa97dd1cSKonstantin Ananyev	struct rte_hash *t;
34aa97dd1cSKonstantin Ananyev	struct stbl_entry *ent;
35aa97dd1cSKonstantin Ananyev} __rte_cache_aligned;
36aa97dd1cSKonstantin Ananyev
37aa97dd1cSKonstantin Ananyevstruct stbl {
38aa97dd1cSKonstantin Ananyev	struct shtbl ht[TLE_VNUM];
39aa97dd1cSKonstantin Ananyev};
40aa97dd1cSKonstantin Ananyev
41aa97dd1cSKonstantin Ananyevstruct stbl4_key {
42aa97dd1cSKonstantin Ananyev	union l4_ports port;
43aa97dd1cSKonstantin Ananyev	union ipv4_addrs addr;
44aa97dd1cSKonstantin Ananyev} __attribute__((__packed__));
45aa97dd1cSKonstantin Ananyev
46aa97dd1cSKonstantin Ananyevstruct stbl6_key {
47aa97dd1cSKonstantin Ananyev	union l4_ports port;
48aa97dd1cSKonstantin Ananyev	union ipv6_addrs addr;
49aa97dd1cSKonstantin Ananyev} __attribute__((__packed__));
50aa97dd1cSKonstantin Ananyev
51aa97dd1cSKonstantin Ananyevstruct stbl_key {
52aa97dd1cSKonstantin Ananyev	union l4_ports port;
53aa97dd1cSKonstantin Ananyev	union {
54aa97dd1cSKonstantin Ananyev		union ipv4_addrs addr4;
55aa97dd1cSKonstantin Ananyev		union ipv6_addrs addr6;
56aa97dd1cSKonstantin Ananyev	};
57aa97dd1cSKonstantin Ananyev} __attribute__((__packed__));
58aa97dd1cSKonstantin Ananyev
59aa97dd1cSKonstantin Ananyevextern void stbl_fini(struct stbl *st);
60aa97dd1cSKonstantin Ananyev
61aa97dd1cSKonstantin Ananyevextern int stbl_init(struct stbl *st, uint32_t num, int32_t socket);
62aa97dd1cSKonstantin Ananyev
63aa97dd1cSKonstantin Ananyevstatic inline void
64aa97dd1cSKonstantin Ananyevstbl_pkt_fill_key(struct stbl_key *k, const union pkt_info *pi, uint32_t type)
65aa97dd1cSKonstantin Ananyev{
66aa97dd1cSKonstantin Ananyev	static const struct stbl_key zero = {
67aa97dd1cSKonstantin Ananyev		.port.raw = 0,
68aa97dd1cSKonstantin Ananyev	};
69aa97dd1cSKonstantin Ananyev
70aa97dd1cSKonstantin Ananyev	k->port = pi->port;
71aa97dd1cSKonstantin Ananyev	if (type == TLE_V4)
72aa97dd1cSKonstantin Ananyev		k->addr4 = pi->addr4;
73aa97dd1cSKonstantin Ananyev	else if (type == TLE_V6)
74aa97dd1cSKonstantin Ananyev		k->addr6 = *pi->addr6;
75aa97dd1cSKonstantin Ananyev	else
76aa97dd1cSKonstantin Ananyev		*k = zero;
77aa97dd1cSKonstantin Ananyev}
78aa97dd1cSKonstantin Ananyev
79aa97dd1cSKonstantin Ananyevstatic inline void
80aa97dd1cSKonstantin Ananyevstbl_lock(struct stbl *st, uint32_t type)
81aa97dd1cSKonstantin Ananyev{
82aa97dd1cSKonstantin Ananyev	rte_spinlock_lock(&st->ht[type].l);
83aa97dd1cSKonstantin Ananyev}
84aa97dd1cSKonstantin Ananyev
85aa97dd1cSKonstantin Ananyevstatic inline void
86aa97dd1cSKonstantin Ananyevstbl_unlock(struct stbl *st, uint32_t type)
87aa97dd1cSKonstantin Ananyev{
88aa97dd1cSKonstantin Ananyev	rte_spinlock_unlock(&st->ht[type].l);
89aa97dd1cSKonstantin Ananyev}
90aa97dd1cSKonstantin Ananyev
91aa97dd1cSKonstantin Ananyevstatic inline struct stbl_entry *
92aa97dd1cSKonstantin Ananyevstbl_add_entry(struct stbl *st, const union pkt_info *pi)
93aa97dd1cSKonstantin Ananyev{
94aa97dd1cSKonstantin Ananyev	int32_t rc;
95aa97dd1cSKonstantin Ananyev	uint32_t type;
96aa97dd1cSKonstantin Ananyev	struct shtbl *ht;
97aa97dd1cSKonstantin Ananyev	struct stbl_key k;
98aa97dd1cSKonstantin Ananyev
99aa97dd1cSKonstantin Ananyev	type = pi->tf.type;
100aa97dd1cSKonstantin Ananyev	stbl_pkt_fill_key(&k, pi, type);
101aa97dd1cSKonstantin Ananyev	ht = st->ht + type;
102aa97dd1cSKonstantin Ananyev
103aa97dd1cSKonstantin Ananyev	rc = rte_hash_add_key(ht->t, &k);
104aa97dd1cSKonstantin Ananyev	if ((uint32_t)rc >= ht->nb_ent)
105aa97dd1cSKonstantin Ananyev		return NULL;
106aa97dd1cSKonstantin Ananyev	return ht->ent + rc;
107aa97dd1cSKonstantin Ananyev}
108aa97dd1cSKonstantin Ananyev
109aa97dd1cSKonstantin Ananyevstatic inline struct stbl_entry *
11021e7392fSKonstantin Ananyevstbl_add_stream(struct stbl *st, const union pkt_info *pi, const void *s)
111aa97dd1cSKonstantin Ananyev{
112aa97dd1cSKonstantin Ananyev	struct stbl_entry *se;
113aa97dd1cSKonstantin Ananyev
114aa97dd1cSKonstantin Ananyev	se = stbl_add_entry(st, pi);
115aa97dd1cSKonstantin Ananyev	if (se != NULL)
11621e7392fSKonstantin Ananyev		se->data = (void *)(uintptr_t)s;
117aa97dd1cSKonstantin Ananyev	return se;
118aa97dd1cSKonstantin Ananyev}
119aa97dd1cSKonstantin Ananyev
120aa97dd1cSKonstantin Ananyevstatic inline struct stbl_entry *
121aa97dd1cSKonstantin Ananyevstbl_find_entry(struct stbl *st, const union pkt_info *pi)
122aa97dd1cSKonstantin Ananyev{
123aa97dd1cSKonstantin Ananyev	int32_t rc;
124aa97dd1cSKonstantin Ananyev	uint32_t type;
125aa97dd1cSKonstantin Ananyev	struct shtbl *ht;
126aa97dd1cSKonstantin Ananyev	struct stbl_key k;
127aa97dd1cSKonstantin Ananyev
128aa97dd1cSKonstantin Ananyev	type = pi->tf.type;
129aa97dd1cSKonstantin Ananyev	stbl_pkt_fill_key(&k, pi, type);
130aa97dd1cSKonstantin Ananyev	ht = st->ht + type;
131aa97dd1cSKonstantin Ananyev
132aa97dd1cSKonstantin Ananyev	rc = rte_hash_lookup(ht->t, &k);
133aa97dd1cSKonstantin Ananyev	if ((uint32_t)rc >= ht->nb_ent)
134aa97dd1cSKonstantin Ananyev		return NULL;
135aa97dd1cSKonstantin Ananyev	return ht->ent + rc;
136aa97dd1cSKonstantin Ananyev}
137aa97dd1cSKonstantin Ananyev
138aa97dd1cSKonstantin Ananyevstatic inline void *
139aa97dd1cSKonstantin Ananyevstbl_find_data(struct stbl *st, const union pkt_info *pi)
140aa97dd1cSKonstantin Ananyev{
141aa97dd1cSKonstantin Ananyev	struct stbl_entry *ent;
142aa97dd1cSKonstantin Ananyev
143aa97dd1cSKonstantin Ananyev	ent = stbl_find_entry(st, pi);
144aa97dd1cSKonstantin Ananyev	return (ent == NULL) ? NULL : ent->data;
145aa97dd1cSKonstantin Ananyev}
146aa97dd1cSKonstantin Ananyev
147aa97dd1cSKonstantin Ananyev#include "tcp_stream.h"
148aa97dd1cSKonstantin Ananyev
149aa97dd1cSKonstantin Ananyevstatic inline void
150aa97dd1cSKonstantin Ananyevstbl_stream_fill_key(struct stbl_key *k, const struct tle_stream *s,
151aa97dd1cSKonstantin Ananyev	uint32_t type)
152aa97dd1cSKonstantin Ananyev{
153aa97dd1cSKonstantin Ananyev	static const struct stbl_key zero = {
154aa97dd1cSKonstantin Ananyev		.port.raw = 0,
155aa97dd1cSKonstantin Ananyev	};
156aa97dd1cSKonstantin Ananyev
157aa97dd1cSKonstantin Ananyev	k->port = s->port;
158aa97dd1cSKonstantin Ananyev	if (type == TLE_V4)
159aa97dd1cSKonstantin Ananyev		k->addr4 = s->ipv4.addr;
160aa97dd1cSKonstantin Ananyev	else if (type == TLE_V6)
161aa97dd1cSKonstantin Ananyev		k->addr6 = s->ipv6.addr;
162aa97dd1cSKonstantin Ananyev	else
163aa97dd1cSKonstantin Ananyev		*k = zero;
164aa97dd1cSKonstantin Ananyev}
165aa97dd1cSKonstantin Ananyev
166aa97dd1cSKonstantin Ananyevstatic inline struct stbl_entry *
167aa97dd1cSKonstantin Ananyevstbl_add_stream_lock(struct stbl *st, const struct tle_tcp_stream *s)
168aa97dd1cSKonstantin Ananyev{
169aa97dd1cSKonstantin Ananyev	uint32_t type;
170aa97dd1cSKonstantin Ananyev	struct stbl_key k;
171aa97dd1cSKonstantin Ananyev	struct stbl_entry *se;
172aa97dd1cSKonstantin Ananyev	struct shtbl *ht;
173aa97dd1cSKonstantin Ananyev	int32_t rc;
174aa97dd1cSKonstantin Ananyev
175aa97dd1cSKonstantin Ananyev	type = s->s.type;
176aa97dd1cSKonstantin Ananyev	stbl_stream_fill_key(&k, &s->s, type);
177aa97dd1cSKonstantin Ananyev	ht = st->ht + type;
178aa97dd1cSKonstantin Ananyev
179aa97dd1cSKonstantin Ananyev	stbl_lock(st, type);
180aa97dd1cSKonstantin Ananyev	rc = rte_hash_add_key(ht->t, &k);
181aa97dd1cSKonstantin Ananyev	stbl_unlock(st, type);
182aa97dd1cSKonstantin Ananyev
183aa97dd1cSKonstantin Ananyev	if ((uint32_t)rc >= ht->nb_ent)
184aa97dd1cSKonstantin Ananyev		return NULL;
185aa97dd1cSKonstantin Ananyev
186aa97dd1cSKonstantin Ananyev	se = ht->ent + rc;
187aa97dd1cSKonstantin Ananyev	if (se != NULL)
188aa97dd1cSKonstantin Ananyev		se->data = (void *)(uintptr_t)s;
189aa97dd1cSKonstantin Ananyev
190aa97dd1cSKonstantin Ananyev	return se;
191aa97dd1cSKonstantin Ananyev}
192aa97dd1cSKonstantin Ananyev
193aa97dd1cSKonstantin Ananyevstatic inline void
1947e18fa1bSKonstantin Ananyevstbl_del_stream(struct stbl *st, struct stbl_entry *se,
1957e18fa1bSKonstantin Ananyev	const struct tle_tcp_stream *s, uint32_t lock)
196aa97dd1cSKonstantin Ananyev{
197aa97dd1cSKonstantin Ananyev	uint32_t type;
198aa97dd1cSKonstantin Ananyev	struct stbl_key k;
199aa97dd1cSKonstantin Ananyev
200aa97dd1cSKonstantin Ananyev	if (se == NULL)
201aa97dd1cSKonstantin Ananyev		return;
202aa97dd1cSKonstantin Ananyev
203aa97dd1cSKonstantin Ananyev	se->data = NULL;
204aa97dd1cSKonstantin Ananyev
205aa97dd1cSKonstantin Ananyev	type = s->s.type;
206aa97dd1cSKonstantin Ananyev	stbl_stream_fill_key(&k, &s->s, type);
2077e18fa1bSKonstantin Ananyev	if (lock != 0)
2087e18fa1bSKonstantin Ananyev		stbl_lock(st, type);
209aa97dd1cSKonstantin Ananyev	rte_hash_del_key(st->ht[type].t, &k);
2107e18fa1bSKonstantin Ananyev	if (lock != 0)
2117e18fa1bSKonstantin Ananyev		stbl_unlock(st, type);
212aa97dd1cSKonstantin Ananyev}
213aa97dd1cSKonstantin Ananyev
214aa97dd1cSKonstantin Ananyev#ifdef __cplusplus
215aa97dd1cSKonstantin Ananyev}
216aa97dd1cSKonstantin Ananyev#endif
217aa97dd1cSKonstantin Ananyev
218aa97dd1cSKonstantin Ananyev#endif /* _STREAM_TABLE_H_ */