ipv6 connection tracking plugin
[vpp.git] / src / plugins / ct6 / ct6.h
1
2 /*
3  * ct6.h - skeleton vpp engine plug-in header file
4  *
5  * Copyright (c) <current-year> <your-organization>
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #ifndef __included_ct6_h__
19 #define __included_ct6_h__
20
21 #include <vnet/vnet.h>
22 #include <vnet/ip/ip.h>
23 #include <vnet/ethernet/ethernet.h>
24 #include <vppinfra/bihash_48_8.h>
25
26 #include <vppinfra/hash.h>
27 #include <vppinfra/error.h>
28
29 /* *INDENT-OFF* */
30 typedef CLIB_PACKED (struct
31 {
32   union
33   {
34     struct
35     {
36       /* out2in */
37       ip6_address_t src;
38       ip6_address_t dst;
39       u16 sport;
40       u16 dport;
41       u8 proto; /* byte 37 */
42     };
43     u64 as_u64[6];
44   };
45 }) ct6_session_key_t;
46 /* *INDENT-ON* */
47
48 typedef struct
49 {
50   ct6_session_key_t key;
51   u32 thread_index;
52   u32 next_index;
53   u32 prev_index;
54   u32 hits;
55   f64 expires;
56 } ct6_session_t;
57
58 typedef struct
59 {
60   /* API message ID base */
61   u16 msg_id_base;
62
63   /* session lookup table */
64   clib_bihash_48_8_t session_hash;
65   u8 feature_initialized;
66
67   /* per_thread session pools */
68   ct6_session_t **sessions;
69   u32 *first_index;
70   u32 *last_index;
71
72   /* Config parameters */
73   f64 session_timeout_interval;
74   uword session_hash_memory;
75   u32 session_hash_buckets;
76   u32 max_sessions_per_worker;
77
78   /* convenience */
79   vlib_main_t *vlib_main;
80   vnet_main_t *vnet_main;
81   ethernet_main_t *ethernet_main;
82 } ct6_main_t;
83
84 extern ct6_main_t ct6_main;
85
86 extern vlib_node_registration_t ct6_out2in_node;
87 extern vlib_node_registration_t ct6_in2out_node;
88
89 format_function_t format_ct6_session;
90
91 ct6_session_t *ct6_create_or_recycle_session (ct6_main_t * cmp,
92                                               clib_bihash_kv_48_8_t * kvpp,
93                                               f64 now, u32 my_thread_index,
94                                               u32 * recyclep, u32 * createp);
95
96 static inline void
97 ct6_lru_remove (ct6_main_t * cmp, ct6_session_t * s0)
98 {
99   ct6_session_t *next_sess, *prev_sess;
100   u32 thread_index;
101   u32 s0_index;
102
103   thread_index = s0->thread_index;
104
105   s0_index = s0 - cmp->sessions[thread_index];
106
107   /* Deal with list heads */
108   if (s0_index == cmp->first_index[thread_index])
109     cmp->first_index[thread_index] = s0->next_index;
110   if (s0_index == cmp->last_index[thread_index])
111     cmp->last_index[thread_index] = s0->prev_index;
112
113   /* Fix next->prev */
114   if (s0->next_index != ~0)
115     {
116       next_sess = pool_elt_at_index (cmp->sessions[thread_index],
117                                      s0->next_index);
118       next_sess->prev_index = s0->prev_index;
119     }
120   /* Fix prev->next */
121   if (s0->prev_index != ~0)
122     {
123       prev_sess = pool_elt_at_index (cmp->sessions[thread_index],
124                                      s0->prev_index);
125       prev_sess->next_index = s0->next_index;
126     }
127 }
128
129 static inline void
130 ct6_lru_add (ct6_main_t * cmp, ct6_session_t * s0, f64 now)
131 {
132   ct6_session_t *next_sess;
133   u32 thread_index;
134   u32 s0_index;
135
136   s0->hits++;
137   s0->expires = now + cmp->session_timeout_interval;
138   thread_index = s0->thread_index;
139
140   s0_index = s0 - cmp->sessions[thread_index];
141
142   /*
143    * Re-add at the head of the forward LRU list,
144    * tail of the reverse LRU list
145    */
146   if (cmp->first_index[thread_index] != ~0)
147     {
148       next_sess = pool_elt_at_index (cmp->sessions[thread_index],
149                                      cmp->first_index[thread_index]);
150       next_sess->prev_index = s0_index;
151     }
152
153   s0->prev_index = ~0;
154
155   /* s0 now the new head of the LRU forward list */
156   s0->next_index = cmp->first_index[thread_index];
157   cmp->first_index[thread_index] = s0_index;
158
159   /* single session case: also the tail of the reverse LRU list */
160   if (cmp->last_index[thread_index] == ~0)
161     cmp->last_index[thread_index] = s0_index;
162 }
163
164 static inline void
165 ct6_update_session_hit (ct6_main_t * cmp, ct6_session_t * s0, f64 now)
166 {
167   ct6_lru_remove (cmp, s0);
168   ct6_lru_add (cmp, s0, now);
169 }
170
171 #endif /* __included_ct6_h__ */
172
173 /*
174  * fd.io coding-style-patch-verification: ON
175  *
176  * Local Variables:
177  * eval: (c-set-style "gnu")
178  * End:
179  */