FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
ct6.c
Go to the documentation of this file.
1 /*
2  * ct6.c - skeleton vpp engine plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/vnet.h>
19 #include <vnet/plugin/plugin.h>
20 #include <ct6/ct6.h>
21 
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vpp/app/version.h>
25 
26 /* define message IDs */
27 #include <ct6/ct6.api_enum.h>
28 #include <ct6/ct6.api_types.h>
29 
30 #define REPLY_MSG_ID_BASE cmp->msg_id_base
32 
34 
35 /* Action function shared between message handler and debug CLI */
36 
37 static void
39 {
40  u32 nworkers = vlib_num_workers ();
41 
42  if (cmp->feature_initialized)
43  return;
44 
45  clib_bihash_init_48_8 (&cmp->session_hash, "ct6 session table",
47  cmp->feature_initialized = 1;
48  vec_validate (cmp->sessions, nworkers);
49  vec_validate_init_empty (cmp->first_index, nworkers, ~0);
50  vec_validate_init_empty (cmp->last_index, nworkers, ~0);
51 }
52 
53 int
55  int enable_disable)
56 {
58  int rv = 0;
59 
60  ct6_feature_init (cmp);
61 
62  /* Utterly wrong? */
64  sw_if_index))
65  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
66 
67  /* Not a physical port? */
70  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
71 
72  vnet_feature_enable_disable ("interface-output", "ct6-in2out",
73  sw_if_index, enable_disable, 0, 0);
74 
75  return rv;
76 }
77 
78 int
80  int enable_disable)
81 {
83  int rv = 0;
84 
85  ct6_feature_init (cmp);
86 
87  /* Utterly wrong? */
89  sw_if_index))
90  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
91 
92  /* Not a physical port? */
95  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
96 
97  vnet_feature_enable_disable ("ip6-unicast", "ct6-out2in",
98  sw_if_index, enable_disable, 0, 0);
99 
100  return rv;
101 }
102 
103 static clib_error_t *
105  unformat_input_t * input,
106  vlib_cli_command_t * cmd)
107 {
108  ct6_main_t *cmp = &ct6_main;
109  u32 sw_if_index = ~0;
110  int enable_disable = 1;
111  u32 inside = ~0;
112  int rv;
113 
115  {
116  if (unformat (input, "disable"))
117  enable_disable = 0;
118  else if (unformat (input, "%U", unformat_vnet_sw_interface,
119  cmp->vnet_main, &sw_if_index))
120  ;
121  else if (unformat (input, "inside") || unformat (input, "in"))
122  inside = 1;
123  else if (unformat (input, "outside") || unformat (input, "out"))
124  inside = 0;
125  else
126  break;
127  }
128 
129  if (inside == ~0)
130  return clib_error_return (0, "Please specify inside or outside");
131 
132  if (sw_if_index == ~0)
133  return clib_error_return (0, "Please specify an interface...");
134 
135  if (inside == 1)
136  rv = ct6_in2out_enable_disable (cmp, sw_if_index, enable_disable);
137  else
138  rv = ct6_out2in_enable_disable (cmp, sw_if_index, enable_disable);
139 
140  switch (rv)
141  {
142  case 0:
143  break;
144 
145  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
146  return clib_error_return
147  (0, "Invalid interface, only works on physical ports");
148  break;
149 
150  default:
151  return clib_error_return (0, "ct6_enable_disable returned %d", rv);
152  }
153  return 0;
154 }
155 
156 /* *INDENT-OFF* */
158 {
159  .path = "set ct6",
160  .short_help =
161  "set ct6 [inside|outside] <interface-name> [disable]",
163 };
164 /* *INDENT-ON* */
165 
166 /* API message handler */
169 {
170  vl_api_ct6_enable_disable_reply_t *rmp;
171  ct6_main_t *cmp = &ct6_main;
172  int rv;
173 
175 
176  if (mp->is_inside)
177  rv = ct6_in2out_enable_disable (cmp, ntohl (mp->sw_if_index),
178  (int) (mp->enable_disable));
179  else
180  rv = ct6_out2in_enable_disable (cmp, ntohl (mp->sw_if_index),
181  (int) (mp->enable_disable));
182 
184  REPLY_MACRO (VL_API_CT6_ENABLE_DISABLE_REPLY);
185 }
186 
187 #include <ct6/ct6.api.c>
188 static clib_error_t *
190 {
191  ct6_main_t *cmp = &ct6_main;
192  clib_error_t *error = 0;
193 
194  cmp->vlib_main = vm;
195  cmp->vnet_main = vnet_get_main ();
196 
197  /* Ask for a correctly-sized block of API message decode slots */
199 
200  /*
201  * Set default parameters...
202  * 256K sessions
203  * 64K buckets
204  * 2 minute inactivity timer
205  * 10000 concurrent sessions
206  */
207  cmp->session_hash_memory = 16ULL << 20;
208  cmp->session_hash_buckets = 64 << 10;
209  cmp->session_timeout_interval = 120.0;
210  cmp->max_sessions_per_worker = 10000;
211 
212  /* ... so the packet generator can feed the in2out node ... */
214  return error;
215 }
216 
218 
219 /* *INDENT-OFF* */
220 VNET_FEATURE_INIT (ct6out2in, static) =
221 {
222  .arc_name = "ip6-unicast",
223  .node_name = "ct6-out2in",
224  .runs_before = VNET_FEATURES ("ip6-lookup"),
225 };
226 /* *INDENT-ON */
227 
228 /* *INDENT-OFF* */
229 VNET_FEATURE_INIT (ct6in2out, static) = {
230  .arc_name = "interface-output",
231  .node_name = "ct6-in2out",
232  .runs_before = VNET_FEATURES ("interface-output-arc-end"),
233 };
234 /* *INDENT-ON */
235 
236 /* *INDENT-OFF* */
238 {
239  .version = VPP_BUILD_VER,
240  .description = "IPv6 Connection Tracker",
241 };
242 /* *INDENT-ON* */
243 
244 u8 *
245 format_ct6_session (u8 * s, va_list * args)
246 {
247  ct6_main_t *cmp = va_arg (*args, ct6_main_t *);
248  int i = va_arg (*args, int);
249  ct6_session_t *s0 = va_arg (*args, ct6_session_t *);
250  int verbose = va_arg (*args, int);
252 
253  if (s0 == 0)
254  {
255  s = format (s, "\n%6s%6s%40s%6s%40s%6s",
256  "Sess", "Prot", "Src", "Sport", "Dst", "Dport");
257  return s;
258  }
259 
260  s = format (s, "\n%6d%6d%40U%6u%40U%6u",
261  s0 - cmp->sessions[i], s0->key.proto,
262  format_ip6_address, &s0->key.src,
263  clib_net_to_host_u16 (s0->key.sport),
264  format_ip6_address, &s0->key.dst,
265  clib_net_to_host_u16 (s0->key.dport));
266 
267  clib_memcpy_fast (&kvp0, s0, sizeof (ct6_session_key_t));
268 
269  if (clib_bihash_search_48_8 (&cmp->session_hash, &kvp0, &kvp0) < 0)
270  {
271  s = format (s, " LOOKUP FAIL!");
272  }
273  else
274  {
275  if (kvp0.value == s0 - cmp->sessions[s0->thread_index])
276  {
277  s = format (s, " OK");
278  if (verbose > 1)
279  {
280  s = format (s, " next %d prev %d", s0->next_index,
281  s0->prev_index);
282  s = format (s, " hits %d expires %.2f", s0->hits, s0->expires);
283  }
284  }
285  else
286  s = format (s, " BOGUS LOOKUP RESULT!");
287  }
288 
289  return s;
290 }
291 
292 static clib_error_t *
294  unformat_input_t * input,
295  vlib_cli_command_t * cmd)
296 {
297  ct6_main_t *cmp = &ct6_main;
298  ct6_session_t *s0;
299  int verbose = 0;
300  u8 *s = 0;
301  int i;
302 
303  if (!cmp->feature_initialized)
304  return clib_error_return (0, "ip6 connection tracking not enabled...");
305 
306  if (unformat (input, "verbose %d", &verbose))
307  ;
308  else if (unformat (input, "verbose"))
309  verbose = 1;
310 
311  for (i = 0; i < vec_len (cmp->sessions); i++)
312  {
313  s = format (s, "Thread %d: %d sessions\n", i,
314  pool_elts (cmp->sessions[i]));
315 
316  if (verbose == 0)
317  continue;
318 
319  s =
320  format (s, "%U", format_ct6_session, cmp,
321  0 /* pool */ , 0 /* header */ , verbose);
322 
323  /* *INDENT-OFF* */
324  pool_foreach (s0, cmp->sessions[i])
325  {
326  s = format (s, "%U", format_ct6_session, cmp, i, s0, verbose);
327  }
328  /* *INDENT-ON* */
329  }
330  vlib_cli_output (cmp->vlib_main, "%v", s);
331  vec_free (s);
332  return 0;
333 }
334 
335 /* *INDENT-OFF* */
337 {
338  .path = "show ip6 connection-tracker",
339  .short_help = "show ip6 connection-tracker",
340  .function = show_ct6_command_fn_command_fn,
341 };
342 /* *INDENT-ON* */
343 
344 static void
345 increment_v6_address (ip6_address_t * a)
346 {
347  u64 v0, v1;
348 
349  v0 = clib_net_to_host_u64 (a->as_u64[0]);
350  v1 = clib_net_to_host_u64 (a->as_u64[1]);
351 
352  v1 += 1;
353  if (v1 == 0)
354  v0 += 1;
355  a->as_u64[0] = clib_net_to_host_u64 (v0);
356  a->as_u64[1] = clib_net_to_host_u64 (v1);
357 }
358 
359 
360 static clib_error_t *
362  unformat_input_t * input,
363  vlib_cli_command_t * cmd)
364 {
365  ct6_main_t *cmp = &ct6_main;
367  ct6_session_key_t *key0;
368  ct6_session_t *s0;
369  u8 src[16], dst[16];
370  u32 recycled = 0, created = 0;
371  int i, num_sessions = 5;
372  u32 midpt_index;
373  u8 *s = 0;
374 
375  cmp->max_sessions_per_worker = 4;
376 
378  {
379  if (unformat (input, "num-sessions %d", &num_sessions))
380  ;
381  else
382  if (unformat
383  (input, "max-sessions %d", &cmp->max_sessions_per_worker))
384  ;
385  else
386  break;
387  }
388 
389  ct6_feature_init (cmp);
390 
391  /* Set up starting src/dst addresses */
392  memset (src, 0, sizeof (src));
393  memset (dst, 0, sizeof (dst));
394 
395  src[0] = 0xdb;
396  dst[0] = 0xbe;
397 
398  src[15] = 1;
399  dst[15] = 1;
400 
401  /*
402  * See if we know about this flow.
403  * Key set up for the out2in path, the performant case
404  */
405  key0 = (ct6_session_key_t *) & kvp0;
406  memset (&kvp0, 0, sizeof (kvp0));
407 
408  for (i = 0; i < num_sessions; i++)
409  {
410  clib_memcpy_fast (&key0->src, src, sizeof (src));
411  clib_memcpy_fast (&key0->dst, dst, sizeof (dst));
412  key0->as_u64[4] = 0;
413  key0->as_u64[5] = 0;
414  key0->sport = clib_host_to_net_u16 (1234);
415  key0->dport = clib_host_to_net_u16 (4321);
416  key0->proto = 17; /* udp, fwiw */
417 
419  (cmp, &kvp0, 3.0 /* now */ , 0 /* thread index */ ,
420  &recycled, &created);
421 
422  s = format (s, "%U (%d, %d)", format_ct6_session, cmp,
423  0 /* thread index */ , s0, 1 /* verbose */ ,
424  recycled, created);
425  vlib_cli_output (vm, "%v", s);
426  vec_free (s);
427  increment_v6_address ((ip6_address_t *) src);
428  recycled = 0;
429  created = 0;
430  }
431 
432  /* *INDENT-OFF* */
433  pool_foreach (s0, cmp->sessions[0])
434  {
435  s = format (s, "%U", format_ct6_session, cmp, 0, s0, 1 /* verbose */);
436  }
437  /* *INDENT-ON* */
438 
439  vlib_cli_output (vm, "\nEnd state: first index %d last index %d\n%v",
440  cmp->first_index[0], cmp->last_index[0], s);
441 
442  vec_free (s);
443 
444  midpt_index = cmp->max_sessions_per_worker / 3;
445 
446  s0 = pool_elt_at_index (cmp->sessions[0], midpt_index);
447  vlib_cli_output (vm, "\nSimulate LRU hit on session %d",
448  s0 - cmp->sessions[0]);
449 
450  ct6_update_session_hit (cmp, s0, 234.0);
451 
452  /* *INDENT-OFF* */
453  pool_foreach (s0, cmp->sessions[0])
454  {
455  s = format (s, "%U", format_ct6_session, cmp, 0, s0, 1 /* verbose */);
456  }
457  /* *INDENT-ON* */
458 
459  vlib_cli_output (vm, "\nEnd state: first index %d last index %d\n%v",
460  cmp->first_index[0], cmp->last_index[0], s);
461 
462  vec_free (s);
463 
464  return 0;
465 }
466 
467 /* *INDENT-OFF* */
469 {
470  .path = "test ip6 connection-tracker",
471  .short_help = "test ip6 connection-tracker",
472  .function = test_ct6_command_fn_command_fn,
473 };
474 /* *INDENT-ON* */
475 
476 static clib_error_t *
478 {
479  ct6_main_t *cmp = &ct6_main;
480 
482  {
483  if (unformat (input, "session-hash-buckets %u",
484  &cmp->session_hash_buckets))
485  ;
486  else if (unformat (input, "session-hash-memory %U",
488  ;
489  else if (unformat (input, "session-timeout %f",
491  ;
492  else
493  {
494  return clib_error_return (0, "unknown input '%U'",
495  format_unformat_error, input);
496  }
497  }
498  return 0;
499 }
500 
502 
503 /*
504  * fd.io coding-style-patch-verification: ON
505  *
506  * Local Variables:
507  * eval: (c-set-style "gnu")
508  * End:
509  */
VALIDATE_SW_IF_INDEX
#define VALIDATE_SW_IF_INDEX(mp)
Definition: api_helper_macros.h:281
vlib_num_workers
static u32 vlib_num_workers()
Definition: threads.h:354
api.h
set_ct6_enable_disable_command_fn
static clib_error_t * set_ct6_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ct6.c:104
vnet_sw_interface_t::type
vnet_sw_interface_type_t type
Definition: interface.h:870
vnet_sw_interface_t
Definition: interface.h:868
ct6_main_t::first_index
u32 * first_index
Definition: ct6.h:69
ct6_session_t::thread_index
u32 thread_index
Definition: ct6.h:51
ethernet_setup_node
static void ethernet_setup_node(vlib_main_t *vm, u32 node_index)
Definition: ethernet.h:408
set_ct6_command
static vlib_cli_command_t set_ct6_command
(constructor) VLIB_CLI_COMMAND (set_ct6_command)
Definition: ct6.c:157
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
ct6_session_t::key
ct6_session_key_t key
Definition: ct6.h:50
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
ct6_update_session_hit
static void ct6_update_session_hit(ct6_main_t *cmp, ct6_session_t *s0, f64 now)
Definition: ct6.h:165
increment_v6_address
static void increment_v6_address(ip6_address_t *a)
Definition: ct6.c:345
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
api.h
vl_api_ct6_enable_disable_t::enable_disable
bool enable_disable
Definition: ct6.api:14
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
ct6_in2out_node
vlib_node_registration_t ct6_in2out_node
(constructor) VLIB_REGISTER_NODE (ct6_in2out_node)
Definition: ct6_in2out.c:349
VNET_FEATURE_INIT
VNET_FEATURE_INIT(ct6out2in, static)
unformat_input_t
struct _unformat_input_t unformat_input_t
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
error
Definition: cJSON.c:88
test_ct6_command_fn_command
static vlib_cli_command_t test_ct6_command_fn_command
(constructor) VLIB_CLI_COMMAND (test_ct6_command_fn_command)
Definition: ct6.c:468
ct6_session_t::hits
u32 hits
Definition: ct6.h:54
ct6_main_t
Definition: ct6.h:58
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ct6_main_t::session_hash
clib_bihash_48_8_t session_hash
Definition: ct6.h:64
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
setup_message_id_table
static void setup_message_id_table(api_main_t *am)
Definition: bfd_api.c:451
VLIB_PLUGIN_REGISTER
VLIB_PLUGIN_REGISTER()
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
ct6_session_t::prev_index
u32 prev_index
Definition: ct6.h:53
unformat_memory_size
unformat_function_t unformat_memory_size
Definition: format.h:288
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vl_api_ct6_enable_disable_t_handler
static void vl_api_ct6_enable_disable_t_handler(vl_api_ct6_enable_disable_t *mp)
Definition: ct6.c:168
ct6_main_t::vnet_main
vnet_main_t * vnet_main
Definition: ct6.h:80
ct6_main_t::sessions
ct6_session_t ** sessions
Definition: ct6.h:68
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
ct6_out2in_enable_disable
int ct6_out2in_enable_disable(ct6_main_t *cmp, u32 sw_if_index, int enable_disable)
Definition: ct6.c:79
REPLY_MACRO
#define REPLY_MACRO(t)
Definition: api_helper_macros.h:30
vl_api_ct6_enable_disable_t
Definition: ct6.api:6
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
ct6_feature_init
static void ct6_feature_init(ct6_main_t *cmp)
Definition: ct6.c:38
vl_api_ct6_enable_disable_t::is_inside
bool is_inside
Definition: ct6.api:17
ct6_session_t::expires
f64 expires
Definition: ct6.h:55
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
ct6_main_t::feature_initialized
u8 feature_initialized
Definition: ct6.h:65
src
vl_api_address_t src
Definition: gre.api:54
show_ct6_command_fn_command
static vlib_cli_command_t show_ct6_command_fn_command
(constructor) VLIB_CLI_COMMAND (show_ct6_command_fn_command)
Definition: ct6.c:336
ct6_main_t::msg_id_base
u16 msg_id_base
Definition: ct6.h:61
ct6_main_t::session_hash_memory
uword session_hash_memory
Definition: ct6.h:74
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
vnet_interface_main_t::sw_interfaces
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:1014
ct6_main_t::session_hash_buckets
u32 session_hash_buckets
Definition: ct6.h:75
ct6_main_t::vlib_main
vlib_main_t * vlib_main
Definition: ct6.h:79
BAD_SW_IF_INDEX_LABEL
#define BAD_SW_IF_INDEX_LABEL
Definition: api_helper_macros.h:289
plugin.h
ct6_create_or_recycle_session
ct6_session_t * ct6_create_or_recycle_session(ct6_main_t *cmp, clib_bihash_kv_48_8_t *kvpp, f64 now, u32 my_thread_index, u32 *recyclep, u32 *createp)
Definition: ct6_in2out.c:77
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
u64
unsigned long u64
Definition: types.h:89
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:459
format
description fragment has unexpected format
Definition: map.api:433
vec_validate_init_empty
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header,...
Definition: vec.h:570
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ct6.h
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
ct6_session_t
Definition: ct6.h:48
api_helper_macros.h
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
vnet_feature_enable_disable
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: pnat_test_stubs.h:50
vlib_main_t
Definition: main.h:102
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
format_ct6_session
u8 * format_ct6_session(u8 *s, va_list *args)
Definition: ct6.c:245
clib_bihash_kv_48_8_t::value
u64 value
Definition: bihash_48_8.h:42
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
a
a
Definition: bitmap.h:544
ct6_in2out_enable_disable
int ct6_in2out_enable_disable(ct6_main_t *cmp, u32 sw_if_index, int enable_disable)
Definition: ct6.c:54
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
ct6_main_t::max_sessions_per_worker
u32 max_sessions_per_worker
Definition: ct6.h:76
ct6_session_t::next_index
u32 next_index
Definition: ct6.h:52
vl_api_ct6_enable_disable_t::sw_if_index
vl_api_interface_index_t sw_if_index
Definition: ct6.api:20
ct6_init
static clib_error_t * ct6_init(vlib_main_t *vm)
Definition: ct6.c:189
ct6_main_t::session_timeout_interval
f64 session_timeout_interval
Definition: ct6.h:73
rv
int __clib_unused rv
Definition: application.c:491
ct6_config
static clib_error_t * ct6_config(vlib_main_t *vm, unformat_input_t *input)
Definition: ct6.c:477
vnet.h
VNET_SW_INTERFACE_TYPE_HARDWARE
@ VNET_SW_INTERFACE_TYPE_HARDWARE
Definition: interface.h:763
vlib_cli_command_t
Definition: cli.h:92
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
ct6_main_t::last_index
u32 * last_index
Definition: ct6.h:70
ct6_main
ct6_main_t ct6_main
Definition: ct6.c:33
test_ct6_command_fn_command_fn
static clib_error_t * test_ct6_command_fn_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ct6.c:361
clib_bihash_kv_48_8_t
Definition: bihash_48_8.h:39
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
show_ct6_command_fn_command_fn
static clib_error_t * show_ct6_command_fn_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ct6.c:293
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137