misc: deprecate gbp and its dependents
[vpp.git] / extras / deprecated / plugins / gbp / gbp_endpoint.h
1 /*
2  * Copyright (c) 2018 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 __GBP_ENDPOINT_H__
17 #define __GBP_ENDPOINT_H__
18
19 #include <plugins/gbp/gbp_types.h>
20 #include <plugins/gbp/gbp_itf.h>
21 #include <vnet/ip/ip.h>
22 #include <vnet/ethernet/mac_address.h>
23
24 #include <vppinfra/bihash_16_8.h>
25 #include <vppinfra/bihash_template.h>
26 #include <vppinfra/bihash_24_8.h>
27 #include <vppinfra/bihash_template.h>
28
29 /**
30  * Flags for each endpoint
31  */
32 typedef enum gbp_endpoint_attr_t_
33 {
34   GBP_ENDPOINT_ATTR_FIRST = 0,
35   GBP_ENDPOINT_ATTR_BOUNCE = GBP_ENDPOINT_ATTR_FIRST,
36   GBP_ENDPOINT_ATTR_REMOTE,
37   GBP_ENDPOINT_ATTR_LEARNT,
38   GBP_ENDPOINT_ATTR_EXTERNAL,
39   GBP_ENDPOINT_ATTR_LAST,
40 } gbp_endpoint_attr_t;
41
42 typedef enum gbp_endpoint_flags_t_
43 {
44   GBP_ENDPOINT_FLAG_NONE = 0,
45   GBP_ENDPOINT_FLAG_BOUNCE = (1 << GBP_ENDPOINT_ATTR_BOUNCE),
46   GBP_ENDPOINT_FLAG_REMOTE = (1 << GBP_ENDPOINT_ATTR_REMOTE),
47   GBP_ENDPOINT_FLAG_LEARNT = (1 << GBP_ENDPOINT_ATTR_LEARNT),
48   GBP_ENDPOINT_FLAG_EXTERNAL = (1 << GBP_ENDPOINT_ATTR_EXTERNAL),
49 } gbp_endpoint_flags_t;
50
51 #define GBP_ENDPOINT_ATTR_NAMES {                 \
52     [GBP_ENDPOINT_ATTR_BOUNCE] = "bounce",        \
53     [GBP_ENDPOINT_ATTR_REMOTE] = "remote",        \
54     [GBP_ENDPOINT_ATTR_LEARNT] = "learnt",        \
55     [GBP_ENDPOINT_ATTR_EXTERNAL] = "external",    \
56 }
57
58 extern u8 *format_gbp_endpoint_flags (u8 * s, va_list * args);
59
60 /**
61  * Sources of Endpoints in priority order. The best (lowest value) source
62  * provides the forwarding information.
63  * Data-plane takes preference because the CP data is not always complete,
64  * it may not have the sclass.
65  */
66 #define foreach_gbp_endpoint_src    \
67   _(DP, "data-plane")               \
68   _(CP, "control-plane")            \
69   _(RR, "recursive-resolution")
70
71 typedef enum gbp_endpoint_src_t_
72 {
73 #define _(v,s) GBP_ENDPOINT_SRC_##v,
74   foreach_gbp_endpoint_src
75 #undef _
76 } gbp_endpoint_src_t;
77
78 #define GBP_ENDPOINT_SRC_MAX (GBP_ENDPOINT_SRC_RR+1)
79
80 extern u8 *format_gbp_endpoint_src (u8 * s, va_list * args);
81
82 /**
83  * This is the identity of an endpoint, as such it is information
84  * about an endpoint that is idempotent.
85  * The ID is used to add the EP into the various data-bases for retrieval.
86  */
87 typedef struct gbp_endpoint_key_t_
88 {
89   /**
90    * A vector of ip addresses that belong to the endpoint.
91    * Together with the route EPG's RD this forms the EP's L3 key
92    */
93   fib_prefix_t *gek_ips;
94
95   /**
96    * MAC address of the endpoint.
97    * Together with the route EPG's BD this forms the EP's L2 key
98    */
99   mac_address_t gek_mac;
100
101   /**
102    * Index of the Bridge-Domain
103    */
104   index_t gek_gbd;
105
106   /**
107    * Index of the Route-Domain
108    */
109   index_t gek_grd;
110 } gbp_endpoint_key_t;
111
112 /**
113  * Information about the location of the endpoint provided by a source
114  * of endpoints
115  */
116 typedef struct gbp_endpoint_loc_t_
117 {
118   /**
119    * The source providing this location information
120    */
121   gbp_endpoint_src_t gel_src;
122
123   /**
124    * The interface on which the EP is connected
125    */
126   gbp_itf_hdl_t gel_itf;
127
128   /**
129    * Endpoint flags
130    */
131   gbp_endpoint_flags_t gel_flags;
132
133   /**
134    * Endpoint Group.
135    */
136   index_t gel_epg;
137
138   /**
139    * number of times this source has locked this
140    */
141   u32 gel_locks;
142
143   /**
144    * Tunnel info for remote endpoints
145    */
146   struct
147   {
148     u32 gel_parent_sw_if_index;
149     ip46_address_t gel_src;
150     ip46_address_t gel_dst;
151   } tun;
152 } gbp_endpoint_loc_t;
153
154 /**
155  * And endpoints current forwarding state
156  */
157 typedef struct gbp_endpoint_fwd_t_
158 {
159   /**
160    * The interface on which the EP is connected
161    */
162   gbp_itf_hdl_t gef_itf;
163
164   /**
165    * The L3 adj, if created
166    */
167   index_t *gef_adjs;
168
169   /**
170    * Endpoint Group's sclass. cached for fast DP access.
171    */
172   sclass_t gef_sclass;
173
174   /**
175    * FIB index the EP is in
176    */
177   u32 gef_fib_index;
178
179   gbp_endpoint_flags_t gef_flags;
180 } gbp_endpoint_fwd_t;
181
182 /**
183  * A Group Based Policy Endpoint.
184  * This is typically a VM or container. If the endpoint is local (i.e. on
185  * the same compute node as VPP) then there is one interface per-endpoint.
186  * If the EP is remote,e.g. reachable over a [vxlan] tunnel, then there
187  * will be multiple EPs reachable over the tunnel and they can be distinguished
188  * via either their MAC or IP Address[es].
189  */
190 typedef struct gbp_endpoint_t_
191 {
192   /**
193    * A FIB node that allows the tracking of children.
194    */
195   fib_node_t ge_node;
196
197   /**
198    * The key/ID of this EP
199    */
200   gbp_endpoint_key_t ge_key;
201
202   /**
203    * Location information provided by the various sources.
204    * These are sorted based on source priority.
205    */
206   gbp_endpoint_loc_t *ge_locs;
207
208   gbp_endpoint_fwd_t ge_fwd;
209
210   /**
211    * The last time a packet from seen from this end point
212    */
213   f64 ge_last_time;
214 } gbp_endpoint_t;
215
216 extern u8 *format_gbp_endpoint (u8 * s, va_list * args);
217
218 /**
219  * GBP Endpoint Databases
220  */
221 typedef struct gbp_ep_by_ip_itf_db_t_
222 {
223   index_t *ged_by_sw_if_index;
224   clib_bihash_24_8_t ged_by_ip_rd;
225   clib_bihash_16_8_t ged_by_mac_bd;
226 } gbp_ep_db_t;
227
228 extern int gbp_endpoint_update_and_lock (gbp_endpoint_src_t src,
229                                          u32 sw_if_index,
230                                          const ip46_address_t * ip,
231                                          const mac_address_t * mac,
232                                          index_t gbd, index_t grd,
233                                          sclass_t sclass,
234                                          gbp_endpoint_flags_t flags,
235                                          const ip46_address_t * tun_src,
236                                          const ip46_address_t * tun_dst,
237                                          u32 * handle);
238 extern void gbp_endpoint_unlock (gbp_endpoint_src_t src, index_t gbpei);
239 extern u32 gbp_endpoint_child_add (index_t gei,
240                                    fib_node_type_t type,
241                                    fib_node_index_t index);
242 extern void gbp_endpoint_child_remove (index_t gei, u32 sibling);
243
244 typedef walk_rc_t (*gbp_endpoint_cb_t) (index_t gbpei, void *ctx);
245 extern void gbp_endpoint_walk (gbp_endpoint_cb_t cb, void *ctx);
246 extern void gbp_endpoint_scan (vlib_main_t * vm);
247 extern int gbp_endpoint_is_remote (const gbp_endpoint_t * ge);
248 extern int gbp_endpoint_is_local (const gbp_endpoint_t * ge);
249 extern int gbp_endpoint_is_external (const gbp_endpoint_t * ge);
250 extern int gbp_endpoint_is_learnt (const gbp_endpoint_t * ge);
251
252
253 extern void gbp_endpoint_flush (gbp_endpoint_src_t src, u32 sw_if_index);
254
255 /**
256  * DP functions and databases
257  */
258 extern gbp_ep_db_t gbp_ep_db;
259 extern gbp_endpoint_t *gbp_endpoint_pool;
260
261 /**
262  * Get the endpoint from a port/interface
263  */
264 always_inline gbp_endpoint_t *
265 gbp_endpoint_get (index_t gbpei)
266 {
267   return (pool_elt_at_index (gbp_endpoint_pool, gbpei));
268 }
269
270 static_always_inline void
271 gbp_endpoint_mk_key_mac (const u8 * mac,
272                          u32 bd_index, clib_bihash_kv_16_8_t * key)
273 {
274   key->key[0] = ethernet_mac_address_u64 (mac);
275   key->key[1] = bd_index;
276 }
277
278 static_always_inline gbp_endpoint_t *
279 gbp_endpoint_find_mac (const u8 * mac, u32 bd_index)
280 {
281   clib_bihash_kv_16_8_t key, value;
282   int rv;
283
284   gbp_endpoint_mk_key_mac (mac, bd_index, &key);
285
286   rv = clib_bihash_search_16_8 (&gbp_ep_db.ged_by_mac_bd, &key, &value);
287
288   if (0 != rv)
289     return NULL;
290
291   return (gbp_endpoint_get (value.value));
292 }
293
294 static_always_inline void
295 gbp_endpoint_mk_key_ip (const ip46_address_t * ip,
296                         u32 fib_index, clib_bihash_kv_24_8_t * key)
297 {
298   key->key[0] = ip->as_u64[0];
299   key->key[1] = ip->as_u64[1];
300   key->key[2] = fib_index;
301 }
302
303 static_always_inline void
304 gbp_endpoint_mk_key_ip4 (const ip4_address_t * ip,
305                          u32 fib_index, clib_bihash_kv_24_8_t * key)
306 {
307   const ip46_address_t a = {
308     .ip4 = *ip,
309   };
310   gbp_endpoint_mk_key_ip (&a, fib_index, key);
311 }
312
313 static_always_inline gbp_endpoint_t *
314 gbp_endpoint_find_ip4 (const ip4_address_t * ip, u32 fib_index)
315 {
316   clib_bihash_kv_24_8_t key, value;
317   int rv;
318
319   gbp_endpoint_mk_key_ip4 (ip, fib_index, &key);
320
321   rv = clib_bihash_search_24_8 (&gbp_ep_db.ged_by_ip_rd, &key, &value);
322
323   if (0 != rv)
324     return NULL;
325
326   return (gbp_endpoint_get (value.value));
327 }
328
329 static_always_inline void
330 gbp_endpoint_mk_key_ip6 (const ip6_address_t * ip,
331                          u32 fib_index, clib_bihash_kv_24_8_t * key)
332 {
333   key->key[0] = ip->as_u64[0];
334   key->key[1] = ip->as_u64[1];
335   key->key[2] = fib_index;
336 }
337
338 static_always_inline gbp_endpoint_t *
339 gbp_endpoint_find_ip6 (const ip6_address_t * ip, u32 fib_index)
340 {
341   clib_bihash_kv_24_8_t key, value;
342   int rv;
343
344   gbp_endpoint_mk_key_ip6 (ip, fib_index, &key);
345
346   rv = clib_bihash_search_24_8 (&gbp_ep_db.ged_by_ip_rd, &key, &value);
347
348   if (0 != rv)
349     return NULL;
350
351   return (gbp_endpoint_get (value.value));
352 }
353
354 static_always_inline gbp_endpoint_t *
355 gbp_endpoint_find_itf (u32 sw_if_index)
356 {
357   index_t gei;
358
359   gei = gbp_ep_db.ged_by_sw_if_index[sw_if_index];
360
361   if (INDEX_INVALID != gei)
362     return (gbp_endpoint_get (gei));
363
364   return (NULL);
365 }
366
367
368 #endif
369
370 /*
371  * fd.io coding-style-patch-verification: ON
372  *
373  * Local Variables:
374  * eval: (c-set-style "gnu")
375  * End:
376  */