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