cnat: add flow hash config to cnat translation
[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_TR_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_TR_FLAG_STACKED = (1 << 1),
68   /* Do not create a return session */
69   CNAT_TR_FLAG_NO_RETURN_SESSION = (1 << 2),
70 } __clib_packed cnat_translation_flag_t;
71
72 typedef enum
73 {
74   CNAT_RESOLV_ADDR_ANY,
75   CNAT_RESOLV_ADDR_BACKEND,
76   CNAT_RESOLV_ADDR_SNAT,
77   CNAT_RESOLV_ADDR_TRANSLATION,
78   CNAT_ADDR_N_RESOLUTIONS,
79 } cnat_addr_resol_type_t;
80
81 typedef enum
82 {
83   CNAT_LB_DEFAULT,
84   CNAT_LB_MAGLEV,
85 } __clib_packed cnat_lb_type_t;
86
87 /**
88  * Entry used to account for a translation's backend
89  * waiting for address resolution
90  */
91 typedef struct addr_resolution_t_
92 {
93   /**
94    * The interface index to resolve
95    */
96   u32 sw_if_index;
97   /**
98    * ip4 or ip6 resolution
99    */
100   ip_address_family_t af;
101   /**
102    * The cnat_addr_resolution_t
103    */
104   cnat_addr_resol_type_t type;
105   /**
106    * Translation index
107    */
108   index_t cti;
109   /**
110    * Callback data
111    */
112   u64 opaque;
113 } addr_resolution_t;
114
115 /**
116  * A Translation represents the translation of a VEP to one of a set
117  * of real server addresses
118  */
119 typedef struct cnat_translation_t_
120 {
121   /**
122    * Linkage into the FIB graph
123    */
124   fib_node_t ct_node;
125
126   /**
127    * The LB used to forward to the backends
128    */
129   dpo_id_t ct_lb;
130
131   /**
132    * The Virtual end point
133    */
134   cnat_endpoint_t ct_vip;
135
136   /**
137    * The vector of tracked back-ends
138    */
139   cnat_ep_trk_t *ct_paths;
140
141   /**
142    * The vector of active tracked back-ends
143    */
144   cnat_ep_trk_t *ct_active_paths;
145
146   /**
147    * The ip protocol for the translation
148    */
149   ip_protocol_t ct_proto;
150
151   /**
152    * The client object this translation belongs on
153    * INDEX_INVALID if vip is unresolved
154    */
155   index_t ct_cci;
156
157   /**
158    * Own index (if copied for trace)
159    */
160   index_t index;
161
162   /**
163    * Translation flags
164    */
165   cnat_translation_flag_t flags;
166
167   /**
168    * Type of load balancing
169    */
170   cnat_lb_type_t lb_type;
171
172   /**
173    * Type of flow hash config
174    */
175   flow_hash_config_t fhc;
176
177   union
178   {
179     u32 *lb_maglev;
180   };
181 } cnat_translation_t;
182
183 extern cnat_translation_t *cnat_translation_pool;
184
185 extern u8 *format_cnat_translation (u8 * s, va_list * args);
186
187 /**
188  * create or update a translation
189  *
190  * @param vip The Virtual Endpoint
191  * @param ip_proto The ip protocol to translate
192  * @param backends the backends to choose from
193  *
194  * @return the ID of the translation. used to delete and gather stats
195  */
196 extern u32 cnat_translation_update (cnat_endpoint_t *vip,
197                                     ip_protocol_t ip_proto,
198                                     cnat_endpoint_tuple_t *backends, u8 flags,
199                                     cnat_lb_type_t lb_type,
200                                     flow_hash_config_t fhc);
201
202 /**
203  * Delete a translation
204  *
205  * @param id the ID as returned from the create
206  */
207 extern int cnat_translation_delete (u32 id);
208
209 /**
210  * Callback function invoked during a walk of all translations
211  */
212 typedef walk_rc_t (*cnat_translation_walk_cb_t) (index_t index, void *ctx);
213
214 /**
215  * Walk/visit each of the translations
216  */
217 extern void cnat_translation_walk (cnat_translation_walk_cb_t cb, void *ctx);
218
219 /**
220  * Purge all the trahslations
221  */
222 extern int cnat_translation_purge (void);
223
224 /**
225  * Add an address resolution request
226  */
227 extern void cnat_translation_watch_addr (index_t cti, u64 opaque,
228                                          cnat_endpoint_t * ep,
229                                          cnat_addr_resol_type_t type);
230
231 /**
232  * Cleanup matching addr resolution requests
233  */
234 extern void cnat_translation_unwatch_addr (u32 cti,
235                                            cnat_addr_resol_type_t type);
236
237 /**
238  * Register a call back for endpoint->address resolution
239  */
240 typedef void (*cnat_if_addr_add_cb_t) (addr_resolution_t *ar,
241                                        ip_address_t *address, u8 is_del);
242
243 extern void cnat_translation_register_addr_add_cb (cnat_addr_resol_type_t typ,
244                                                    cnat_if_addr_add_cb_t fn);
245
246 /*
247  * Data plane functions
248  */
249 extern clib_bihash_8_8_t cnat_translation_db;
250
251 static_always_inline cnat_translation_t *
252 cnat_translation_get (index_t cti)
253 {
254   return (pool_elt_at_index (cnat_translation_pool, cti));
255 }
256
257 static_always_inline cnat_translation_t *
258 cnat_find_translation (index_t cti, u16 port, ip_protocol_t proto)
259 {
260   clib_bihash_kv_8_8_t bkey, bvalue;
261   u64 key;
262   int rv;
263
264   key = ((u64) proto << 24) | port;
265   key = key << 32 | (u32) cti;
266
267   bkey.key = key;
268   rv = clib_bihash_search_inline_2_8_8 (&cnat_translation_db, &bkey, &bvalue);
269   if (!rv)
270     return (pool_elt_at_index (cnat_translation_pool, bvalue.value));
271
272   return (NULL);
273 }
274
275 /*
276  * fd.io coding-style-patch-verification: ON
277  *
278  * Local Variables:
279  * eval: (c-set-style "gnu")
280  * End:
281  */
282
283 #endif