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