FD.io VPP  v21.01.1
Vector Packet Processing
cnat_translation.c
Go to the documentation of this file.
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 #include <vnet/fib/fib_source.h>
17 #include <vnet/fib/fib_table.h>
19 #include <vnet/dpo/load_balance.h>
20 #include <vnet/dpo/drop_dpo.h>
21 
22 #include <cnat/cnat_translation.h>
23 #include <cnat/cnat_session.h>
24 #include <cnat/cnat_client.h>
25 
27 clib_bihash_8_8_t cnat_translation_db;
29 
31  ip_address_t * address, u8 is_del);
33 
35 
36 vlib_combined_counter_main_t cnat_translation_counters = {
37  .name = "cnat-translation",
38  .stat_segment_name = "/net/cnat-translation",
39 };
40 
41 void
44 {
46 
47  if (INDEX_INVALID == ep->ce_sw_if_index)
48  return;
49 
50  pool_get (tr_resolutions, ar);
51  ar->af = ep->ce_ip.version;
52  ar->sw_if_index = ep->ce_sw_if_index;
53  ar->type = type;
54  ar->opaque = opaque;
55  ar->cti = cti;
56 }
57 
58 static void
60 {
61  cnat_resolve_ep (&path->src_ep);
62  cnat_resolve_ep (&path->dst_ep);
63 }
64 
65 void
67 {
68  /* Delete tr resolution entries matching translation index */
70  index_t *indexes = 0, *ari;
71  /* *INDENT-OFF* */
72  pool_foreach (ar, tr_resolutions) {
73  if ((cti == INDEX_INVALID || ar->cti == cti) &&
74  (ar->type == type || CNAT_RESOLV_ADDR_ANY == type))
75  vec_add1(indexes, ar - tr_resolutions);
76  }
77  /* *INDENT-ON* */
78  vec_foreach (ari, indexes) pool_put_index (tr_resolutions, *ari);
79 
80  vec_free (indexes);
81 }
82 
83 static void
85 {
86  /* We only track fully resolved endpoints */
87  if (!trk->is_active)
88  return;
89  fib_entry_untrack (trk->ct_fei, trk->ct_sibling);
90 }
91 
92 static void
94 {
95  fib_prefix_t pfx;
96  /* We only track fully resolved endpoints */
99  if (!trk->is_active)
100  return;
101 
104  &pfx,
106  cti, &trk->ct_sibling);
107 
110  (pfx.fp_proto), &trk->ct_dpo);
111 }
112 
113 /**
114  * Add a translation to the bihash
115  *
116  * @param cci the ID of the parent client (invalid if vip not resolved)
117  * @param vip the translation endpoint
118  * @param proto the translation proto
119  * @param cti the translation index to be used as value
120  */
121 static void
124 {
126  u64 key;
127  if (INDEX_INVALID == cci)
128  {
129  key = proto << 8 | 0x80 | vip->ce_ip.version;
130  key = key << 16 | vip->ce_port;
131  key = key << 32 | (u32) vip->ce_sw_if_index;
132  }
133  else
134  {
135  key = proto << 8;
136  key = key << 16 | vip->ce_port;
137  key = key << 32 | (u32) cci;
138  }
139 
140  bkey.key = key;
141  bkey.value = cti;
142 
143  clib_bihash_add_del_8_8 (&cnat_translation_db, &bkey, 1);
144 }
145 
146 /**
147  * Remove a translation from the bihash
148  *
149  * @param cci the ID of the parent client
150  * @param vip the translation endpoint
151  * @param proto the translation proto
152  */
153 static void
156 {
158  u64 key;
159  if (INDEX_INVALID == cci)
160  {
161  key = proto << 8 | 0x80 | vip->ce_ip.version;
162  key = key << 16 | vip->ce_port;
163  key = key << 32 | (u32) vip->ce_sw_if_index;
164  }
165  else
166  {
167  key = proto << 8;
168  key = key << 16 | vip->ce_port;
169  key = key << 32 | (u32) cci;
170  }
171 
172  bkey.key = key;
173 
174  clib_bihash_add_del_8_8 (&cnat_translation_db, &bkey, 0);
175 }
176 
177 static void
179 {
180  fib_protocol_t fproto;
181  cnat_ep_trk_t *trk;
182  dpo_proto_t dproto;
183  u32 ep_idx = 0;
184  index_t lbi;
185 
187  dproto = fib_proto_to_dpo (fproto);
188 
189  vec_foreach (trk, ct->ct_paths) if (trk->is_active)
190  ep_idx++;
191 
192  lbi = load_balance_create (ep_idx, fib_proto_to_dpo (fproto),
194 
195  ep_idx = 0;
196  vec_foreach (trk, ct->ct_paths) if (trk->is_active)
197  load_balance_set_bucket (lbi, ep_idx++, &trk->ct_dpo);
198 
199  dpo_set (&ct->ct_lb, DPO_LOAD_BALANCE, dproto, lbi);
200  dpo_stack (cnat_client_dpo, dproto, &ct->ct_lb, &ct->ct_lb);
202 }
203 
204 int
206 {
207  cnat_translation_t *ct;
208  cnat_ep_trk_t *trk;
209 
210  if (pool_is_free_index (cnat_translation_pool, id))
211  return (VNET_API_ERROR_NO_SUCH_ENTRY);
212 
213  ct = pool_elt_at_index (cnat_translation_pool, id);
214 
215  dpo_reset (&ct->ct_lb);
216 
217  vec_foreach (trk, ct->ct_paths) cnat_tracker_release (trk);
218 
222  pool_put (cnat_translation_pool, ct);
223 
224  return (0);
225 }
226 
227 u32
231 {
233  const cnat_client_t *cc;
234  cnat_translation_t *ct;
235  cnat_ep_trk_t *trk;
236  index_t cci;
237 
238  cnat_lazy_init ();
239  if (cnat_resolve_ep (vip))
240  {
241  /* vip only contains a sw_if_index for now */
242  ct = cnat_find_translation (vip->ce_sw_if_index, vip->ce_port, proto);
243  cci = INDEX_INVALID;
244  }
245  else
246  {
247  /* do we know of this ep's vip */
248  cci = cnat_client_add (&vip->ce_ip, flags);
249  cc = cnat_client_get (cci);
250 
251  ct = cnat_find_translation (cc->parent_cci, vip->ce_port, proto);
252  }
253 
254  if (NULL == ct)
255  {
256  pool_get_zero (cnat_translation_pool, ct);
257 
258  clib_memcpy (&ct->ct_vip, vip, sizeof (*vip));
259  ct->ct_proto = proto;
260  ct->ct_cci = cci;
261  ct->index = ct - cnat_translation_pool;
262 
263  cnat_add_translation_to_db (cci, vip, proto, ct->index);
265 
266  vlib_validate_combined_counter (&cnat_translation_counters, ct->index);
267  vlib_zero_combined_counter (&cnat_translation_counters, ct->index);
268  }
269  ct->flags = flags;
270 
272  cnat_translation_watch_addr (ct->index, 0, vip,
274 
275  vec_foreach (trk, ct->ct_paths)
276  {
277  cnat_tracker_release (trk);
278  }
279 
282 
283  u64 path_idx = 0;
284  vec_foreach (path, paths)
285  {
286  cnat_resolve_ep_tuple (path);
288  path_idx << 32 | VLIB_RX, &path->src_ep,
291  path_idx << 32 | VLIB_TX, &path->dst_ep,
293  path_idx++;
294 
295  vec_add2 (ct->ct_paths, trk, 1);
296 
297  clib_memcpy (&trk->ct_ep[VLIB_TX], &path->dst_ep,
298  sizeof (trk->ct_ep[VLIB_TX]));
299  clib_memcpy (&trk->ct_ep[VLIB_RX], &path->src_ep,
300  sizeof (trk->ct_ep[VLIB_RX]));
301 
302  cnat_tracker_track (ct->index, trk);
303  }
304 
306 
307  return (ct->index);
308 }
309 
310 void
312 {
313  u32 api;
314 
315  /* *INDENT-OFF* */
316  pool_foreach_index (api, cnat_translation_pool)
317  {
318  if (!cb(api, ctx))
319  break;
320  }
321  /* *INDENT-ON* */
322 }
323 
324 static u8 *
325 format_cnat_ep_trk (u8 * s, va_list * args)
326 {
327  cnat_ep_trk_t *ck = va_arg (*args, cnat_ep_trk_t *);
328  u32 indent = va_arg (*args, u32);
329 
330  s = format (s, "%U->%U", format_cnat_endpoint, &ck->ct_ep[VLIB_RX],
332  s = format (s, "\n%Ufib-entry:%d", format_white_space, indent, ck->ct_fei);
333  s = format (s, "\n%U%U",
334  format_white_space, indent, format_dpo_id, &ck->ct_dpo, 6);
335 
336  return (s);
337 }
338 
339 u8 *
340 format_cnat_translation (u8 * s, va_list * args)
341 {
342  cnat_translation_t *ct = va_arg (*args, cnat_translation_t *);
343  cnat_ep_trk_t *ck;
344 
345  s = format (s, "[%d] ", ct->index);
346  s = format (s, "%U %U", format_cnat_endpoint, &ct->ct_vip,
348 
349  vec_foreach (ck, ct->ct_paths)
350  s = format (s, "\n%U", format_cnat_ep_trk, ck, 2);
351 
352  /* If printing a trace, the LB object might be deleted */
354  {
355  s = format (s, "\n via:");
356  s = format (s, "\n%U%U",
357  format_white_space, 2, format_dpo_id, &ct->ct_lb, 2);
358  }
359 
360  return (s);
361 }
362 
363 static clib_error_t *
365  unformat_input_t * input, vlib_cli_command_t * cmd)
366 {
367  index_t cti;
368  cnat_translation_t *ct;
369 
370  cti = INDEX_INVALID;
371 
373  {
374  if (unformat (input, "%d", &cti))
375  ;
376  else
377  return (clib_error_return (0, "unknown input '%U'",
378  format_unformat_error, input));
379  }
380 
381  if (INDEX_INVALID == cti)
382  {
383  /* *INDENT-OFF* */
384  pool_foreach_index (cti, cnat_translation_pool)
385  {
386  ct = pool_elt_at_index (cnat_translation_pool, cti);
388  }
389  /* *INDENT-ON* */
390  }
391  else
392  {
393  vlib_cli_output (vm, "Invalid policy ID:%d", cti);
394  }
395 
396  return (NULL);
397 }
398 
399 int
401 {
402  /* purge all the translations */
403  index_t tri, *trp, *trs = NULL;
404 
405  /* *INDENT-OFF* */
406  pool_foreach_index (tri, cnat_translation_pool)
407  {
408  vec_add1(trs, tri);
409  }
410  /* *INDENT-ON* */
411 
412  vec_foreach (trp, trs) cnat_translation_delete (*trp);
413 
414  ASSERT (0 == pool_elts (cnat_translation_pool));
415 
416  vec_free (trs);
417 
418  return (0);
419 }
420 
421 /* *INDENT-OFF* */
422 VLIB_CLI_COMMAND (cnat_translation_show_cmd_node, static) = {
423  .path = "show cnat translation",
424  .function = cnat_translation_show,
425  .short_help = "show cnat translation <VIP>",
426  .is_mp_safe = 1,
427 };
428 /* *INDENT-ON* */
429 
430 static fib_node_t *
432 {
434  return (&(ct->ct_node));
435 }
436 
437 static cnat_translation_t *
439 {
440  return ((cnat_translation_t *) (((char *) node) -
442  ct_node)));
443 }
444 
445 static void
447 {
448  /**/}
449 
450 /*
451  * A back walk has reached this ABF policy
452  */
456 {
457  /*
458  * re-stack the fmask on the n-eos of the via
459  */
461 
462  /* If we have more than FIB_PATH_LIST_POPULAR paths
463  * we might get called during path tracking
464  * (cnat_tracker_track) */
465  if (!(ct->flags & CNAT_TRANSLATION_STACKED))
467 
469 
471 }
472 
473 /*
474  * The translation's graph node virtual function table
475  */
476 static const fib_node_vft_t cnat_translation_vft = {
478  .fnv_last_lock = cnat_translation_last_lock_gone,
479  .fnv_back_walk = cnat_translation_back_walk_notify,
480 };
481 
482 static clib_error_t *
484  unformat_input_t * input,
485  vlib_cli_command_t * cmd)
486 {
487  u32 del_index = INDEX_INVALID;
488  ip_protocol_t proto = IP_PROTOCOL_TCP;
489  cnat_endpoint_t vip;
491  cnat_endpoint_tuple_t tmp, *paths = NULL, *path;
492  unformat_input_t _line_input, *line_input = &_line_input;
493  clib_error_t *e = 0;
494 
495  /* Get a line of input. */
496  if (!unformat_user (input, unformat_line_input, line_input))
497  return 0;
498 
499  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
500  {
501  if (unformat (line_input, "add"))
502  del_index = INDEX_INVALID;
503  else if (unformat (line_input, "del %d", &del_index))
504  ;
505  else
506  if (unformat (line_input, "proto %U", unformat_ip_protocol, &proto))
507  ;
508  else if (unformat (line_input, "vip %U", unformat_cnat_ep, &vip))
509  flags = CNAT_FLAG_EXCLUSIVE;
510  else if (unformat (line_input, "real %U", unformat_cnat_ep, &vip))
511  flags = 0;
512  else if (unformat (line_input, "to %U", unformat_cnat_ep_tuple, &tmp))
513  {
514  vec_add2 (paths, path, 1);
515  clib_memcpy (path, &tmp, sizeof (cnat_endpoint_tuple_t));
516  }
517  else
518  {
519  e = clib_error_return (0, "unknown input '%U'",
520  format_unformat_error, line_input);
521  goto done;
522  }
523  }
524 
525  if (INDEX_INVALID == del_index)
526  cnat_translation_update (&vip, proto, paths, flags);
527  else
528  cnat_translation_delete (del_index);
529 
530 done:
531  vec_free (paths);
532  unformat_free (line_input);
533  return (e);
534 }
535 
536 /* *INDENT-OFF* */
537 VLIB_CLI_COMMAND (cnat_translation_cli_add_del_command, static) =
538 {
539  .path = "cnat translation",
540  .short_help = "cnat translation [add|del] proto [TCP|UDP] [vip|real] [ip|sw_if_index [v6]] [port] [to [ip|sw_if_index [v6]] [port]->[ip|sw_if_index [v6]] [port]]",
541  .function = cnat_translation_cli_add_del,
542 };
543 /* *INDENT-ON* */
544 
545 static void
547  ip_address_t * address, u8 is_del)
548 {
549  cnat_translation_t *ct;
550  ct = cnat_translation_get (ar->cti);
551  if (!is_del && ct->ct_vip.ce_flags & CNAT_EP_FLAG_RESOLVED)
552  return;
553 
555 
556  if (is_del)
557  {
559  ct->ct_cci = INDEX_INVALID;
561  /* Are there remaining addresses ? */
562  if (0 == cnat_resolve_addr (ar->sw_if_index, ar->af, address))
563  is_del = 0;
564  }
565 
566  if (!is_del)
567  {
568  ct->ct_cci = cnat_client_add (address, ct->flags);
570  ip_address_copy (&ct->ct_vip.ce_ip, address);
572  }
573 
575  ct->index);
576 }
577 
578 static void
580  ip_address_t * address, u8 is_del)
581 {
582  cnat_translation_t *ct;
583  cnat_ep_trk_t *trk;
584  cnat_endpoint_t *ep;
585 
586  u8 direction = ar->opaque & 0xf;
587  u32 path_idx = ar->opaque >> 32;
588 
589  ct = cnat_translation_get (ar->cti);
590 
591  trk = &ct->ct_paths[path_idx];
592  ep = &trk->ct_ep[direction];
593 
594  if (!is_del && ep->ce_flags & CNAT_EP_FLAG_RESOLVED)
595  return;
596 
597  ASSERT (ep->ce_sw_if_index == ar->sw_if_index);
598 
599  if (is_del)
600  {
602  /* Are there remaining addresses ? */
603  if (0 == cnat_resolve_addr (ar->sw_if_index, ar->af, address))
604  is_del = 0;
605  }
606 
607  if (!is_del)
608  {
609  ip_address_copy (&ep->ce_ip, address);
611  }
612 
614  cnat_tracker_track (ar->cti, trk);
615 
618 }
619 
620 static void
622  u8 is_del)
623 {
624  cnat_endpoint_t *ep;
625  ep = AF_IP4 == ar->af ? &cnat_main.snat_ip4 : &cnat_main.snat_ip6;
626 
627  if (!is_del && ep->ce_flags & CNAT_EP_FLAG_RESOLVED)
628  return;
629 
630  if (is_del)
631  {
633  /* Are there remaining addresses ? */
634  if (0 == cnat_resolve_addr (ar->sw_if_index, ar->af, address))
635  is_del = 0;
636  }
637 
638  if (!is_del)
639  {
640  ip_address_copy (&ep->ce_ip, address);
642  }
643 
644 }
645 
646 static void
648  u8 is_del)
649 {
650  addr_resolution_t *ar;
651  /* *INDENT-OFF* */
652  pool_foreach (ar, tr_resolutions) {
653  if (ar->sw_if_index != sw_if_index)
654  continue;
655  if (ar->af != ip_addr_version (address))
656  continue;
657  cnat_if_addr_add_cbs[ar->type] (ar, address, is_del);
658  }
659  /* *INDENT-ON* */
660 }
661 
662 static void
664  uword opaque, u32 sw_if_index,
665  ip6_address_t * address,
666  u32 address_length, u32 if_address_index,
667  u32 is_del)
668 {
670  ip_address_set (&addr, address, AF_IP6);
671  cnat_if_addr_add_del_callback (sw_if_index, &addr, is_del);
672 }
673 
674 static void
676  uword opaque, u32 sw_if_index,
678  u32 address_length, u32 if_address_index,
679  u32 is_del)
680 {
682  ip_address_set (&addr, address, AF_IP4);
683  cnat_if_addr_add_del_callback (sw_if_index, &addr, is_del);
684 }
685 
686 static clib_error_t *
688 {
689  ip4_main_t *i4m = &ip4_main;
690  ip6_main_t *i6m = &ip6_main;
693  fib_node_register_new_type (&cnat_translation_vft);
694 
695  clib_bihash_init_8_8 (&cnat_translation_db, "CNat translation DB",
698 
702 
706 
713  return (NULL);
714 }
715 
717 
718 /*
719  * fd.io coding-style-patch-verification: ON
720  *
721  * Local Variables:
722  * eval: (c-set-style "gnu")
723  * End:
724  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
walk_rc_t(* cnat_translation_walk_cb_t)(index_t index, void *ctx)
Callback function invoked during a walk of all translations.
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
dpo_type_t cnat_client_dpo
Definition: cnat_client.c:26
static fib_node_back_walk_rc_t cnat_translation_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
format_function_t format_ip_protocol
Definition: format.h:45
unformat_function_t unformat_ip_protocol
Definition: format.h:46
fib_node_index_t fib_entry_track(u32 fib_index, const fib_prefix_t *prefix, fib_node_type_t child_type, index_t child_index, u32 *sibling)
Trackers are used on FIB entries by objects that which to track the changing state of the entry...
#define pool_foreach_index(i, v)
Definition: pool.h:569
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:108
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
Definition: ip4.h:141
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
void ip_address_set(ip_address_t *dst, const void *src, u8 version)
Definition: ip_types.c:208
static_always_inline cnat_translation_t * cnat_translation_get(index_t cti)
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:254
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
cnat_endpoint_t snat_ip6
Definition: cnat_types.h:134
unsigned long u64
Definition: types.h:89
static void cnat_if_addr_add_del_backend_cb(addr_resolution_t *ar, ip_address_t *address, u8 is_del)
static clib_error_t * cnat_translation_cli_add_del(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
void fib_entry_contribute_forwarding(fib_node_index_t fib_entry_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
Definition: fib_entry.c:437
static void cnat_tracker_release(cnat_ep_trk_t *trk)
static void cnat_translation_last_lock_gone(fib_node_t *node)
ip_protocol_t ct_proto
The ip protocol for the translation.
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
static void cnat_add_translation_to_db(index_t cci, cnat_endpoint_t *vip, ip_protocol_t proto, index_t cti)
Add a translation to the bihash.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:630
A Translation represents the translation of a VEP to one of a set of real server addresses.
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:70
vlib_main_t * vm
Definition: in2out_ed.c:1580
cnat_endpoint_t src_ep
Definition: cnat_types.h:71
index_t parent_cci
Parent cnat_client index if cloned via interpose or own index if vanilla client.
Definition: cnat_client.h:74
vl_api_fib_path_t path
Definition: mfib_types.api:44
static void cnat_if_addr_add_del_snat_cb(addr_resolution_t *ar, ip_address_t *address, u8 is_del)
static void cnat_if_addr_add_del_translation_cb(addr_resolution_t *ar, ip_address_t *address, u8 is_del)
#define ip_addr_version(_a)
Definition: ip_types.h:93
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
index_t cnat_client_add(const ip_address_t *ip, u8 flags)
Definition: cnat_client.c:151
vhost_vring_addr_t addr
Definition: vhost_user.h:111
cnat_if_addr_add_cb_t * cnat_if_addr_add_cbs
unsigned char u8
Definition: types.h:56
u32 sw_if_index
The interface index to resolve.
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
Definition: fib_node.c:80
cnat_translation_t * cnat_translation_pool
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void cnat_resolve_ep_tuple(cnat_endpoint_tuple_t *path)
#define clib_memcpy(d, s, n)
Definition: string.h:180
index_t load_balance_create(u32 n_buckets, dpo_proto_t lb_proto, flow_hash_config_t fhc)
Definition: load_balance.c:264
u64 opaque
Callback data.
uword unformat_cnat_ep(unformat_input_t *input, va_list *args)
Definition: cnat_types.c:74
cnat_endpoint_t dst_ep
Definition: cnat_types.h:70
void cnat_translation_watch_addr(index_t cti, u64 opaque, cnat_endpoint_t *ep, cnat_addr_resol_type_t type)
Add an address resolution request.
load_balance_t * load_balance_pool
Pool of all DPOs.
Definition: load_balance.c:52
cnat_endpoint_t ct_vip
The Virtual end point.
static_always_inline cnat_translation_t * cnat_find_translation(index_t cti, u16 port, ip_protocol_t proto)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
description fragment has unexpected format
Definition: map.api:433
Aggregate type for a prefix.
Definition: fib_types.h:202
#define clib_error_return(e, args...)
Definition: error.h:99
void ip_address_to_fib_prefix(const ip_address_t *addr, fib_prefix_t *prefix)
convert from a IP address to a FIB prefix
Definition: ip_types.c:271
cnat_addr_resol_type_t
unsigned int u32
Definition: types.h:88
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
void cnat_translation_unwatch_addr(u32 cti, cnat_addr_resol_type_t type)
Cleanup matching addr resolution requests.
static cnat_translation_t * cnat_translation_get_from_node(fib_node_t *node)
int cnat_translation_purge(void)
Purge all the trahslations.
unformat_function_t unformat_line_input
Definition: format.h:282
vl_api_fib_path_type_t type
Definition: fib_types.api:123
enum ip_protocol ip_protocol_t
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:304
index_t ct_cci
The client object this translation belongs on INDEX_INVALID if vip is unresolved. ...
int cnat_translation_delete(u32 id)
Delete a translation.
vl_api_ip_proto_t proto
Definition: acl_types.api:51
u64 key
the key
Definition: bihash_8_8.h:43
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
static clib_error_t * cnat_translation_init(vlib_main_t *vm)
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
static void cnat_translation_stack(cnat_translation_t *ct)
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
dpo_id_t ct_dpo
The forwarding contributed by the entry.
cnat_addr_resol_type_t type
The cnat_addr_resolution_t.
u8 * format_cnat_endpoint(u8 *s, va_list *args)
Definition: cnat_types.c:123
ip6_main_t ip6_main
Definition: ip6_forward.c:2785
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
Definition: ip_flow_hash.h:29
An node in the FIB graph.
Definition: fib_node.h:295
static fib_node_type_t cnat_translation_fib_node_type
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Definition: ip6.h:148
cnat_ep_trk_t * ct_paths
The vector of tracked back-ends.
static_always_inline cnat_client_t * cnat_client_get(index_t i)
Definition: cnat_client.h:91
fib_node_t ct_node
Linkage into the FIB graph.
u64 value
the value
Definition: bihash_8_8.h:44
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
static void cnat_tracker_track(index_t cti, cnat_ep_trk_t *trk)
void cnat_client_translation_added(index_t cci)
A translation that references this VIP was added.
Definition: cnat_client.c:109
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
ip4_add_del_interface_address_function_t * function
Definition: ip4.h:75
addr_resolution_t * tr_resolutions
fib_node_get_t fnv_get
Definition: fib_node.h:283
Entry used to account for a translation&#39;s backend waiting for address resolution. ...
static fib_node_t * cnat_translation_get_node(fib_node_index_t index)
static u8 * format_cnat_ep_trk(u8 *s, va_list *args)
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
cnat_endpoint_t ct_ep[VLIB_N_DIR]
The EP being tracked.
8 octet key, 8 octet key value pair
Definition: bihash_8_8.h:41
fib_protocol_t ip_address_family_to_fib_proto(ip_address_family_t af)
Definition: ip_types.c:224
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:186
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
Context passed between object during a back walk.
Definition: fib_node.h:208
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
static void cnat_if_addr_add_del_callback(u32 sw_if_index, ip_address_t *address, u8 is_del)
ip6_add_del_interface_address_function_t * function
Definition: ip6.h:96
static clib_error_t * cnat_translation_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip_address_family_t af
ip4 or ip6 resolution
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:330
#define ASSERT(truth)
void fib_entry_untrack(fib_node_index_t fei, u32 sibling)
Stop tracking a FIB entry.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
manual_print typedef address
Definition: ip_types.api:96
dpo_id_t ct_lb
The LB used to forward to the backends.
void cnat_client_translation_deleted(index_t cci)
A translation that references this VIP was deleted.
Definition: cnat_client.c:121
u8 is_active
Allows to disable if not resolved yet.
IPv4 main type.
Definition: ip4.h:107
static void cnat_remove_translation_from_db(index_t cci, cnat_endpoint_t *vip, ip_protocol_t proto)
Remove a translation from the bihash.
u8 * format_cnat_translation(u8 *s, va_list *args)
ip_address_family_t version
Definition: ip_types.h:82
index_t cti
Translation index.
static void cnat_ip4_if_addr_add_del_callback(struct ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_del)
u8 cnat_resolve_addr(u32 sw_if_index, ip_address_family_t af, ip_address_t *addr)
Definition: cnat_types.c:30
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:343
void load_balance_set_bucket(index_t lbi, u32 bucket, const dpo_id_t *next)
Definition: load_balance.c:281
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:148
u32 cnat_translation_update(cnat_endpoint_t *vip, ip_protocol_t proto, cnat_endpoint_tuple_t *paths, u8 flags)
create or update a translation
u32 translation_hash_buckets
Definition: cnat_types.h:109
typedef key
Definition: ipsec_types.api:86
void cnat_translation_walk(cnat_translation_walk_cb_t cb, void *ctx)
Walk/visit each of the translations.
paths
Definition: map.api:460
Definition: defs.h:47
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:188
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
uword unformat_cnat_ep_tuple(unformat_input_t *input, va_list *args)
Definition: cnat_types.c:107
#define CNAT_FIB_TABLE
Definition: cnat_types.h:27
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
cnat_main_t cnat_main
Definition: cnat_types.c:18
clib_bihash_8_8_t cnat_translation_db
char * name
The counter collection&#39;s name.
Definition: counter.h:212
u32 index
Definition: flow_types.api:221
fib_node_index_t ct_fei
The FIB entry for the EP.
uword translation_hash_memory
Definition: cnat_types.h:106
A collection of combined counters.
Definition: counter.h:207
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void ip_address_copy(ip_address_t *dst, const ip_address_t *src)
Definition: ip_types.c:133
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
void(* cnat_if_addr_add_cb_t)(addr_resolution_t *ar, ip_address_t *address, u8 is_del)
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
#define vec_foreach(var, vec)
Vector iterator.
ip_address_t ce_ip
Definition: cnat_types.h:62
import vnet interface_types api
Definition: sample.api:20
Data used to track an EP in the FIB.
cnat_endpoint_t snat_ip4
Definition: cnat_types.h:131
u8 cnat_resolve_ep(cnat_endpoint_t *ep)
Resolve endpoint address.
Definition: cnat_types.c:64
static void cnat_ip6_if_addr_add_del_callback(struct ip6_main_t *im, uword opaque, u32 sw_if_index, ip6_address_t *address, u32 address_length, u32 if_address_index, u32 is_del)
index_t index
Own index (if copied for trace)
void cnat_lazy_init()
Lazy initialization when first adding a translation or using snat.
Definition: cnat_types.c:168
u8 flags
Translation flags.
fib_forward_chain_type_t fib_forw_chain_type_from_fib_proto(fib_protocol_t proto)
Convert from a fib-protocol to a chain type.
Definition: fib_types.c:449
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
Definition: defs.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
A client is a representation of an IP address behind the NAT.
Definition: cnat_client.h:35
void dpo_stack(dpo_type_t child_type, dpo_proto_t child_proto, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child-parent relationship.
Definition: dpo.c:521
u32 ct_sibling
The sibling on the entry&#39;s child list.
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127