FD.io VPP  v16.09
Vector Packet Processing
sticky_hash.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include <vnet/l2/l2_classify.h>
16 
17 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vnet/pg/pg.h>
20 #include <vnet/ip/ip.h>
21 #include <vnet/ip/ip_packet.h>
22 #include <vnet/ip/ip4_packet.h>
23 #include <vnet/ip/ip6_packet.h>
24 #include <vppinfra/error.h>
25 
26 typedef struct
27 {
30  /* Not strictly needed, for show command */
33 
34 typedef struct
35 {
37 
38  /* next index added to l2_classify */
40 
41  /* session pool */
43 
44  /* Forward and reverse data session setup buffers */
45  u8 fdata[3 * sizeof (u32x4)];
46  u8 rdata[3 * sizeof (u32x4)];
47 
48  /* convenience variables */
53 }
55 
56 typedef struct
57 {
58  /* $$$$ fill in with per-pkt trace data */
62 
63 /* packet trace format function */
64 static u8 *
65 format_sticky_hash_miss_trace (u8 * s, va_list * args)
66 {
67  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
68  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
70 
71  s = format (s, "STICKY_HASH_MISS: sw_if_index %d", t->sw_if_index);
72  return s;
73 }
74 
75 typedef CLIB_PACKED (struct
76  {
78  }) classify_data_or_mask_t;
79 
80 sticky_hash_main_t sticky_hash_main;
81 
83 
84 #define foreach_sticky_hash_miss_error \
85 _(MISSES, "forward flow classify misses")
86 
87 typedef enum
88 {
89 #define _(sym,str) STICKY_HASH_MISS_ERROR_##sym,
91 #undef _
92  STICKY_HASH_MISS_N_ERROR,
94 
95 static char *sticky_hash_miss_error_strings[] = {
96 #define _(sym,string) string,
98 #undef _
99 };
100 
101 /*
102  * To drop a pkt and increment one of the previous counters:
103  *
104  * set b0->error = error_node->errors[STICKY_HASH_MISS_ERROR_EXAMPLE];
105  * set next0 to a disposition index bound to "error-drop".
106  *
107  * To manually increment the specific counter STICKY_HASH_MISS_ERROR_EXAMPLE:
108  *
109  * vlib_node_t *n = vlib_get_node (vm, sticky_hash_miss.index);
110  * u32 node_counter_base_index = n->error_heap_index;
111  * vlib_error_main_t * em = &vm->error_main;
112  * em->counters[node_counter_base_index + STICKY_HASH_MISS_ERROR_EXAMPLE] += 1;
113  *
114  */
115 
116 typedef enum
117 {
121 
122 static uword
124  vlib_node_runtime_t * node, vlib_frame_t * frame)
125 {
126  u32 n_left_from, *from, *to_next;
127  sticky_hash_miss_next_t next_index;
128  sticky_hash_main_t *mp = &sticky_hash_main;
129  vlib_node_t *n = vlib_get_node (vm, sticky_hash_miss_node.index);
130  u32 node_counter_base_index = n->error_heap_index;
131  vlib_error_main_t *em = &vm->error_main;
133  ip4_main_t *im = &ip4_main;
134 
135  from = vlib_frame_vector_args (frame);
136  n_left_from = frame->n_vectors;
137  next_index = node->cached_next_index;
138 
139  while (n_left_from > 0)
140  {
141  u32 n_left_to_next;
142 
143  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
144 
145  while (n_left_from > 0 && n_left_to_next > 0)
146  {
147  u32 bi0;
148  vlib_buffer_t *b0;
149  u32 next0;
150  u32 sw_if_index0;
151  u32 fib_index0, ft_index0, rt_index0;
152  vnet_classify_table_3_t *ft0, *rt0;
153  vnet_classify_entry_3_t *fe0, *re0;
154  classify_data_or_mask_t *h0;
155  u8 was_found0;
156  ip4_fib_t *fib0;
158  u32 tmp;
159 
160  /* speculatively enqueue b0 to the current next frame */
161  bi0 = from[0];
162  to_next[0] = bi0;
163  from += 1;
164  to_next += 1;
165  n_left_from -= 1;
166  n_left_to_next -= 1;
167 
168  b0 = vlib_get_buffer (vm, bi0);
169 
170  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
171  next0 = mp->cached_next_index;
172 
173  h0 = vlib_buffer_get_current (b0);
174 
175  /* Add forward and reverse entries for this flow */
176  clib_memcpy (mp->fdata, h0, sizeof (mp->fdata));
177  clib_memcpy (mp->rdata, h0, sizeof (mp->rdata));
178 
179  h0 = (classify_data_or_mask_t *) (mp->rdata);
180 
181  /* swap src + dst addresses to form reverse data */
182  tmp = h0->ip.src_address.as_u32;
183  h0->ip.src_address.as_u32 = h0->ip.dst_address.as_u32;
184  h0->ip.dst_address.as_u32 = tmp;
185 
186  /* dig up fwd + rev tables */
187  fib_index0 = vec_elt (im->fib_index_by_sw_if_index, sw_if_index0);
188  fib0 = vec_elt_at_index (im->fibs, fib_index0);
189 
190  ft_index0 = fib0->fwd_classify_table_index;
191  rt_index0 = fib0->rev_classify_table_index;
192 
193  ft0 = (vnet_classify_table_3_t *)
194  pool_elt_at_index (cm->tables, ft_index0);
195  rt0 = (vnet_classify_table_3_t *)
196  pool_elt_at_index (cm->tables, rt_index0);
197 
198  fe0 =
199  vnet_classify_find_or_add_entry_3 (ft0, mp->fdata, &was_found0);
200  fe0->next_index = L2_CLASSIFY_NEXT_IP4_INPUT;
201  fe0->advance = sizeof (ethernet_header_t);
202 
203  re0 = vnet_classify_find_or_add_entry_3 (rt0, mp->rdata, 0);
204  re0->next_index = L2_CLASSIFY_NEXT_IP4_INPUT; /* $$$ FIXME */
205  re0->advance = sizeof (ethernet_header_t);
206 
207  /* Note: we could get a whole vector of misses for the same sess */
208  if (was_found0 == 0)
209  {
210  pool_get (mp->sessions, s);
211 
212  fe0->opaque_index = s - mp->sessions;
213  re0->opaque_index = s - mp->sessions;
214 
215  s->fwd_entry_index = fe0 - ft0->entries;
216  s->rev_entry_index = re0 - rt0->entries;
217  s->fib_index = fib_index0;
218  }
219 
221  && (b0->flags & VLIB_BUFFER_IS_TRACED)))
222  {
224  vlib_add_trace (vm, node, b0, sizeof (*t));
225  t->sw_if_index = sw_if_index0;
226  t->next_index = next0;
227  }
228 
229  em->counters[node_counter_base_index +
230  STICKY_HASH_MISS_ERROR_MISSES] += 1;
231 
232  vlib_buffer_advance (b0, sizeof (ethernet_header_t));
233 
234  /* verify speculative enqueue, maybe switch current next frame */
235  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
236  to_next, n_left_to_next,
237  bi0, next0);
238  }
239 
240  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
241  }
242 
243  return frame->n_vectors;
244 }
245 
246 /* *INDENT-OFF* */
247 VLIB_REGISTER_NODE (sticky_hash_miss_node) = {
248  .function = sticky_hash_miss_node_fn,
249  .name = "sticky-hash-miss",
250  .vector_size = sizeof (u32),
251  .format_trace = format_sticky_hash_miss_trace,
253 
254  .n_errors = ARRAY_LEN(sticky_hash_miss_error_strings),
255  .error_strings = sticky_hash_miss_error_strings,
256 
257  .n_next_nodes = STICKY_HASH_MISS_N_NEXT,
258 
259  /* edit / add dispositions here */
260  .next_nodes = {
261  [STICKY_HASH_MISS_NEXT_IP4_INPUT] = "ip4-input",
262  },
263 };
264 /* *INDENT-ON* */
265 
266 clib_error_t *
268 {
269  sticky_hash_main_t *mp = &sticky_hash_main;
270 
271  mp->vlib_main = vm;
272  mp->vnet_main = vnet_get_main ();
275 
276  return 0;
277 }
278 
280 
283  u32 fwd_sw_if_index, u8 * fwd_mask,
284  u32 rev_sw_if_index, u8 * rev_mask, u32 nbuckets, int enable_disable)
285 {
286  ip4_main_t *im = &ip4_main;
287  u32 fib_index;
288  ip4_fib_t *fib;
291  vnet_classify_table_3_t *ft, *rt;
292 
293  fib_index = vec_elt (im->fib_index_by_sw_if_index, fwd_sw_if_index);
294  fib = vec_elt_at_index (im->fibs, fib_index);
295 
296  if (fib->fwd_classify_table_index == ~0)
297  {
298  /* Set up forward table */
299  ft = (vnet_classify_table_3_t *)
300  vnet_classify_new_table (cm, fwd_mask, nbuckets,
301  0 /* skip */ , 3 /* match */ );
303  = ft - (vnet_classify_table_3_t *) cm->tables;
304  mp->fwd_miss_next_index =
306  sticky_hash_miss_node.index);
307  ft->miss_next_index = mp->fwd_miss_next_index;
308 
309  /* Set up reverse table */
310  rt = (vnet_classify_table_3_t *)
311  vnet_classify_new_table (cm, rev_mask, nbuckets,
312  0 /* skip */ , 3 /* match */ );
314  = rt - (vnet_classify_table_3_t *) cm->tables;
315  }
316 
319  fwd_sw_if_index);
320 
323  fwd_sw_if_index);
324 
327  fwd_sw_if_index);
328 
330  [fwd_sw_if_index] = fib->fwd_classify_table_index;
331 
333  [fwd_sw_if_index] = ~0;
334 
336  [fwd_sw_if_index] = ~0;
337 
338 
341  rev_sw_if_index);
342 
345  rev_sw_if_index);
346 
349  rev_sw_if_index);
350 
351 
353  [rev_sw_if_index] = fib->rev_classify_table_index;
354 
356  [rev_sw_if_index] = ~0;
357 
359  [rev_sw_if_index] = ~0;
360 
361  vnet_l2_classify_enable_disable (fwd_sw_if_index, enable_disable);
362  vnet_l2_classify_enable_disable (rev_sw_if_index, enable_disable);
363  return 0;
364 }
365 
366 static clib_error_t *
368  unformat_input_t * input,
369  vlib_cli_command_t * cmd)
370 {
371  u32 fwd_sw_if_index = ~0, rev_sw_if_index = ~0;
372  int enable_disable = 1;
373  u32 nbuckets = 2;
374  int rv;
375  sticky_hash_main_t *mp = &sticky_hash_main;
376  classify_data_or_mask_t fwd_mask, rev_mask;
377  u8 *fm = 0, *rm = 0;
378 
380  {
381  if (unformat
382  (input, "fwd %U", unformat_vnet_sw_interface, mp->vnet_main,
383  &fwd_sw_if_index))
384  ;
385  if (unformat
386  (input, "rev %U", unformat_vnet_sw_interface, mp->vnet_main,
387  &rev_sw_if_index))
388  ;
389  else if (unformat (input, "nbuckets %d", &nbuckets))
390  ;
391  else if (unformat (input, "disable"))
392  enable_disable = 0;
393 
394  else
395  break;
396  }
397 
398  nbuckets = 1 << max_log2 (nbuckets);
399 
400  if (fwd_sw_if_index == ~0)
401  return clib_error_return (0, "fwd interface not set");
402 
403  if (rev_sw_if_index == ~0)
404  return clib_error_return (0, "rev interface not set");
405 
406  if (!is_pow2 (nbuckets))
407  return clib_error_return (0, "nbuckets %d not a power of 2", nbuckets);
408 
409  ASSERT (sizeof (fwd_mask) <= 3 * sizeof (u32x4));
410 
411  /* Mask on src/dst address, depending on direction */
412  memset (&fwd_mask, 0, sizeof (fwd_mask));
413  memset (&fwd_mask.ip.src_address, 0xff, 4);
414 
415  memset (&rev_mask, 0, sizeof (rev_mask));
416  memset (&rev_mask.ip.dst_address, 0xff, 4);
417 
418  vec_validate (fm, 3 * sizeof (u32x4) - 1);
419  vec_validate (rm, 3 * sizeof (u32x4) - 1);
420 
421  clib_memcpy (fm, &fwd_mask, sizeof (fwd_mask));
422  clib_memcpy (rm, &rev_mask, sizeof (rev_mask));
423 
424  rv = ip4_sticky_hash_enable_disable (mp, fwd_sw_if_index, fm,
425  rev_sw_if_index, rm,
426  nbuckets, enable_disable);
427 
428  vec_free (fm);
429  vec_free (rm);
430  switch (rv)
431  {
432  case 0:
433  return 0;
434 
435  default:
436  return clib_error_return (0,
437  "ip4_sticky_hash_enable_disable returned %d",
438  rv);
439  }
440 
441  return 0;
442 }
443 
444 /* *INDENT-OFF* */
445 VLIB_CLI_COMMAND (sticky_hash_init_command, static) = {
446  .path = "ip sticky classify",
447  .short_help = "ip sticky classify fwd <intfc> rev <intfc> "
448  "[nbuckets <nn>][disable]",
450 };
451 /* *INDENT-ON* */
452 
453 
454 u8 *
455 format_sticky_hash_session (u8 * s, va_list * args)
456 {
457  sticky_hash_main_t *mp = va_arg (*args, sticky_hash_main_t *);
458  sticky_hash_session_t *session = va_arg (*args, sticky_hash_session_t *);
459  vnet_classify_table_3_t *t;
460  vnet_classify_entry_3_t *e;
461  ip4_main_t *im = &ip4_main;
463  ip4_fib_t *fib;
464  classify_data_or_mask_t *match;
465 
466  fib = vec_elt_at_index (im->fibs, session->fib_index);
467 
468  t = (vnet_classify_table_3_t *)
469  pool_elt_at_index (cm->tables, fib->fwd_classify_table_index);
470  e = pool_elt_at_index (t->entries, session->fwd_entry_index);
471  match = (classify_data_or_mask_t *) (e->key);
472 
473  s = format
474  (s,
475  "[%6d] fwd src %U next index %d session %d fib %d\n"
476  " hits %lld last-heard %.6f\n",
477  e - t->entries,
478  format_ip4_address, &match->ip.src_address,
479  e->next_index, e->opaque_index, fib->table_id, e->hits, e->last_heard);
480 
481  if (e->opaque_index != session - mp->sessions)
482  s = format (s, "WARNING: forward session index mismatch!\n");
483 
484  t = (vnet_classify_table_3_t *)
485  pool_elt_at_index (cm->tables, fib->rev_classify_table_index);
486  e = pool_elt_at_index (t->entries, session->rev_entry_index);
487  match = (classify_data_or_mask_t *) (e->key);
488 
489  s = format
490  (s,
491  "[%6d] rev dst %U next index %d session %d\n"
492  " hits %lld last-heard %.6f\n",
493  e - t->entries,
494  format_ip4_address, &match->ip.dst_address,
495  e->next_index, e->opaque_index, e->hits, e->last_heard);
496 
497  if (e->opaque_index != session - mp->sessions)
498  s = format (s, "WARNING: reverse session index mismatch!\n");
499  s = format (s, "---------\n");
500 
501  return s;
502 }
503 
504 static clib_error_t *
506  unformat_input_t * input,
507  vlib_cli_command_t * cmd)
508 {
509  sticky_hash_main_t *mp = &sticky_hash_main;
511  int verbose = 0;
512  int dump_classifier_tables = 0;
513  ip4_fib_t *fib;
514  ip4_main_t *im4 = &ip4_main;
516 
518  {
519  if (unformat (input, "verbose"))
520  verbose = 1;
521  else if (unformat (input, "dump-tables")
522  || unformat (input, "dump-classifier-tables"))
523  dump_classifier_tables = 1;
524  else
525  break;
526  }
527 
528  if (pool_elts (mp->sessions) == 0)
529  vlib_cli_output (vm, "No ip sticky hash sessions");
530 
531 
532  vlib_cli_output (vm, "%d active sessions\n", pool_elts (mp->sessions));
533 
534  vec_foreach (fib, im4->fibs)
535  {
536  if (fib->fwd_classify_table_index != ~0)
537  vlib_cli_output (vm, "fib %d fwd table: \n%U",
538  fib->table_id,
540  cm,
542  (cm->tables, fib->fwd_classify_table_index),
543  dump_classifier_tables);
544  if (fib->rev_classify_table_index != ~0)
545  vlib_cli_output (vm, "fib %d rev table: \n%U",
546  fib->table_id,
548  cm,
550  (cm->tables, fib->rev_classify_table_index),
551  dump_classifier_tables);
552  }
553 
554  if (verbose)
555  {
556  /* *INDENT-OFF* */
557  pool_foreach (s, mp->sessions,
558  ({
559  vlib_cli_output (vm, "%U", format_sticky_hash_session, mp, s);
560  }));
561  /* *INDENT-ON* */
562  }
563  return 0;
564 }
565 
566 /* *INDENT-OFF* */
567 VLIB_CLI_COMMAND (show_sticky_hash_command, static) = {
568  .path = "show sticky classify",
569  .short_help = "Display sticky classifier tables",
571 };
572 /* *INDENT-ON* */
573 
574 
575 /*
576  * fd.io coding-style-patch-verification: ON
577  *
578  * Local Variables:
579  * eval: (c-set-style "gnu")
580  * End:
581  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:457
u32 error_heap_index
Definition: node.h:278
#define CLIB_UNUSED(x)
Definition: clib.h:79
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static u8 * format_sticky_hash_miss_trace(u8 *s, va_list *args)
Definition: sticky_hash.c:65
sticky_hash_session_t * sessions
Definition: sticky_hash.c:42
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
vlib_node_registration_t sticky_hash_miss_node
(constructor) VLIB_REGISTER_NODE (sticky_hash_miss_node)
Definition: sticky_hash.c:247
u8 rdata[3 *sizeof(u32x4)]
Definition: sticky_hash.c:46
u32 table_id
Definition: ip4.h:59
#define foreach_sticky_hash_miss_error
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
struct _vlib_node_registration vlib_node_registration_t
static char * sticky_hash_miss_error_strings[]
Definition: sticky_hash.c:95
u8 fdata[3 *sizeof(u32x4)]
Definition: sticky_hash.c:45
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:123
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
format_function_t format_ip4_address
Definition: format.h:71
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1061
vnet_classify_main_t * vnet_classify_main
Definition: sticky_hash.c:51
u32 fwd_classify_table_index
Definition: ip4.h:68
u32 * classify_table_index_by_sw_if_index[L2_CLASSIFY_N_TABLES]
Definition: l2_classify.h:61
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:187
vlib_main_t * vlib_main
Definition: sticky_hash.c:49
unsigned long long u32x4
Definition: ixge.c:28
vnet_classify_table_t * vnet_classify_new_table(vnet_classify_main_t *cm, u8 *mask, u32 nbuckets, u32 memory_size, u32 skip_n_vectors, u32 match_n_vectors)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 * format_sticky_hash_session(u8 *s, va_list *args)
Definition: sticky_hash.c:455
void vnet_l2_classify_enable_disable(u32 sw_if_index, int enable_disable)
Definition: l2_classify.c:433
u32 rev_classify_table_index
Definition: ip4.h:69
l2_classify_main_t l2_classify_main
Definition: l2_classify.c:51
sticky_hash_miss_next_t
Definition: sticky_hash.c:116
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
vlib_error_main_t error_main
Definition: main.h:124
clib_error_t * sticky_hash_miss_init(vlib_main_t *vm)
Definition: sticky_hash.c:267
#define PREDICT_FALSE(x)
Definition: clib.h:97
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:130
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:348
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
u64 * counters
Definition: error.h:78
u16 n_vectors
Definition: node.h:344
vnet_main_t * vnet_main
Definition: sticky_hash.c:50
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
Definition: ip4.h:48
u8 * format_classify_table(u8 *s, va_list *args)
#define clib_memcpy(a, b, c)
Definition: string.h:63
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:200
typedef CLIB_PACKED(struct{ethernet_header_t eh;ip4_header_t ip;})
Definition: sticky_hash.c:75
vlib_node_registration_t l2_classify_node
(constructor) VLIB_REGISTER_NODE (l2_classify_node)
Definition: l2_classify.c:53
#define ARRAY_LEN(x)
Definition: clib.h:59
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:50
u16 cached_next_index
Definition: node.h:462
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
ip4_fib_t * fibs
Vector of FIBs.
Definition: ip4.h:118
#define vnet_buffer(b)
Definition: buffer.h:335
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:418
static clib_error_t * show_ip4_sticky_hash_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: sticky_hash.c:505
IPv4 main type.
Definition: ip4.h:114
l2_classify_main_t * l2_classify_main
Definition: sticky_hash.c:52
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
vnet_classify_main_t vnet_classify_main
Definition: vnet_classify.c:21
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:93
static uword is_pow2(uword x)
Definition: clib.h:266
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
#define vec_elt(v, i)
Get vector value at index i.
static int ip4_sticky_hash_enable_disable(sticky_hash_main_t *mp, u32 fwd_sw_if_index, u8 *fwd_mask, u32 rev_sw_if_index, u8 *rev_mask, u32 nbuckets, int enable_disable)
Definition: sticky_hash.c:282
static uword sticky_hash_miss_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: sticky_hash.c:123
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
unsigned char u8
Definition: types.h:56
static uword max_log2(uword x)
Definition: clib.h:222
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:251
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1578
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
#define vec_foreach(var, vec)
Vector iterator.
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
static clib_error_t * ip4_sticky_hash_init_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: sticky_hash.c:367
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:85
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
sticky_hash_miss_error_t
Definition: sticky_hash.c:93
Definition: defs.h:46
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109