cnat: maglev fixes
[vpp.git] / src / plugins / cnat / cnat_translation.h
1 /*
2  * Copyright (c) 2020 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 #ifndef __CNAT_TRANSLATION_H__
17 #define __CNAT_TRANSLATION_H__
18
19 #include <cnat/cnat_types.h>
20 #include <vnet/ip/ip_types.h>
21 #include <vppinfra/bihash_8_8.h>
22
23 /**
24  * Counters for each translation
25  */
26 extern vlib_combined_counter_main_t cnat_translation_counters;
27
28
29 /**
30  * Data used to track an EP in the FIB
31  */
32 typedef struct cnat_ep_trk_t_
33 {
34   /**
35    * The EP being tracked
36    */
37   cnat_endpoint_t ct_ep[VLIB_N_DIR];
38
39   /**
40    * The FIB entry for the EP
41    */
42   fib_node_index_t ct_fei;
43
44   /**
45    * The sibling on the entry's child list
46    */
47   u32 ct_sibling;
48
49   /**
50    * The forwarding contributed by the entry
51    */
52   dpo_id_t ct_dpo;
53
54   /**
55    * Allows to disable if not resolved yet
56    */
57   u8 ct_flags; /* cnat_trk_flag_t */
58 } cnat_ep_trk_t;
59
60 typedef enum cnat_translation_flag_t_
61 {
62   /* Do allocate a source port */
63   CNAT_TRANSLATION_FLAG_ALLOCATE_PORT = (1 << 0),
64   /* Has this translation been satcked ?
65    * this allow not being called twice when
66    * with more then FIB_PATH_LIST_POPULAR backends  */
67   CNAT_TRANSLATION_STACKED = (1 << 1),
68 } cnat_translation_flag_t;
69
70 typedef enum
71 {
72   CNAT_RESOLV_ADDR_ANY,
73   CNAT_RESOLV_ADDR_BACKEND,
74   CNAT_RESOLV_ADDR_SNAT,
75   CNAT_RESOLV_ADDR_TRANSLATION,
76   CNAT_ADDR_N_RESOLUTIONS,
77 } cnat_addr_resol_type_t;
78
79 typedef enum __attribute__ ((__packed__))
80 {
81   CNAT_LB_DEFAULT,
82   CNAT_LB_MAGLEV,
83 } cnat_lb_type_t;
84
85 /**
86  * Entry used to account for a translation's backend
87  * waiting for address resolution
88  */
89 typedef struct addr_resolution_t_
90 {
91   /**
92    * The interface index to resolve
93    */
94   u32 sw_if_index;
95   /**
96    * ip4 or ip6 resolution
97    */
98   ip_address_family_t af;
99   /**
100    * The cnat_addr_resolution_t
101    */
102   cnat_addr_resol_type_t type;
103   /**
104    * Translation index
105    */
106   index_t cti;
107   /**
108    * Callback data
109    */
110   u64 opaque;
111 } addr_resolution_t;
112
113 /**
114  * A Translation represents the translation of a VEP to one of a set
115  * of real server addresses
116  */
117 typedef struct cnat_translation_t_
118 {
119   /**
120    * Linkage into the FIB graph
121    */
122   fib_node_t ct_node;
123
124   /**
125    * The LB used to forward to the backends
126    */
127   dpo_id_t ct_lb;
128
129   /**
130    * The Virtual end point
131    */
132   cnat_endpoint_t ct_vip;
133
134   /**
135    * The vector of tracked back-ends
136    */
137   cnat_ep_trk_t *ct_paths;
138
139   /**
140    * The vector of active tracked back-ends
141    */
142   cnat_ep_trk_t *ct_active_paths;
143
144   /**
145    * The ip protocol for the translation
146    */
147   ip_protocol_t ct_proto;
148
149   /**
150    * The client object this translation belongs on
151    * INDEX_INVALID if vip is unresolved
152    */
153   index_t ct_cci;
154
155   /**
156    * Own index (if copied for trace)
157    */
158   index_t index;
159
160   /**
161    * Translation flags
162    */
163   u8 flags;
164
165   /**
166    * Type of load balancing
167    */
168   cnat_lb_type_t lb_type;
169
170   union
171   {
172     u32 *lb_maglev;
173   };
174 } cnat_translation_t;
175
176 extern cnat_translation_t *cnat_translation_pool;
177
178 extern u8 *format_cnat_translation (u8 * s, va_list * args);
179
180 /**
181  * create or update a translation
182  *
183  * @param vip The Virtual Endpoint
184  * @param ip_proto The ip protocol to translate
185  * @param backends the backends to choose from
186  *
187  * @return the ID of the translation. used to delete and gather stats
188  */
189 extern u32 cnat_translation_update (cnat_endpoint_t *vip,
190                                     ip_protocol_t ip_proto,
191                                     cnat_endpoint_tuple_t *backends, u8 flags,
192                                     cnat_lb_type_t lb_type);
193
194 /**
195  * Delete a translation
196  *
197  * @param id the ID as returned from the create
198  */
199 extern int cnat_translation_delete (u32 id);
200
201 /**
202  * Callback function invoked during a walk of all translations
203  */
204 typedef walk_rc_t (*cnat_translation_walk_cb_t) (index_t index, void *ctx);
205
206 /**
207  * Walk/visit each of the translations
208  */
209 extern void cnat_translation_walk (cnat_translation_walk_cb_t cb, void *ctx);
210
211 /**
212  * Purge all the trahslations
213  */
214 extern int cnat_translation_purge (void);
215
216 /**
217  * Add an address resolution request
218  */
219 extern void cnat_translation_watch_addr (index_t cti, u64 opaque,
220                                          cnat_endpoint_t * ep,
221                                          cnat_addr_resol_type_t type);
222
223 /**
224  * Cleanup matching addr resolution requests
225  */
226 extern void cnat_translation_unwatch_addr (u32 cti,
227                                            cnat_addr_resol_type_t type);
228
229 /**
230  * Register a call back for endpoint->address resolution
231  */
232 typedef void (*cnat_if_addr_add_cb_t) (addr_resolution_t *ar,
233                                        ip_address_t *address, u8 is_del);
234
235 extern void cnat_translation_register_addr_add_cb (cnat_addr_resol_type_t typ,
236                                                    cnat_if_addr_add_cb_t fn);
237
238 /*
239  * Data plane functions
240  */
241 extern clib_bihash_8_8_t cnat_translation_db;
242
243 static_always_inline cnat_translation_t *
244 cnat_translation_get (index_t cti)
245 {
246   return (pool_elt_at_index (cnat_translation_pool, cti));
247 }
248
249 static_always_inline cnat_translation_t *
250 cnat_find_translation (index_t cti, u16 port, ip_protocol_t proto)
251 {
252   clib_bihash_kv_8_8_t bkey, bvalue;
253   u64 key;
254   int rv;
255
256   key = ((u64) proto << 24) | port;
257   key = key << 32 | (u32) cti;
258
259   bkey.key = key;
260   rv = clib_bihash_search_inline_2_8_8 (&cnat_translation_db, &bkey, &bvalue);
261   if (!rv)
262     return (pool_elt_at_index (cnat_translation_pool, bvalue.value));
263
264   return (NULL);
265 }
266
267 /*
268  * fd.io coding-style-patch-verification: ON
269  *
270  * Local Variables:
271  * eval: (c-set-style "gnu")
272  * End:
273  */
274
275 #endif