FD.io VPP  v21.01.1
Vector Packet Processing
policer_classify.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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  */
16 #include <vnet/l2/l2_input.h>
17 
19 
20 static void
25  int feature_enable)
26 {
27  if (tid == POLICER_CLASSIFY_TABLE_L2)
28  {
29  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_POLICER_CLAS,
30  feature_enable);
31  }
32  else
33  {
35  u8 arc;
36 
37  if (tid == POLICER_CLASSIFY_TABLE_IP4)
38  {
39  vnet_feature_enable_disable ("ip4-unicast", "ip4-policer-classify",
40  sw_if_index, feature_enable, 0, 0);
41  arc = vnet_get_feature_arc_index ("ip4-unicast");
42  }
43 
44  else
45  {
46  vnet_feature_enable_disable ("ip6-unicast", "ip6-policer-classify",
47  sw_if_index, feature_enable, 0, 0);
48  arc = vnet_get_feature_arc_index ("ip6-unicast");
49  }
50 
52  pcm->vnet_config_main[tid] = &fcm->config_main;
53  }
54 }
55 
56 int
58  u32 ip4_table_index, u32 ip6_table_index,
59  u32 l2_table_index, u32 is_add)
60 {
63  u32 pct[POLICER_CLASSIFY_N_TABLES] = { ip4_table_index, ip6_table_index,
64  l2_table_index
65  };
66  u32 ti;
67 
68  /* Assume that we've validated sw_if_index in the API layer */
69 
70  for (ti = 0; ti < POLICER_CLASSIFY_N_TABLES; ti++)
71  {
72  if (pct[ti] == ~0)
73  continue;
74 
75  if (pool_is_free_index (vcm->tables, pct[ti]))
76  return VNET_API_ERROR_NO_SUCH_TABLE;
77 
79  (pcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
80 
81  /* Reject any DEL operation with wrong sw_if_index */
82  if (!is_add &&
83  (pct[ti] !=
84  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
85  {
87  ("Non-existent intf_idx=%d with table_index=%d for delete",
88  sw_if_index, pct[ti]);
89  return VNET_API_ERROR_NO_SUCH_TABLE;
90  }
91 
92  /* Return ok on ADD operaton if feature is already enabled */
93  if (is_add &&
94  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
95  return 0;
96 
97  vnet_policer_classify_feature_enable (vm, pcm, sw_if_index, ti, is_add);
98 
99  if (is_add)
101  else
103  }
104 
105 
106  return 0;
107 }
108 
109 static clib_error_t *
111  unformat_input_t * input,
112  vlib_cli_command_t * cmd)
113 {
114  vnet_main_t *vnm = vnet_get_main ();
115  u32 sw_if_index = ~0;
116  u32 ip4_table_index = ~0;
117  u32 ip6_table_index = ~0;
118  u32 l2_table_index = ~0;
119  u32 is_add = 1;
120  u32 idx_cnt = 0;
121  int rv;
122 
124  {
125  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
126  vnm, &sw_if_index))
127  ;
128  else if (unformat (input, "ip4-table %d", &ip4_table_index))
129  idx_cnt++;
130  else if (unformat (input, "ip6-table %d", &ip6_table_index))
131  idx_cnt++;
132  else if (unformat (input, "l2-table %d", &l2_table_index))
133  idx_cnt++;
134  else if (unformat (input, "del"))
135  is_add = 0;
136  else
137  break;
138  }
139 
140  if (sw_if_index == ~0)
141  return clib_error_return (0, "Interface must be specified.");
142 
143  if (!idx_cnt)
144  return clib_error_return (0, "Table index should be specified.");
145 
146  if (idx_cnt > 1)
147  return clib_error_return (0, "Only one table index per API is allowed.");
148 
149  rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
150  ip6_table_index, l2_table_index,
151  is_add);
152 
153  switch (rv)
154  {
155  case 0:
156  break;
157 
158  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
159  return clib_error_return (0, "No such interface");
160 
161  case VNET_API_ERROR_NO_SUCH_ENTRY:
162  return clib_error_return (0, "No such classifier table");
163  }
164  return 0;
165 }
166 
167 /* *INDENT-OFF* */
168 VLIB_CLI_COMMAND (set_policer_classify_command, static) = {
169  .path = "set policer classify",
170  .short_help =
171  "set policer classify interface <int> [ip4-table <index>]\n"
172  " [ip6-table <index>] [l2-table <index>] [del]",
174 };
175 /* *INDENT-ON* */
176 
177 static uword
178 unformat_table_type (unformat_input_t * input, va_list * va)
179 {
180  u32 *r = va_arg (*va, u32 *);
181  u32 tid;
182 
183  if (unformat (input, "ip4"))
185  else if (unformat (input, "ip6"))
187  else if (unformat (input, "l2"))
189  else
190  return 0;
191 
192  *r = tid;
193  return 1;
194 }
195 
196 static clib_error_t *
198  unformat_input_t * input,
199  vlib_cli_command_t * cmd)
200 {
203  u32 *vec_tbl;
204  int i;
205 
206  if (unformat (input, "type %U", unformat_table_type, &type))
207  ;
208  else
209  return clib_error_return (0, "Type must be specified.");;
210 
211  if (type == POLICER_CLASSIFY_N_TABLES)
212  return clib_error_return (0, "Invalid table type.");
213 
215 
216  if (vec_len (vec_tbl))
217  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
218  "Interface name");
219  else
220  vlib_cli_output (vm, "No tables configured.");
221 
222  for (i = 0; i < vec_len (vec_tbl); i++)
223  {
224  if (vec_elt (vec_tbl, i) == ~0)
225  continue;
226 
227  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt (vec_tbl, i),
229  }
230 
231  return 0;
232 }
233 
234 /* *INDENT-OFF* */
235 VLIB_CLI_COMMAND (show_policer_classify_command, static) = {
236  .path = "show classify policer",
237  .short_help = "show classify policer type [ip4|ip6|l2]",
239 };
240 /* *INDENT-ON* */
241 
242 /*
243  * fd.io coding-style-patch-verification: ON
244  *
245  * Local Variables:
246  * eval: (c-set-style "gnu")
247  * End:
248  */
vnet_config_main_t config_main
Definition: feature.h:82
policer_classify_main_t policer_classify_main
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:197
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vlib_main_t * vm
Definition: in2out_ed.c:1580
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
policer_classify_table_id_t
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
u32 * classify_table_index_by_sw_if_index[POLICER_CLASSIFY_N_TABLES]
vl_api_fib_path_type_t type
Definition: fib_types.api:123
struct _unformat_input_t unformat_input_t
vnet_config_main_t * vnet_config_main[POLICER_CLASSIFY_N_TABLES]
static clib_error_t * set_policer_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define clib_warning(format, args...)
Definition: error.h:59
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:56
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
static clib_error_t * show_policer_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 l2input_intf_bitmap_enable(u32 sw_if_index, l2input_feat_masks_t feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:177
static uword unformat_table_type(unformat_input_t *input, va_list *va)
#define vec_elt(v, i)
Get vector value at index i.
vnet_classify_main_t * vnet_classify_main
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
static vnet_feature_config_main_t * vnet_get_feature_arc_config_main(u8 arc_index)
Definition: feature.h:233
static void vnet_policer_classify_feature_enable(vlib_main_t *vnm, policer_classify_main_t *pcm, u32 sw_if_index, policer_classify_table_id_t tid, int feature_enable)
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)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:556
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
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: feature.c:303
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170