gso: use the header offsets from buffer metadata
[vpp.git] / src / vnet / session / session_table.c
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
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 #include <vnet/session/session_table.h>
17 #include <vnet/session/session.h>
18
19 /**
20  * Pool of session tables
21  */
22 static session_table_t *lookup_tables;
23
24 session_table_t *
25 _get_session_tables (void)
26 {
27   return lookup_tables;
28 }
29
30 session_table_t *
31 session_table_alloc (void)
32 {
33   session_table_t *slt;
34   pool_get_aligned (lookup_tables, slt, CLIB_CACHE_LINE_BYTES);
35   clib_memset (slt, 0, sizeof (*slt));
36   return slt;
37 }
38
39 u32
40 session_table_index (session_table_t * slt)
41 {
42   return (slt - lookup_tables);
43 }
44
45 session_table_t *
46 session_table_get (u32 table_index)
47 {
48   if (pool_is_free_index (lookup_tables, table_index))
49     return 0;
50   return pool_elt_at_index (lookup_tables, table_index);
51 }
52
53 #define foreach_hash_table_parameter            \
54   _(v4,session,buckets,20000)                   \
55   _(v4,session,memory,(64<<20))                 \
56   _(v6,session,buckets,20000)                   \
57   _(v6,session,memory,(64<<20))                 \
58   _(v4,halfopen,buckets,20000)                  \
59   _(v4,halfopen,memory,(64<<20))                \
60   _(v6,halfopen,buckets,20000)                  \
61   _(v6,halfopen,memory,(64<<20))
62
63 void
64 session_table_free (session_table_t *slt, u8 fib_proto)
65 {
66   u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
67   int i;
68
69   for (i = 0; i < TRANSPORT_N_PROTOS; i++)
70     session_rules_table_free (&slt->session_rules[i]);
71
72   vec_free (slt->session_rules);
73
74   if (fib_proto == FIB_PROTOCOL_IP4 || all)
75     {
76       clib_bihash_free_16_8 (&slt->v4_session_hash);
77       clib_bihash_free_16_8 (&slt->v4_half_open_hash);
78     }
79   if (fib_proto == FIB_PROTOCOL_IP6 || all)
80     {
81       clib_bihash_free_48_8 (&slt->v6_session_hash);
82       clib_bihash_free_48_8 (&slt->v6_half_open_hash);
83     }
84
85   pool_put (lookup_tables, slt);
86 }
87
88 /**
89  * Initialize session table hash tables
90  *
91  * If vpp configured with set of table parameters it uses them,
92  * otherwise it uses defaults above.
93  */
94 void
95 session_table_init (session_table_t * slt, u8 fib_proto)
96 {
97   u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
98   int i;
99
100 #define _(af,table,parm,value)                                          \
101   u32 configured_##af##_##table##_table_##parm = value;
102   foreach_hash_table_parameter;
103 #undef _
104
105 #define _(af,table,parm,value)                                          \
106   if (session_main.configured_##af##_##table##_table_##parm)    \
107     configured_##af##_##table##_table_##parm =                          \
108       session_main.configured_##af##_##table##_table_##parm;
109   foreach_hash_table_parameter;
110 #undef _
111
112   if (fib_proto == FIB_PROTOCOL_IP4 || all)
113     {
114       clib_bihash_init2_args_16_8_t _a, *a = &_a;
115
116       memset (a, 0, sizeof (*a));
117       a->h = &slt->v4_session_hash;
118       a->name = "v4 session table";
119       a->nbuckets = configured_v4_session_table_buckets;
120       a->memory_size = configured_v4_session_table_memory;
121       a->dont_add_to_all_bihash_list = 1;
122       a->instantiate_immediately = 1;
123       clib_bihash_init2_16_8 (a);
124
125       memset (a, 0, sizeof (*a));
126       a->h = &slt->v4_half_open_hash;
127       a->name = "v4 half-open table";
128       a->nbuckets = configured_v4_halfopen_table_buckets;
129       a->memory_size = configured_v4_halfopen_table_memory;
130       a->dont_add_to_all_bihash_list = 1;
131       a->instantiate_immediately = 1;
132       clib_bihash_init2_16_8 (a);
133     }
134   if (fib_proto == FIB_PROTOCOL_IP6 || all)
135     {
136       clib_bihash_init2_args_48_8_t _a, *a = &_a;
137
138       memset (a, 0, sizeof (*a));
139       a->h = &slt->v6_session_hash;
140       a->name = "v6 session table";
141       a->nbuckets = configured_v6_session_table_buckets;
142       a->memory_size = configured_v6_session_table_memory;
143       a->dont_add_to_all_bihash_list = 1;
144       a->instantiate_immediately = 1;
145       clib_bihash_init2_48_8 (a);
146
147       memset (a, 0, sizeof (*a));
148       a->h = &slt->v6_half_open_hash;
149       a->name = "v6 half-open table";
150       a->nbuckets = configured_v6_halfopen_table_buckets;
151       a->memory_size = configured_v6_halfopen_table_memory;
152       a->dont_add_to_all_bihash_list = 1;
153       a->instantiate_immediately = 1;
154       clib_bihash_init2_48_8 (a);
155     }
156
157   vec_validate (slt->session_rules, TRANSPORT_N_PROTOS - 1);
158   for (i = 0; i < TRANSPORT_N_PROTOS; i++)
159     session_rules_table_init (&slt->session_rules[i]);
160 }
161
162 typedef struct _ip4_session_table_walk_ctx_t
163 {
164   ip4_session_table_walk_fn_t fn;
165   void *ctx;
166 } ip4_session_table_walk_ctx_t;
167
168 static int
169 ip4_session_table_walk_cb (clib_bihash_kv_16_8_t * kvp, void *arg)
170 {
171   ip4_session_table_walk_ctx_t *ctx = arg;
172   ctx->fn (kvp, ctx->ctx);
173   return (BIHASH_WALK_CONTINUE);
174 }
175
176 void
177 ip4_session_table_walk (clib_bihash_16_8_t * hash,
178                         ip4_session_table_walk_fn_t fn, void *arg)
179 {
180   ip4_session_table_walk_ctx_t ctx = {
181     .fn = fn,
182     .ctx = arg,
183   };
184   clib_bihash_foreach_key_value_pair_16_8 (hash, ip4_session_table_walk_cb,
185                                            &ctx);
186 }
187
188 u32
189 session_table_memory_size (session_table_t *st)
190 {
191   u64 total_size = 0;
192
193   if (clib_bihash_is_initialised_16_8 (&st->v4_session_hash))
194     {
195       clib_bihash_alloc_chunk_16_8_t *c = st->v4_session_hash.chunks;
196       while (c)
197         {
198           total_size += c->size;
199           c = c->next;
200         }
201       c = st->v4_half_open_hash.chunks;
202       while (c)
203         {
204           total_size += c->size;
205           c = c->next;
206         }
207     }
208
209   if (clib_bihash_is_initialised_48_8 (&st->v6_session_hash))
210     {
211       clib_bihash_alloc_chunk_48_8_t *c = st->v6_session_hash.chunks;
212       while (c)
213         {
214           total_size += c->size;
215           c = c->next;
216         }
217       c = st->v6_half_open_hash.chunks;
218       while (c)
219         {
220           total_size += c->size;
221           c = c->next;
222         }
223     }
224
225   return total_size;
226 }
227
228 u8 *
229 format_session_table (u8 *s, va_list *args)
230 {
231   session_table_t *st = va_arg (*args, session_table_t *);
232
233   if (clib_bihash_is_initialised_16_8 (&st->v4_session_hash))
234     {
235       s = format (s, "%U", format_bihash_16_8, &st->v4_session_hash, 0);
236       s = format (s, "%U", format_bihash_16_8, &st->v4_half_open_hash, 0);
237     }
238
239   if (clib_bihash_is_initialised_48_8 (&st->v6_session_hash))
240     {
241       s = format (s, "%U", format_bihash_48_8, &st->v6_session_hash, 0);
242       s = format (s, "%U", format_bihash_48_8, &st->v6_half_open_hash, 0);
243     }
244
245   return s;
246 }
247
248 /*
249  * fd.io coding-style-patch-verification: ON
250  *
251  * Local Variables:
252  * eval: (c-set-style "gnu")
253  * End:
254  */