FD.io VPP  v21.01.1
Vector Packet Processing
classify_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * classify_api.c - classify api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 
30 #include <vnet/l2/l2_classify.h>
31 #include <vnet/ip/ip6.h>
32 #include <vnet/ip/ip4.h>
33 
34 #include <vnet/vnet_msg_enum.h>
35 
36 #define vl_typedefs /* define message structures */
37 #include <vnet/vnet_all_api_h.h>
38 #undef vl_typedefs
39 
40 #define vl_endianfun /* define message structures */
41 #include <vnet/vnet_all_api_h.h>
42 #undef vl_endianfun
43 
44 /* instantiate all the print functions we know about */
45 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
46 #define vl_printfun
47 #include <vnet/vnet_all_api_h.h>
48 #undef vl_printfun
49 
51 
52 #define foreach_vpe_api_msg \
53 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
54 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
55 _(CLASSIFY_TABLE_IDS, classify_table_ids) \
56 _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
57 _(CLASSIFY_TABLE_INFO, classify_table_info) \
58 _(CLASSIFY_SESSION_DUMP, classify_session_dump) \
59 _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \
60 _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
61 _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
62 _(FLOW_CLASSIFY_DUMP, flow_classify_dump) \
63 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
64 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
65 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
66 _(OUTPUT_ACL_SET_INTERFACE, output_acl_set_interface) \
67 _(CLASSIFY_PCAP_LOOKUP_TABLE, classify_pcap_lookup_table) \
68 _(CLASSIFY_PCAP_SET_TABLE, classify_pcap_set_table) \
69 _(CLASSIFY_PCAP_GET_TABLES, classify_pcap_get_tables) \
70 _(CLASSIFY_TRACE_LOOKUP_TABLE, classify_trace_lookup_table) \
71 _(CLASSIFY_TRACE_SET_TABLE, classify_trace_set_table) \
72 _(CLASSIFY_TRACE_GET_TABLES, classify_trace_get_tables) \
73 
74 
75 #define foreach_classify_add_del_table_field \
76 _(table_index) \
77 _(nbuckets) \
78 _(memory_size) \
79 _(skip_n_vectors) \
80 _(match_n_vectors) \
81 _(next_table_index) \
82 _(miss_next_index) \
83 _(mask_len)
84 
85 
88 {
92  int rv = 0;
93  u32 table_index = ~0;
94 
96  if (!reg)
97  return;
98 
99  u32 n_skip = ntohl (mp->skip_n_vectors);
100  u32 n_match = ntohl (mp->match_n_vectors);
101  u32 mask_len = ntohl (mp->mask_len);
102  u32 sw_if_index = ntohl (mp->sw_if_index);
103 
104  if (n_skip > 5
105  || 0 <= n_match || n_match > 5
106  || mask_len != n_match * sizeof (u32x4)
107  || sw_if_index == ~0
108  || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index))
109  {
110  rv = VNET_API_ERROR_INVALID_VALUE;
111  goto out;
112  }
113 
114  u32 table_chain;
115  table_chain = classify_get_pcap_chain (cm, sw_if_index);
116 
117  u8 *mask_vec = 0;
118  vec_validate (mask_vec, mask_len - 1);
119  clib_memcpy (mask_vec, mp->mask, mask_len);
120 
121  if (table_chain != ~0)
122  table_index = classify_lookup_chain (table_chain,
123  mask_vec, n_skip, n_match);
124 
125  vec_free (mask_vec);
126 
127 out:
128  rmp = vl_msg_api_alloc (sizeof (*rmp));
129  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_LOOKUP_TABLE_REPLY);
130  rmp->context = mp->context;
131  rmp->retval = ntohl (rv);
132  rmp->table_index = htonl (table_index);
133 
134  vl_api_send_msg (reg, (u8 *) rmp);
135 }
136 
139 {
143  int rv = 0;
144 
146  if (!reg)
147  return;
148 
149  u32 table_index = ntohl (mp->table_index);
150  u32 sw_if_index = ntohl (mp->sw_if_index);
151 
152  if (sw_if_index == ~0
153  || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index)
154  || (table_index != ~0 && pool_is_free_index (cm->tables, table_index)))
155  {
156  rv = VNET_API_ERROR_INVALID_VALUE;
157  goto out;
158  }
159 
160  /*
161  * Maybe reorder tables such that masks are most-specify to least-specific.
162  */
163  if (table_index != ~0 && mp->sort_masks)
164  table_index = classify_sort_table_chain (cm, table_index);
165 
166  classify_set_pcap_chain (cm, sw_if_index, table_index);
167 
168 out:
169  rmp = vl_msg_api_alloc (sizeof (*rmp));
170  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_SET_TABLE_REPLY);
171  rmp->context = mp->context;
172  rmp->retval = ntohl (rv);
173  rmp->table_index = htonl (table_index);
174 
175  vl_api_send_msg (reg, (u8 *) rmp);
176 }
177 
180 {
184  int rv = 0;
185  u32 *tables = 0;
186  u32 count;
187 
189  if (!reg)
190  return;
191 
192  u32 sw_if_index = ntohl (mp->sw_if_index);
193  if (sw_if_index == ~0
194  || sw_if_index >= vec_len (cm->classify_table_index_by_sw_if_index))
195  {
196  rv = VNET_API_ERROR_INVALID_VALUE;
197  goto out;
198  }
199 
200  u32 table_index = classify_get_pcap_chain (cm, sw_if_index);
201  if (table_index == ~0)
202  goto out;
203 
204  /*
205  * Form a vector of all classifier tables in this chain.
206  */
208  u32 i;
209 
210  for (i = table_index; i != ~0; i = t->next_table_index)
211  {
212  vec_add1 (tables, i);
213  t = pool_elt_at_index (cm->tables, i);
214  }
215 
216 out:
217  count = vec_len (tables);
218  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
219  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_PCAP_GET_TABLES_REPLY);
220  rmp->context = mp->context;
221  rmp->retval = ntohl (rv);
222  rmp->count = htonl (count);
223 
224  for (i = 0; i < count; ++i)
225  {
226  rmp->indices[i] = htonl (tables[i]);
227  }
228 
229  vec_free (tables);
230 
231  vl_api_send_msg (reg, (u8 *) rmp);
232 }
233 
234 
237 {
240  int rv = 0;
241  u32 table_index = ~0;
242 
244  if (!reg)
245  return;
246 
247  u32 n_skip = ntohl (mp->skip_n_vectors);
248  u32 n_match = ntohl (mp->match_n_vectors);
249  u32 mask_len = ntohl (mp->mask_len);
250  if (n_skip > 5
251  || n_match == 0 || n_match > 5 || mask_len != n_match * sizeof (u32x4))
252  {
253  rv = VNET_API_ERROR_INVALID_VALUE;
254  goto out;
255  }
256 
257  u32 table_chain;
258  table_chain = classify_get_trace_chain ();
259 
260  u8 *mask_vec = 0;
261  vec_validate (mask_vec, mask_len - 1);
262  clib_memcpy (mask_vec, mp->mask, mask_len);
263 
264  if (table_chain != ~0)
265  table_index = classify_lookup_chain (table_chain,
266  mask_vec, n_skip, n_match);
267  vec_free (mask_vec);
268 
269 out:
270  rmp = vl_msg_api_alloc (sizeof (*rmp));
271  rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TRACE_LOOKUP_TABLE_REPLY));
272  rmp->context = mp->context;
273  rmp->retval = ntohl (rv);
274  rmp->table_index = htonl (table_index);
275 
276  vl_api_send_msg (reg, (u8 *) rmp);
277 }
278 
281 {
285  int rv = 0;
286 
288  if (!reg)
289  return;
290 
291  u32 table_index = ntohl (mp->table_index);
292  if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
293  {
294  rv = VNET_API_ERROR_INVALID_VALUE;
295  goto out;
296  }
297 
298  /*
299  * Maybe reorder tables such that masks are most-specific to least-specific.
300  */
301  if (table_index != ~0 && mp->sort_masks)
302  table_index = classify_sort_table_chain (cm, table_index);
303 
304  classify_set_trace_chain (cm, table_index);
305 
306 out:
307  rmp = vl_msg_api_alloc (sizeof (*rmp));
308  rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TRACE_SET_TABLE_REPLY));
309  rmp->context = mp->context;
310  rmp->retval = ntohl (rv);
311  rmp->table_index = htonl (table_index);
312 
313  vl_api_send_msg (reg, (u8 *) rmp);
314 }
315 
318 {
322  int rv = 0;
323  u32 *tables = 0;
324  u32 count;
325 
327  if (!reg)
328  return;
329 
330  u32 table_index = classify_get_trace_chain ();
331  if (table_index == ~0)
332  goto out;
333 
334  /*
335  * Form a vector of all classifier tables in this chain.
336  */
338  u32 i;
339 
340  for (i = table_index; i != ~0; i = t->next_table_index)
341  {
342  vec_add1 (tables, i);
343  t = pool_elt_at_index (cm->tables, i);
344  }
345 
346 out:
347  count = vec_len (tables);
348  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
349  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TRACE_GET_TABLES_REPLY);
350  rmp->context = mp->context;
351  rmp->retval = ntohl (rv);
352  rmp->count = htonl (count);
353 
354  for (i = 0; i < count; ++i)
355  {
356  rmp->indices[i] = htonl (tables[i]);
357  }
358 
359  vec_free (tables);
360 
361  vl_api_send_msg (reg, (u8 *) rmp);
362 }
363 
364 
367 {
371  int rv;
372 
373 #define _(a) u32 a;
375 #undef _
376 
377 #define _(a) a = ntohl(mp->a);
379 #undef _
380 
381  if (mask_len != match_n_vectors * sizeof (u32x4))
382  {
383  rv = VNET_API_ERROR_INVALID_VALUE;
384  goto out;
385  }
386 
387  /* The underlying API fails silently, on purpose, so check here */
388  if (mp->is_add == 0) /* delete */
389  {
390  if (pool_is_free_index (cm->tables, table_index))
391  {
392  rv = VNET_API_ERROR_NO_SUCH_TABLE;
393  goto out;
394  }
395  }
396  else /* add or update */
397  {
398  if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
399  table_index = ~0;
400  }
401 
402  u8 current_data_flag = mp->current_data_flag;
403  i16 current_data_offset = clib_net_to_host_i16 (mp->current_data_offset);
404 
406  (cm, mp->mask, nbuckets, memory_size,
407  skip_n_vectors, match_n_vectors,
408  next_table_index, miss_next_index, &table_index,
409  current_data_flag, current_data_offset, mp->is_add, mp->del_chain);
410 
411 out:
412  /* *INDENT-OFF* */
413  REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
414  ({
415  if (rv == 0 && mp->is_add)
416  {
417  t = pool_elt_at_index (cm->tables, table_index);
418  rmp->skip_n_vectors = htonl(t->skip_n_vectors);
419  rmp->match_n_vectors = htonl(t->match_n_vectors);
420  rmp->new_table_index = htonl(table_index);
421  }
422  else
423  {
424  rmp->skip_n_vectors = ~0;
425  rmp->match_n_vectors = ~0;
426  rmp->new_table_index = ~0;
427  }
428  }));
429  /* *INDENT-ON* */
430 }
431 
434 {
436  vl_api_classify_add_del_session_reply_t *rmp;
437  int rv;
438  u32 table_index, hit_next_index, opaque_index, metadata, match_len;
439  i32 advance;
440  u8 action;
442 
443  table_index = ntohl (mp->table_index);
444  hit_next_index = ntohl (mp->hit_next_index);
445  opaque_index = ntohl (mp->opaque_index);
446  advance = ntohl (mp->advance);
447  action = mp->action;
448  metadata = ntohl (mp->metadata);
449  match_len = ntohl (mp->match_len);
450 
451  if (pool_is_free_index (cm->tables, table_index))
452  {
453  rv = VNET_API_ERROR_NO_SUCH_TABLE;
454  goto out;
455  }
456 
457  t = pool_elt_at_index (cm->tables, table_index);
458 
459  if (match_len != (t->skip_n_vectors + t->match_n_vectors) * sizeof (u32x4))
460  {
461  rv = VNET_API_ERROR_INVALID_VALUE;
462  goto out;
463  }
464 
466  (cm, table_index, mp->match, hit_next_index, opaque_index,
467  advance, action, metadata, mp->is_add);
468 
469 out:
470  REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
471 }
472 
473 static void
476 {
478  vl_api_policer_classify_set_interface_reply_t *rmp;
479  int rv;
480  u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
481 
482  ip4_table_index = ntohl (mp->ip4_table_index);
483  ip6_table_index = ntohl (mp->ip6_table_index);
484  l2_table_index = ntohl (mp->l2_table_index);
485  sw_if_index = ntohl (mp->sw_if_index);
486 
488 
489  rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
490  ip6_table_index, l2_table_index,
491  mp->is_add);
492 
494 
495  REPLY_MACRO (VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY);
496 }
497 
498 static void
500  u32 table_index, vl_api_registration_t * reg,
501  u32 context)
502 {
504 
505  mp = vl_msg_api_alloc (sizeof (*mp));
506  clib_memset (mp, 0, sizeof (*mp));
507  mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS);
508  mp->context = context;
509  mp->sw_if_index = htonl (sw_if_index);
510  mp->table_index = htonl (table_index);
511 
512  vl_api_send_msg (reg, (u8 *) mp);
513 }
514 
515 static void
517 {
520  u32 *vec_tbl;
521  int i;
522  u32 filter_sw_if_index;
523 
525  if (!reg)
526  return;
527 
528  filter_sw_if_index = ntohl (mp->sw_if_index);
529  if (filter_sw_if_index
531  return;
532 
533  if (filter_sw_if_index != ~0)
534  vec_tbl =
535  &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index];
536  else
537  vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
538 
539  if (vec_len (vec_tbl))
540  {
541  for (i = 0; i < vec_len (vec_tbl); i++)
542  {
543  if (vec_elt (vec_tbl, i) == ~0)
544  continue;
545 
546  send_policer_classify_details (i, vec_elt (vec_tbl, i), reg,
547  mp->context);
548  }
549  }
550 }
551 
552 static void
554 {
556 
558  if (!reg)
559  return;
560 
563  u32 *table_ids = 0;
564  u32 count;
565 
566  /* *INDENT-OFF* */
567  pool_foreach (t, cm->tables)
568  {
569  vec_add1 (table_ids, ntohl(t - cm->tables));
570  }
571  /* *INDENT-ON* */
572  count = vec_len (table_ids);
573 
575  rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
576  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_IDS_REPLY);
577  rmp->context = mp->context;
578  rmp->count = ntohl (count);
579  clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
580  rmp->retval = 0;
581 
582  vl_api_send_msg (reg, (u8 *) rmp);
583 
584  vec_free (table_ids);
585 }
586 
587 static void
590 {
592  int rv = 0;
593 
594  u32 sw_if_index = ntohl (mp->sw_if_index);
595  u32 *acl = 0;
596 
598  vec_set (acl, ~0);
599 
601 
603 
604  int if_idx;
605  u32 type;
606 
607  for (type = 0; type < IN_OUT_ACL_N_TABLES; type++)
608  {
609  u32 *vec_tbl =
611  [type];
612  if (vec_len (vec_tbl))
613  {
614  for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
615  {
616  if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
617  {
618  continue;
619  }
620  acl[type] = vec_elt (vec_tbl, if_idx);
621  }
622  }
623  }
624 
626 
627  /* *INDENT-OFF* */
628  REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
629  ({
630  rmp->sw_if_index = ntohl(sw_if_index);
631  rmp->l2_table_id = ntohl(acl[IN_OUT_ACL_TABLE_L2]);
632  rmp->ip4_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP4]);
633  rmp->ip6_table_id = ntohl(acl[IN_OUT_ACL_TABLE_IP6]);
634  }));
635  /* *INDENT-ON* */
636  vec_free (acl);
637 }
638 
639 static void
641 {
643 
645  if (!reg)
646  return;
647 
649 
651  u32 table_id = ntohl (mp->table_id);
653 
654  /* *INDENT-OFF* */
655  pool_foreach (t, cm->tables)
656  {
657  if (table_id == t - cm->tables)
658  {
660  (sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
661  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
662  rmp->context = mp->context;
663  rmp->table_id = ntohl(table_id);
664  rmp->nbuckets = ntohl(t->nbuckets);
665  rmp->match_n_vectors = ntohl(t->match_n_vectors);
666  rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
667  rmp->active_sessions = ntohl(t->active_elements);
668  rmp->next_table_index = ntohl(t->next_table_index);
669  rmp->miss_next_index = ntohl(t->miss_next_index);
670  rmp->mask_length = ntohl(t->match_n_vectors * sizeof (u32x4));
671  clib_memcpy(rmp->mask, t->mask, t->match_n_vectors * sizeof(u32x4));
672  rmp->retval = 0;
673  break;
674  }
675  }
676  /* *INDENT-ON* */
677 
678  if (rmp == 0)
679  {
680  rmp = vl_msg_api_alloc (sizeof (*rmp));
681  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
682  rmp->context = mp->context;
683  rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
684  }
685 
686  vl_api_send_msg (reg, (u8 *) rmp);
687 }
688 
689 static void
691  u32 table_id,
692  u32 match_length,
693  vnet_classify_entry_t * e, u32 context)
694 {
696 
697  rmp = vl_msg_api_alloc (sizeof (*rmp));
698  clib_memset (rmp, 0, sizeof (*rmp));
699  rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS);
700  rmp->context = context;
701  rmp->table_id = ntohl (table_id);
702  rmp->hit_next_index = ntohl (e->next_index);
703  rmp->advance = ntohl (e->advance);
704  rmp->opaque_index = ntohl (e->opaque_index);
705  rmp->match_length = ntohl (match_length);
706  clib_memcpy (rmp->match, e->key, match_length);
707 
708  vl_api_send_msg (reg, (u8 *) rmp);
709 }
710 
711 static void
713 {
716 
717  u32 table_id = ntohl (mp->table_id);
719 
721  if (!reg)
722  return;
723 
724  /* *INDENT-OFF* */
725  pool_foreach (t, cm->tables)
726  {
727  if (table_id == t - cm->tables)
728  {
730  vnet_classify_entry_t * v, * save_v;
731  int i, j, k;
732 
733  for (i = 0; i < t->nbuckets; i++)
734  {
735  b = &t->buckets [i];
736  if (b->offset == 0)
737  continue;
738 
739  save_v = vnet_classify_get_entry (t, b->offset);
740  for (j = 0; j < (1<<b->log2_pages); j++)
741  {
742  for (k = 0; k < t->entries_per_page; k++)
743  {
745  (t, save_v, j*t->entries_per_page + k);
747  continue;
748 
750  (reg, table_id, t->match_n_vectors * sizeof (u32x4),
751  v, mp->context);
752  }
753  }
754  }
755  break;
756  }
757  }
758  /* *INDENT-ON* */
759 }
760 
761 static void
764 {
766  vl_api_flow_classify_set_interface_reply_t *rmp;
767  int rv;
768  u32 sw_if_index, ip4_table_index, ip6_table_index;
769 
770  ip4_table_index = ntohl (mp->ip4_table_index);
771  ip6_table_index = ntohl (mp->ip6_table_index);
772  sw_if_index = ntohl (mp->sw_if_index);
773 
775 
776  rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
777  ip6_table_index, mp->is_add);
778 
780 
781  REPLY_MACRO (VL_API_FLOW_CLASSIFY_SET_INTERFACE_REPLY);
782 }
783 
784 static void
786  u32 table_index, vl_api_registration_t * reg,
787  u32 context)
788 {
790 
791  mp = vl_msg_api_alloc (sizeof (*mp));
792  clib_memset (mp, 0, sizeof (*mp));
793  mp->_vl_msg_id = ntohs (VL_API_FLOW_CLASSIFY_DETAILS);
794  mp->context = context;
795  mp->sw_if_index = htonl (sw_if_index);
796  mp->table_index = htonl (table_index);
797 
798  vl_api_send_msg (reg, (u8 *) mp);
799 }
800 
801 static void
803 {
806  u32 *vec_tbl;
807  int i;
808  u32 filter_sw_if_index;
809 
811  if (!reg)
812  return;
813 
814  filter_sw_if_index = ntohl (mp->sw_if_index);
815  if (filter_sw_if_index
817  return;
818 
819  if (filter_sw_if_index != ~0)
820  vec_tbl =
821  &pcm->classify_table_index_by_sw_if_index[mp->type][filter_sw_if_index];
822  else
823  vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
824 
825  if (vec_len (vec_tbl))
826  {
827  for (i = 0; i < vec_len (vec_tbl); i++)
828  {
829  if (vec_elt (vec_tbl, i) == ~0)
830  continue;
831 
832  send_flow_classify_details (i, vec_elt (vec_tbl, i), reg,
833  mp->context);
834  }
835  }
836 }
837 
840 {
842  vl_api_classify_set_interface_ip_table_reply_t *rmp;
843  int rv;
844 
846 
847  u32 table_index = ntohl (mp->table_index);
848  u32 sw_if_index = ntohl (mp->sw_if_index);
849 
850  if (mp->is_ipv6)
851  rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
852  else
853  rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
854 
856 
857  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
858 }
859 
862 {
863  vl_api_classify_set_interface_l2_tables_reply_t *rmp;
864  int rv;
865  u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
866  int enable;
867 
868  ip4_table_index = ntohl (mp->ip4_table_index);
869  ip6_table_index = ntohl (mp->ip6_table_index);
870  other_table_index = ntohl (mp->other_table_index);
871  sw_if_index = ntohl (mp->sw_if_index);
872 
874 
875  if (mp->is_input)
876  rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
877  ip6_table_index,
878  other_table_index);
879  else
880  rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
881  ip6_table_index,
882  other_table_index);
883 
884  if (rv == 0)
885  {
886  if (ip4_table_index != ~0 || ip6_table_index != ~0
887  || other_table_index != ~0)
888  enable = 1;
889  else
890  enable = 0;
891 
892  if (mp->is_input)
893  vnet_l2_input_classify_enable_disable (sw_if_index, enable);
894  else
895  vnet_l2_output_classify_enable_disable (sw_if_index, enable);
896  }
897 
899 
900  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
901 }
902 
905 {
907  vl_api_input_acl_set_interface_reply_t *rmp;
908  int rv;
909 
911 
912  u32 ip4_table_index = ntohl (mp->ip4_table_index);
913  u32 ip6_table_index = ntohl (mp->ip6_table_index);
914  u32 l2_table_index = ntohl (mp->l2_table_index);
915  u32 sw_if_index = ntohl (mp->sw_if_index);
916 
917  rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
918  ip6_table_index, l2_table_index, mp->is_add);
919 
921 
922  REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
923 }
924 
927 {
929  vl_api_output_acl_set_interface_reply_t *rmp;
930  int rv;
931 
933 
934  u32 ip4_table_index = ntohl (mp->ip4_table_index);
935  u32 ip6_table_index = ntohl (mp->ip6_table_index);
936  u32 l2_table_index = ntohl (mp->l2_table_index);
937  u32 sw_if_index = ntohl (mp->sw_if_index);
938 
939  rv = vnet_set_output_acl_intfc (vm, sw_if_index, ip4_table_index,
940  ip6_table_index, l2_table_index,
941  mp->is_add);
942 
944 
945  REPLY_MACRO (VL_API_OUTPUT_ACL_SET_INTERFACE_REPLY);
946 }
947 
948 /*
949  * classify_api_hookup
950  * Add vpe's API message handlers to the table.
951  * vlib has already mapped shared memory and
952  * added the client registration handlers.
953  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
954  */
955 #define vl_msg_name_crc_list
956 #include <vnet/vnet_all_api_h.h>
957 #undef vl_msg_name_crc_list
958 
959 static void
961 {
962 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
963  foreach_vl_msg_name_crc_classify;
964 #undef _
965 }
966 
967 static clib_error_t *
969 {
970  api_main_t *am = vlibapi_get_main ();
971 
972 #define _(N,n) \
973  vl_msg_api_set_handlers(VL_API_##N, #n, \
974  vl_api_##n##_t_handler, \
975  vl_noop_handler, \
976  vl_api_##n##_t_endian, \
977  vl_api_##n##_t_print, \
978  sizeof(vl_api_##n##_t), 1);
980 #undef _
981 
982  /*
983  * Set up the (msg_name, crc, message-id) table
984  */
986 
987  return 0;
988 }
989 
991 
992 /*
993  * fd.io coding-style-patch-verification: ON
994  *
995  * Local Variables:
996  * eval: (c-set-style "gnu")
997  * End:
998  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
Reply for classify table session dump request.
Definition: classify.api:303
policer_classify_main_t policer_classify_main
u32 table_index[default=0xffffffff]
Definition: classify.api:574
static void vl_api_classify_table_info_t_handler(vl_api_classify_table_info_t *mp)
Definition: classify_api.c:640
static void send_classify_session_details(vl_api_registration_t *reg, u32 table_id, u32 match_length, vnet_classify_entry_t *e, u32 context)
Definition: classify_api.c:690
Classify get table IDs request.
Definition: classify.api:194
#define foreach_vpe_api_msg
Definition: classify_api.c:52
#define ntohs(x)
Definition: af_xdp.bpf.c:29
static void vl_api_classify_add_del_table_t_handler(vl_api_classify_add_del_table_t *mp)
Definition: classify_api.c:366
vl_api_interface_index_t sw_if_index
Definition: classify.api:361
Set/unset policer classify interface.
Definition: classify.api:145
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
int vnet_set_ip6_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 table_index)
Definition: ip6_forward.c:3031
#define REPLY_MACRO2(t, body)
u32 * classify_table_index_by_sw_if_index[IN_OUT_ACL_N_TABLE_GROUPS][IN_OUT_ACL_N_TABLES]
Definition: in_out_acl.h:50
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
Classify add / del session request.
Definition: classify.api:119
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
static void vl_api_output_acl_set_interface_t_handler(vl_api_output_acl_set_interface_t *mp)
Definition: classify_api.c:926
void vnet_l2_input_classify_enable_disable(u32 sw_if_index, int enable_disable)
Enable/disable l2 input classification on a specific interface.
u32 classify_lookup_chain(u32 table_index, u8 *mask, u32 n_skip, u32 n_match)
vlib_main_t * vm
Definition: in2out_ed.c:1580
Classify pcap table lookup response.
Definition: classify.api:500
Add/Delete classification table request.
Definition: classify.api:45
Classify trace table lookup response.
Definition: classify.api:557
static void vl_api_classify_trace_lookup_table_t_handler(vl_api_classify_trace_lookup_table_t *mp)
Definition: classify_api.c:236
Reply for classify get table IDs request.
Definition: classify.api:205
static void vl_api_classify_trace_get_tables_t_handler(vl_api_classify_trace_get_tables_t *mp)
Definition: classify_api.c:317
static void vl_api_classify_trace_set_table_t_handler(vl_api_classify_trace_set_table_t *mp)
Definition: classify_api.c:280
void * vl_msg_api_alloc(int nbytes)
vl_api_interface_index_t sw_if_index
Definition: classify.api:515
unsigned char u8
Definition: types.h:56
vl_api_interface_index_t sw_if_index
Definition: classify.api:237
static void send_policer_classify_details(u32 sw_if_index, u32 table_index, vl_api_registration_t *reg, u32 context)
Definition: classify_api.c:499
#define clib_memcpy(d, s, n)
Definition: string.h:180
static void vl_api_input_acl_set_interface_t_handler(vl_api_input_acl_set_interface_t *mp)
Definition: classify_api.c:904
u32 classify_get_pcap_chain(vnet_classify_main_t *cm, u32 sw_if_index)
vl_api_interface_index_t sw_if_index
Definition: classify.api:222
Classify sessions dump request.
Definition: classify.api:287
u32 * classify_table_index_by_sw_if_index[FLOW_CLASSIFY_N_TABLES]
Definition: flow_classify.h:39
static void send_flow_classify_details(u32 sw_if_index, u32 table_index, vl_api_registration_t *reg, u32 context)
Definition: classify_api.c:785
Set/unset output ACL interface.
Definition: classify.api:434
Classify Trace table lookup response.
Definition: classify.api:583
static void setup_message_id_table(api_main_t *am)
Definition: classify_api.c:960
const cJSON *const b
Definition: cJSON.h:255
Set/unset input ACL interface.
Definition: classify.api:412
int vnet_l2_output_classify_set_tables(u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 other_table_index)
Set l2 per-protocol, per-interface output classification tables.
unsigned int u32
Definition: types.h:88
Reply for classify table id by interface index request.
Definition: classify.api:233
int vnet_set_ip4_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 table_index)
Definition: ip4_forward.c:2930
u32 * classify_table_index_by_sw_if_index[POLICER_CLASSIFY_N_TABLES]
static int vnet_classify_entry_is_free(vnet_classify_entry_t *e)
vl_api_fib_path_type_t type
Definition: fib_types.api:123
int vnet_classify_add_del_session(vnet_classify_main_t *cm, u32 table_index, u8 *match, u32 hit_next_index, u32 opaque_index, i32 advance, u8 action, u32 metadata, int is_add)
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
Flow classify operational state response.
Definition: classify.api:359
vl_api_interface_index_t sw_if_index
Definition: classify.api:438
#define foreach_classify_add_del_table_field
Definition: classify_api.c:75
u64 memory_size
Definition: vhost_user.h:105
Classify pcap table lookup response.
Definition: classify.api:472
Set/unset l2 classification tables for an interface request.
Definition: classify.api:389
u32 opaque_index[default=0xffffffff]
Definition: classify.api:126
Add/Delete classification table response.
Definition: classify.api:71
vl_api_flow_classify_table_t type
Definition: classify.api:350
#define REPLY_MACRO(t)
Add a Classify table into the Trace chain.
Definition: classify.api:570
static clib_error_t * classify_api_hookup(vlib_main_t *vm)
Definition: classify_api.c:968
int vnet_set_input_acl_intfc(vlib_main_t *vm, u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 l2_table_index, u32 is_add)
Definition: in_out_acl.c:129
Get list of flow classify interfaces and tables.
Definition: classify.api:347
vl_api_interface_index_t sw_if_index
Definition: classify.api:490
static vnet_classify_entry_t * vnet_classify_entry_at_index(vnet_classify_table_t *t, vnet_classify_entry_t *e, u32 index)
flow_classify_main_t flow_classify_main
Definition: flow_classify.c:19
static void vl_api_flow_classify_set_interface_t_handler(vl_api_flow_classify_set_interface_t *mp)
Definition: classify_api.c:763
Find a mask-compatible Classify table in the Trace chain.
Definition: classify.api:542
Classify table info.
Definition: classify.api:248
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:227
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
#define BAD_SW_IF_INDEX_LABEL
static void vl_api_classify_set_interface_l2_tables_t_handler(vl_api_classify_set_interface_l2_tables_t *mp)
Definition: classify_api.c:861
Find a compatible Classify table in a PCAP chain.
Definition: classify.api:456
int vnet_set_flow_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 is_add)
Definition: flow_classify.c:49
static void vl_api_classify_set_interface_ip_table_t_handler(vl_api_classify_set_interface_ip_table_t *mp)
Definition: classify_api.c:839
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
Set/unset the classification table for an interface request.
Definition: classify.api:372
Set/unset flow classify interface.
Definition: classify.api:326
int vnet_l2_input_classify_set_tables(u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 other_table_index)
Set l2 per-protocol, per-interface input classification tables.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
Classify get the PCAP table indices for an interface.
Definition: classify.api:511
static void vl_api_classify_session_dump_t_handler(vl_api_classify_session_dump_t *mp)
Definition: classify_api.c:712
static void vl_api_classify_pcap_set_table_t_handler(vl_api_classify_pcap_set_table_t *mp)
Definition: classify_api.c:138
vl_api_interface_index_t sw_if_index[default=0xffffffff]
Definition: classify.api:460
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:56
vl_api_classify_action_t action[default=0]
Definition: classify.api:128
Policer classify operational state response.
Definition: classify.api:183
signed int i32
Definition: types.h:77
vl_api_interface_index_t sw_if_index
Definition: classify.api:416
vl_api_interface_index_t sw_if_index
Definition: classify.api:377
vl_api_interface_index_t sw_if_index
Definition: classify.api:186
Classify get the Trace tables response.
Definition: classify.api:606
Get list of policer classify interfaces and tables.
Definition: classify.api:170
static void vl_api_flow_classify_dump_t_handler(vl_api_flow_classify_dump_t *mp)
Definition: classify_api.c:802
vl_api_interface_index_t sw_if_index
Definition: classify.api:149
vl_api_policer_classify_table_t type
Definition: classify.api:174
static void vl_api_policer_classify_dump_t_handler(vl_api_policer_classify_dump_t *mp)
Definition: classify_api.c:516
vl_api_interface_index_t sw_if_index
Definition: classify.api:351
Classify get a PCAP tables response.
Definition: classify.api:524
vnet_classify_main_t vnet_classify_main
Definition: vnet_classify.c:32
#define vec_set(v, val)
Set all vector elements to given value.
Definition: vec.h:963
vl_api_interface_index_t sw_if_index
Definition: classify.api:329
i16 current_data_offset[default=0]
Definition: classify.api:59
Classify get the Trace table indices.
Definition: classify.api:594
Classify table ids by interface index request.
Definition: classify.api:218
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 table_index[default=0xffffffff]
Definition: classify.api:491
static void vl_api_policer_classify_set_interface_t_handler(vl_api_policer_classify_set_interface_t *mp)
Definition: classify_api.c:475
int vnet_classify_add_del_table(vnet_classify_main_t *cm, u8 *mask, u32 nbuckets, u32 memory_size, u32 skip, u32 match, u32 next_table_index, u32 miss_next_index, u32 *table_index, u8 current_data_flag, i16 current_data_offset, int is_add, int del_chain)
#define vec_elt(v, i)
Get vector value at index i.
vl_api_mac_event_action_t action
Definition: l2.api:181
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vnet_classify_bucket_t * buckets
static void vl_api_classify_pcap_lookup_table_t_handler(vl_api_classify_pcap_lookup_table_t *mp)
Definition: classify_api.c:87
u32 classify_sort_table_chain(vnet_classify_main_t *cm, u32 table_index)
u32 table_id
Definition: wireguard.api:102
void vnet_l2_output_classify_enable_disable(u32 sw_if_index, int enable_disable)
Enable/disable l2 input classification on a specific interface.
u32 hit_next_index[default=0xffffffff]
Definition: classify.api:125
void classify_set_pcap_chain(vnet_classify_main_t *cm, u32 sw_if_index, u32 table_index)
static void vl_api_classify_table_by_interface_t_handler(vl_api_classify_table_by_interface_t *mp)
Definition: classify_api.c:589
vl_api_interface_index_t sw_if_index
Definition: classify.api:175
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:389
static void vl_api_classify_table_ids_t_handler(vl_api_classify_table_ids_t *mp)
Definition: classify_api.c:553
u32 classify_get_trace_chain(void)
in_out_acl_main_t in_out_acl_main
Definition: in_out_acl.c:21
static void vl_api_classify_pcap_get_tables_t_handler(vl_api_classify_pcap_get_tables_t *mp)
Definition: classify_api.c:179
unsigned long long u32x4
Definition: ixge.c:28
u8 count
Definition: dhcp.api:208
int vnet_set_policer_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 l2_table_index, u32 is_add)
void * vl_msg_api_alloc_as_if_client(int nbytes)
static void vl_api_classify_add_del_session_t_handler(vl_api_classify_add_del_session_t *mp)
Definition: classify_api.c:433
vl_api_interface_index_t sw_if_index
Definition: classify.api:393
Reply for classify table info request.
Definition: classify.api:267
void classify_set_trace_chain(vnet_classify_main_t *cm, u32 table_index)
VLIB_API_INIT_FUNCTION(classify_api_hookup)
int vnet_set_output_acl_intfc(vlib_main_t *vm, u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 l2_table_index, u32 is_add)
Definition: in_out_acl.c:139
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
Add a Classify table into a PCAP chain on an interface.
Definition: classify.api:486
static vnet_classify_entry_t * vnet_classify_get_entry(vnet_classify_table_t *t, uword offset)
#define VALIDATE_SW_IF_INDEX(mp)
signed short i16
Definition: types.h:46