FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
cnat_snat_policy.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/ip/ip.h>
17 #include <cnat/cnat_snat_policy.h>
18 #include <cnat/cnat_translation.h>
19 
21 
22 uword
24 {
25  u8 *a = va_arg (*args, u8 *);
26  if (unformat (input, "include-v4"))
28  else if (unformat (input, "include-v6"))
30  else if (unformat (input, "k8s"))
32  else
33  return 0;
34  return 1;
35 }
36 
37 u8 *
39 {
40  cnat_snat_interface_map_type_t mtype = va_arg (*args, int);
41  switch (mtype)
42  {
44  s = format (s, "Included v4");
45  break;
47  s = format (s, "Included v6");
48  break;
50  s = format (s, "k8s pod");
51  break;
52  default:
53  s = format (s, "(unknown)");
54  break;
55  }
56  return (s);
57 }
58 
59 u8 *
60 format_cnat_snat_prefix (u8 *s, va_list *args)
61 {
62  clib_bihash_kv_24_8_t *kv = va_arg (*args, clib_bihash_kv_24_8_t *);
63  CLIB_UNUSED (int verbose) = va_arg (*args, int);
64  u32 af = kv->key[2] >> 32;
65  u32 len = kv->key[2] & 0xffffffff;
66  if (AF_IP4 == af)
67  s = format (s, "%U/%d", format_ip4_address, &kv->key[0], len);
68  else
69  s = format (s, "%U/%d", format_ip6_address, &kv->key[0], len);
70  return (s);
71 }
72 
73 static void
76 {
77  int i;
79  /* Note: bitmap reversed so this is in fact a longest prefix match */
81  {
82  int dst_address_length = 128 - i;
84  dst_address_length);
85  }
86 }
87 
88 int
91 {
93 
94  if (table >= ARRAY_LEN (cpm->interface_maps))
95  return VNET_API_ERROR_INVALID_VALUE;
96 
97  clib_bitmap_t **map = &cpm->interface_maps[table];
98 
99  *map = clib_bitmap_set (*map, sw_if_index, is_add);
100  return 0;
101 }
102 
103 static clib_error_t *
105  unformat_input_t *input,
106  vlib_cli_command_t *cmd)
107 {
108  vnet_main_t *vnm = vnet_get_main ();
109  int is_add = 1;
110  u32 sw_if_index = ~0;
111  u32 table;
112  int rv;
113 
115  {
116  if (unformat (input, "del"))
117  is_add = 0;
118  else if (unformat (input, "table %U",
120  ;
121  else if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
122  &sw_if_index))
123  ;
124  else
125  return clib_error_return (0, "unknown input '%U'",
126  format_unformat_error, input);
127  }
128 
129  if (sw_if_index == ~0)
130  return clib_error_return (0, "Interface not specified");
131 
132  rv = cnat_snat_policy_add_del_if (sw_if_index, is_add, table);
133 
134  if (rv)
135  return clib_error_return (0, "Error %d", rv);
136 
137  return NULL;
138 }
139 
140 VLIB_CLI_COMMAND (cnat_snat_policy_add_del_if_command, static) = {
141  .path = "set cnat snat-policy if",
142  .short_help = "set cnat snat-policy if [del]"
143  "[table [include-v4 include-v6 k8s]] [interface]",
145 };
146 
147 int
149 {
150  /* All packets destined to this prefix won't be source-NAT-ed */
151  cnat_snat_exclude_pfx_table_t *table = &cnat_snat_policy_main.excluded_pfx;
153  ip6_address_t *mask;
154  u64 af = ip_prefix_version (pfx);
155  ;
156 
157  mask = &table->ip_masks[pfx->len];
158  if (AF_IP4 == af)
159  {
160  kv.key[0] = (u64) ip_prefix_v4 (pfx).as_u32 & mask->as_u64[0];
161  kv.key[1] = 0;
162  }
163  else
164  {
165  kv.key[0] = ip_prefix_v6 (pfx).as_u64[0] & mask->as_u64[0];
166  kv.key[1] = ip_prefix_v6 (pfx).as_u64[1] & mask->as_u64[1];
167  }
168  kv.key[2] = ((u64) af << 32) | pfx->len;
169  clib_bihash_add_del_24_8 (&table->ip_hash, &kv, 1 /* is_add */);
170 
171  table->meta[af].dst_address_length_refcounts[pfx->len]++;
173  table->meta[af].non_empty_dst_address_length_bitmap, 128 - pfx->len, 1);
175  return 0;
176 }
177 
178 int
180 {
181  cnat_snat_exclude_pfx_table_t *table = &cnat_snat_policy_main.excluded_pfx;
182  clib_bihash_kv_24_8_t kv, val;
183  ip6_address_t *mask;
184  u64 af = ip_prefix_version (pfx);
185  ;
186 
187  mask = &table->ip_masks[pfx->len];
188  if (AF_IP4 == af)
189  {
190  kv.key[0] = (u64) ip_prefix_v4 (pfx).as_u32 & mask->as_u64[0];
191  kv.key[1] = 0;
192  }
193  else
194  {
195  kv.key[0] = ip_prefix_v6 (pfx).as_u64[0] & mask->as_u64[0];
196  kv.key[1] = ip_prefix_v6 (pfx).as_u64[1] & mask->as_u64[1];
197  }
198  kv.key[2] = ((u64) af << 32) | pfx->len;
199 
200  if (clib_bihash_search_24_8 (&table->ip_hash, &kv, &val))
201  {
202  return 1;
203  }
204  clib_bihash_add_del_24_8 (&table->ip_hash, &kv, 0 /* is_add */);
205  /* refcount accounting */
206  ASSERT (table->meta[af].dst_address_length_refcounts[pfx->len] > 0);
207  if (--table->meta[af].dst_address_length_refcounts[pfx->len] == 0)
208  {
211  128 - pfx->len, 0);
213  }
214  return 0;
215 }
216 
217 int
219 {
220  /* Returns 0 if addr matches any of the listed prefixes */
221  cnat_snat_exclude_pfx_table_t *table = &cnat_snat_policy_main.excluded_pfx;
222  clib_bihash_kv_24_8_t kv, val;
223  int i, n_p, rv;
224  n_p = vec_len (table->meta[af].prefix_lengths_in_search_order);
225  if (AF_IP4 == af)
226  {
227  kv.key[0] = addr->ip4.as_u32;
228  kv.key[1] = 0;
229  }
230  else
231  {
232  kv.key[0] = addr->as_u64[0];
233  kv.key[1] = addr->as_u64[1];
234  }
235 
236  /*
237  * start search from a mask length same length or shorter.
238  * we don't want matches longer than the mask passed
239  */
240  i = 0;
241  for (; i < n_p; i++)
242  {
243  int dst_address_length =
245  ip6_address_t *mask = &table->ip_masks[dst_address_length];
246 
247  ASSERT (dst_address_length >= 0 && dst_address_length <= 128);
248  /* As lengths are decreasing, masks are increasingly specific. */
249  kv.key[0] &= mask->as_u64[0];
250  kv.key[1] &= mask->as_u64[1];
251  kv.key[2] = ((u64) af << 32) | dst_address_length;
252  rv = clib_bihash_search_inline_2_24_8 (&table->ip_hash, &kv, &val);
253  if (rv == 0)
254  return 0;
255  }
256  return -1;
257 }
258 
261 {
263  return clib_bitmap_get (cpm->interface_maps[af], sw_if_index);
264 }
265 
266 int
268 {
269  /* srcNAT everything by default */
270  return 1;
271 }
272 
273 int
275 {
276  ip46_address_t *dst_addr = &session->key.cs_ip[VLIB_TX];
277  u32 in_if = vnet_buffer (b)->sw_if_index[VLIB_RX];
278  ip_address_family_t af = session->key.cs_af;
279 
280  /* source nat for outgoing connections */
281  if (cnat_snat_policy_interface_enabled (in_if, af))
282  if (cnat_search_snat_prefix (dst_addr, af))
283  /* Destination is not in the prefixes that don't require snat */
284  return 1;
285  return 0;
286 }
287 
288 int
290 {
292  ip_address_family_t af = session->key.cs_af;
293 
294  ip46_address_t *src_addr = &session->key.cs_ip[VLIB_RX];
295  ip46_address_t *dst_addr = &session->key.cs_ip[VLIB_TX];
296  u32 in_if = vnet_buffer (b)->sw_if_index[VLIB_RX];
297  u32 out_if = vnet_buffer (b)->sw_if_index[VLIB_TX];
298 
299  /* source nat for outgoing connections */
300  if (cnat_snat_policy_interface_enabled (in_if, af))
301  if (cnat_search_snat_prefix (dst_addr, af))
302  /* Destination is not in the prefixes that don't require snat */
303  return 1;
304 
305  /* source nat for translations that come from the outside:
306  src not not a pod interface, dst not a pod interface */
308  in_if) &&
310  out_if))
311  {
312  if (AF_IP6 == af &&
313  ip6_address_is_equal (&src_addr->ip6,
314  &ip_addr_v6 (&cpm->snat_ip6.ce_ip)))
315  return 0;
316  if (AF_IP4 == af &&
317  ip4_address_is_equal (&src_addr->ip4,
318  &ip_addr_v4 (&cpm->snat_ip4.ce_ip)))
319  return 0;
320  return 1;
321  }
322 
323  /* handle the case where a container is connecting to itself via a service */
324  if (ip46_address_is_equal (src_addr, dst_addr))
325  return 1;
326 
327  return 0;
328 }
329 
330 void
332 {
334 
335  cnat_lazy_init ();
336 
338 
339  ip_address_set (&cpm->snat_ip4.ce_ip, ip4, AF_IP4);
340  ip_address_set (&cpm->snat_ip6.ce_ip, ip6, AF_IP6);
343 
344  cnat_resolve_ep (&cpm->snat_ip4);
345  cnat_resolve_ep (&cpm->snat_ip6);
350 }
351 
352 static clib_error_t *
354  vlib_cli_command_t *cmd)
355 {
356  unformat_input_t _line_input, *line_input = &_line_input;
357  vnet_main_t *vnm = vnet_get_main ();
358  ip4_address_t ip4 = { { 0 } };
359  ip6_address_t ip6 = { { 0 } };
360  clib_error_t *e = 0;
362 
363  cnat_lazy_init ();
364 
365  /* Get a line of input. */
366  if (!unformat_user (input, unformat_line_input, line_input))
367  return 0;
368 
369  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
370  {
371  if (unformat_user (line_input, unformat_ip4_address, &ip4))
372  ;
373  else if (unformat_user (line_input, unformat_ip6_address, &ip6))
374  ;
375  else if (unformat_user (line_input, unformat_vnet_sw_interface, vnm,
376  &sw_if_index))
377  ;
378  else
379  {
380  e = clib_error_return (0, "unknown input '%U'",
381  format_unformat_error, input);
382  goto done;
383  }
384  }
385 
386  cnat_set_snat (&ip4, &ip6, sw_if_index);
387 
388 done:
389  unformat_free (line_input);
390 
391  return (e);
392 }
393 
394 VLIB_CLI_COMMAND (cnat_set_snat_command, static) = {
395  .path = "set cnat snat-policy addr",
396  .short_help =
397  "set cnat snat-policy addr [<ip4-address>][<ip6-address>][sw_if_index]",
398  .function = cnat_set_snat_cli,
399 };
400 
401 static clib_error_t *
403  unformat_input_t *input,
404  vlib_cli_command_t *cmd)
405 {
406  ip_prefix_t pfx;
407  u8 is_add = 1;
408  int rv;
409 
411  {
412  if (unformat (input, "%U", unformat_ip_prefix, &pfx))
413  ;
414  else if (unformat (input, "del"))
415  is_add = 0;
416  else
417  return (clib_error_return (0, "unknown input '%U'",
418  format_unformat_error, input));
419  }
420 
421  if (is_add)
422  rv = cnat_snat_policy_add_pfx (&pfx);
423  else
424  rv = cnat_snat_policy_del_pfx (&pfx);
425 
426  if (rv)
427  return (clib_error_return (0, "error %d", rv, input));
428 
429  return (NULL);
430 }
431 
432 VLIB_CLI_COMMAND (cnat_snat_policy_add_del_pfx_command, static) = {
433  .path = "set cnat snat-policy prefix",
434  .short_help = "set cnat snat-policy prefix [del] [prefix]",
436 };
437 
438 static clib_error_t *
440  vlib_cli_command_t *cmd)
441 {
442  cnat_snat_exclude_pfx_table_t *excluded_pfx =
443  &cnat_snat_policy_main.excluded_pfx;
445  vnet_main_t *vnm = vnet_get_main ();
447 
448  vlib_cli_output (vm, "Source NAT\n ip4: %U\n ip6: %U\n\n",
450  &cpm->snat_ip6);
451  vlib_cli_output (vm, "Excluded prefixes:\n %U\n", format_bihash_24_8,
452  &excluded_pfx->ip_hash, 1);
453 
454  for (int i = 0; i < CNAT_N_SNAT_IF_MAP; i++)
455  {
456  vlib_cli_output (vm, "\n%U interfaces:\n",
458  clib_bitmap_foreach (sw_if_index, cpm->interface_maps[i])
460  sw_if_index);
461  }
462 
463  return (NULL);
464 }
465 
466 VLIB_CLI_COMMAND (cnat_show_snat_command, static) = {
467  .path = "show cnat snat-policy",
468  .short_help = "show cnat snat-policy",
469  .function = cnat_show_snat,
470 };
471 
472 int
474 {
476  switch (policy)
477  {
480  break;
483  break;
486  break;
487  default:
488  return 1;
489  }
490  return 0;
491 }
492 
493 static clib_error_t *
495  vlib_cli_command_t *cmd)
496 {
499  {
500  if (unformat (input, "none"))
501  ;
502  else if (unformat (input, "if-pfx"))
503  policy = CNAT_SNAT_POLICY_IF_PFX;
504  else if (unformat (input, "k8s"))
505  policy = CNAT_SNAT_POLICY_K8S;
506  else
507  return clib_error_return (0, "unknown input '%U'",
508  format_unformat_error, input);
509  }
510 
511  cnat_set_snat_policy (policy);
512  return NULL;
513 }
514 
515 VLIB_CLI_COMMAND (cnat_snat_policy_set_cmd, static) = {
516  .path = "set cnat snat-policy",
517  .short_help = "set cnat snat-policy [none][if-pfx][k8s]",
518  .function = cnat_snat_policy_set_cmd_fn,
519 };
520 
521 static void
523  u8 is_del)
524 {
526  cnat_endpoint_t *ep;
527 
528  ep = AF_IP4 == ar->af ? &cpm->snat_ip4 : &cpm->snat_ip6;
529 
530  if (!is_del && ep->ce_flags & CNAT_EP_FLAG_RESOLVED)
531  return;
532 
533  if (is_del)
534  {
536  /* Are there remaining addresses ? */
537  if (0 == cnat_resolve_addr (ar->sw_if_index, ar->af, address))
538  is_del = 0;
539  }
540 
541  if (!is_del)
542  {
543  ip_address_copy (&ep->ce_ip, address);
545  }
546 }
547 
548 static clib_error_t *
550 {
553  cnat_snat_exclude_pfx_table_t *excluded_pfx = &cpm->excluded_pfx;
554 
555  int i;
556  for (i = 0; i < ARRAY_LEN (excluded_pfx->ip_masks); i++)
557  {
558  u32 j, i0, i1;
559 
560  i0 = i / 32;
561  i1 = i % 32;
562 
563  for (j = 0; j < i0; j++)
564  excluded_pfx->ip_masks[i].as_u32[j] = ~0;
565 
566  if (i1)
567  excluded_pfx->ip_masks[i].as_u32[i0] =
568  clib_host_to_net_u32 (pow2_mask (i1) << (32 - i1));
569  }
570  clib_bihash_init_24_8 (&excluded_pfx->ip_hash, "snat prefixes",
572  clib_bihash_set_kvp_format_fn_24_8 (&excluded_pfx->ip_hash,
574 
575  for (int i = 0; i < CNAT_N_SNAT_IF_MAP; i++)
577 
580 
582 
583  return (NULL);
584 }
585 
587 
588 /*
589  * fd.io coding-style-patch-verification: ON
590  *
591  * Local Variables:
592  * eval: (c-set-style "gnu")
593  * End:
594  */
#define ip_addr_v6(_a)
Definition: ip_types.h:92
struct cnat_session_t_::@635 key
this key sits in the same memory location a &#39;key&#39; in the bihash kvp
#define CLIB_UNUSED(x)
Definition: clib.h:90
static_always_inline int ip4_address_is_equal(const ip4_address_t *ip4_1, const ip4_address_t *ip4_2)
Definition: ip46_address.h:101
int cnat_snat_policy_add_del_if(u32 sw_if_index, u8 is_add, cnat_snat_interface_map_type_t table)
a
Definition: bitmap.h:544
int cnat_snat_policy_none(vlib_buffer_t *b, cnat_session_t *session)
unsigned long u64
Definition: types.h:89
vnet_feature_config_main_t * cm
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
clib_bitmap_t * interface_maps[CNAT_N_SNAT_IF_MAP]
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
vl_api_ipsec_spd_action_t policy
Definition: ipsec.api:99
unformat_function_t unformat_vnet_sw_interface
#define ip_prefix_v6(_a)
Definition: ip_types.h:127
u8 * format_cnat_snat_interface_map_type(u8 *s, va_list *args)
#define ip_prefix_v4(_a)
Definition: ip_types.h:126
static clib_error_t * cnat_snat_policy_add_del_if_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vhost_vring_addr_t addr
Definition: vhost_user.h:130
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
vlib_buffer_t ** b
u32 sw_if_index
The interface index to resolve.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
unsigned int u32
Definition: types.h:88
#define clib_bitmap_validate(v, n_bits)
Definition: bitmap.h:115
A session represents the memory of a translation.
Definition: cnat_session.h:37
u8 cs_af
The address family describing the IP addresses.
Definition: cnat_session.h:62
format_function_t format_ip4_address
Definition: format.h:73
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
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.
#define static_always_inline
Definition: clib.h:112
unformat_function_t unformat_ip4_address
Definition: format.h:68
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
int cnat_snat_policy_del_pfx(ip_prefix_t *pfx)
static uword pow2_mask(uword x)
Definition: clib.h:252
vl_api_ip6_address_t ip6
Definition: one.api:424
int cnat_snat_policy_k8s(vlib_buffer_t *b, cnat_session_t *session)
description fragment has unexpected format
Definition: map.api:433
static clib_error_t * cnat_show_snat(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define clib_error_return(e, args...)
Definition: error.h:99
vnet_main_t * vnet_get_main(void)
int cnat_snat_policy_add_pfx(ip_prefix_t *pfx)
int __clib_unused rv
Definition: application.c:491
void cnat_translation_unwatch_addr(u32 cti, cnat_addr_resol_type_t type)
Cleanup matching addr resolution requests.
static_always_inline int cnat_snat_policy_interface_enabled(u32 sw_if_index, ip_address_family_t af)
static clib_error_t * cnat_snat_policy_set_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip46_address_t cs_ip[VLIB_N_DIR]
IP 4/6 address in the rx/tx direction.
Definition: cnat_session.h:47
unformat_function_t unformat_line_input
Definition: format.h:275
void ip_address_set(ip_address_t *dst, const void *src, ip_address_family_t af)
Definition: ip_types.c:207
cnat_snat_policy_t snat_policy
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
int cnat_search_snat_prefix(ip46_address_t *addr, ip_address_family_t af)
struct _unformat_input_t unformat_input_t
static clib_error_t * cnat_set_snat_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
cnat_snat_pfx_table_meta_t meta[2]
vl_api_mac_address_t src_addr
Definition: flow_types.api:64
u8 * format_cnat_endpoint(u8 *s, va_list *args)
Definition: cnat_types.c:134
vl_api_ip4_address_t ip4
Definition: one.api:376
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
static u8 ip46_address_is_equal(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
Definition: ip46_address.h:93
u8 len
Definition: ip_types.api:103
unformat_function_t unformat_ip6_address
Definition: format.h:89
vl_api_mac_address_t dst_addr
Definition: flow_types.api:65
void cnat_translation_register_addr_add_cb(cnat_addr_resol_type_t typ, cnat_if_addr_add_cb_t fn)
cnat_snat_policy_main_t cnat_snat_policy_main
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
format_function_t format_ip6_address
Definition: format.h:91
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
vl_api_pnat_mask_t mask
Definition: pnat.api:45
counters map
Definition: map.api:356
Entry used to account for a translation&#39;s backend waiting for address resolution. ...
#define ARRAY_LEN(x)
Definition: clib.h:70
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
void cnat_set_snat(ip4_address_t *ip4, ip6_address_t *ip6, u32 sw_if_index)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
ip_address_family_t af
ip4 or ip6 resolution
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
#define ip_addr_v4(_a)
Definition: ip_types.h:91
manual_print typedef address
Definition: ip_types.api:96
static clib_error_t * cnat_snat_policy_add_del_pfx_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
uword unformat_cnat_snat_interface_map_type(unformat_input_t *input, va_list *args)
u8 cnat_resolve_addr(u32 sw_if_index, ip_address_family_t af, ip_address_t *addr)
Definition: cnat_types.c:29
static void cnat_if_addr_add_del_snat_cb(addr_resolution_t *ar, ip_address_t *address, u8 is_del)
static uword ip6_address_is_equal(const ip6_address_t *a, const ip6_address_t *b)
Definition: ip6_packet.h:167
enum ip_address_family_t_ ip_address_family_t
u32 snat_if_map_length
Definition: cnat_types.h:116
Definition: defs.h:47
static clib_error_t * cnat_snat_init(vlib_main_t *vm)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
u8 * format_cnat_snat_prefix(u8 *s, va_list *args)
VLIB buffer representation.
Definition: buffer.h:111
u64 uword
Definition: types.h:112
static void cnat_compute_prefix_lengths_in_search_order(cnat_snat_exclude_pfx_table_t *table, ip_address_family_t af)
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
cnat_main_t cnat_main
Definition: cnat_types.c:18
#define ip_prefix_version(_a)
Definition: ip_types.h:124
#define vnet_buffer(b)
Definition: buffer.h:437
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
uword clib_bitmap_t
Definition: bitmap.h:50
ip_address_t ce_ip
Definition: cnat_types.h:75
uword unformat_ip_prefix(unformat_input_t *input, va_list *args)
Definition: ip_types.c:64
enum cnat_snat_interface_map_type_t_ cnat_snat_interface_map_type_t
int cnat_set_snat_policy(cnat_snat_policy_type_t policy)
cnat_snat_exclude_pfx_table_t excluded_pfx
int cnat_snat_policy_if_pfx(vlib_buffer_t *b, cnat_session_t *session)
enum cnat_snat_policy_type_t_ cnat_snat_policy_type_t
u8 cnat_resolve_ep(cnat_endpoint_t *ep)
Resolve endpoint address.
Definition: cnat_types.c:63
u32 snat_hash_buckets
Definition: cnat_types.h:112
void cnat_lazy_init()
Lazy initialization when first adding a translation or using snat.
Definition: cnat_types.c:176
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
Definition: defs.h:46
uword snat_hash_memory
Definition: cnat_types.h:109
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163