FD.io VPP  v18.07.1-13-g909ba93
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 
18 
19 static void
22  u32 sw_if_index,
24  int feature_enable)
25 {
26  if (tid == POLICER_CLASSIFY_TABLE_L2)
27  {
28  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_POLICER_CLAS,
29  feature_enable);
30  }
31  else
32  {
34  u8 arc;
35 
36  if (tid == POLICER_CLASSIFY_TABLE_IP4)
37  {
38  vnet_feature_enable_disable ("ip4-unicast", "ip4-policer-classify",
39  sw_if_index, feature_enable, 0, 0);
40  arc = vnet_get_feature_arc_index ("ip4-unicast");
41  }
42 
43  else
44  {
45  vnet_feature_enable_disable ("ip6-unicast", "ip6-policer-classify",
46  sw_if_index, feature_enable, 0, 0);
47  arc = vnet_get_feature_arc_index ("ip6-unicast");
48  }
49 
51  pcm->vnet_config_main[tid] = &fcm->config_main;
52  }
53 }
54 
55 int
57  u32 ip4_table_index, u32 ip6_table_index,
58  u32 l2_table_index, u32 is_add)
59 {
62  u32 pct[POLICER_CLASSIFY_N_TABLES] = { ip4_table_index, ip6_table_index,
63  l2_table_index
64  };
65  u32 ti;
66 
67  /* Assume that we've validated sw_if_index in the API layer */
68 
69  for (ti = 0; ti < POLICER_CLASSIFY_N_TABLES; ti++)
70  {
71  if (pct[ti] == ~0)
72  continue;
73 
74  if (pool_is_free_index (vcm->tables, pct[ti]))
75  return VNET_API_ERROR_NO_SUCH_TABLE;
76 
78  (pcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
79 
80  /* Reject any DEL operation with wrong sw_if_index */
81  if (!is_add &&
82  (pct[ti] !=
83  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
84  {
86  ("Non-existent intf_idx=%d with table_index=%d for delete",
87  sw_if_index, pct[ti]);
88  return VNET_API_ERROR_NO_SUCH_TABLE;
89  }
90 
91  /* Return ok on ADD operaton if feature is already enabled */
92  if (is_add &&
93  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
94  return 0;
95 
96  vnet_policer_classify_feature_enable (vm, pcm, sw_if_index, ti, is_add);
97 
98  if (is_add)
99  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = pct[ti];
100  else
101  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = ~0;
102  }
103 
104 
105  return 0;
106 }
107 
108 static clib_error_t *
110  unformat_input_t * input,
111  vlib_cli_command_t * cmd)
112 {
113  vnet_main_t *vnm = vnet_get_main ();
114  u32 sw_if_index = ~0;
115  u32 ip4_table_index = ~0;
116  u32 ip6_table_index = ~0;
117  u32 l2_table_index = ~0;
118  u32 is_add = 1;
119  u32 idx_cnt = 0;
120  int rv;
121 
123  {
124  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
125  vnm, &sw_if_index))
126  ;
127  else if (unformat (input, "ip4-table %d", &ip4_table_index))
128  idx_cnt++;
129  else if (unformat (input, "ip6-table %d", &ip6_table_index))
130  idx_cnt++;
131  else if (unformat (input, "l2-table %d", &l2_table_index))
132  idx_cnt++;
133  else if (unformat (input, "del"))
134  is_add = 0;
135  else
136  break;
137  }
138 
139  if (sw_if_index == ~0)
140  return clib_error_return (0, "Interface must be specified.");
141 
142  if (!idx_cnt)
143  return clib_error_return (0, "Table index should be specified.");
144 
145  if (idx_cnt > 1)
146  return clib_error_return (0, "Only one table index per API is allowed.");
147 
148  rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
149  ip6_table_index, l2_table_index,
150  is_add);
151 
152  switch (rv)
153  {
154  case 0:
155  break;
156 
157  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
158  return clib_error_return (0, "No such interface");
159 
160  case VNET_API_ERROR_NO_SUCH_ENTRY:
161  return clib_error_return (0, "No such classifier table");
162  }
163  return 0;
164 }
165 
166 /* *INDENT-OFF* */
167 VLIB_CLI_COMMAND (set_policer_classify_command, static) = {
168  .path = "set policer classify",
169  .short_help =
170  "set policer classify interface <int> [ip4-table <index>]\n"
171  " [ip6-table <index>] [l2-table <index>] [del]",
173 };
174 /* *INDENT-ON* */
175 
176 static uword
177 unformat_table_type (unformat_input_t * input, va_list * va)
178 {
179  u32 *r = va_arg (*va, u32 *);
180  u32 tid;
181 
182  if (unformat (input, "ip4"))
184  else if (unformat (input, "ip6"))
186  else if (unformat (input, "l2"))
188  else
189  return 0;
190 
191  *r = tid;
192  return 1;
193 }
194 
195 static clib_error_t *
197  unformat_input_t * input,
198  vlib_cli_command_t * cmd)
199 {
202  u32 *vec_tbl;
203  int i;
204 
205  if (unformat (input, "type %U", unformat_table_type, &type))
206  ;
207  else
208  return clib_error_return (0, "Type must be specified.");;
209 
210  if (type == POLICER_CLASSIFY_N_TABLES)
211  return clib_error_return (0, "Invalid table type.");
212 
213  vec_tbl = pcm->classify_table_index_by_sw_if_index[type];
214 
215  if (vec_len (vec_tbl))
216  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
217  "Interface name");
218  else
219  vlib_cli_output (vm, "No tables configured.");
220 
221  for (i = 0; i < vec_len (vec_tbl); i++)
222  {
223  if (vec_elt (vec_tbl, i) == ~0)
224  continue;
225 
226  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt (vec_tbl, i),
228  }
229 
230  return 0;
231 }
232 
233 /* *INDENT-OFF* */
234 VLIB_CLI_COMMAND (show_policer_classify_command, static) = {
235  .path = "show classify policer",
236  .short_help = "show classify policer type [ip4|ip6|l2]",
238 };
239 /* *INDENT-ON* */
240 
241 /*
242  * fd.io coding-style-patch-verification: ON
243  *
244  * Local Variables:
245  * eval: (c-set-style "gnu")
246  * End:
247  */
vnet_config_main_t config_main
Definition: feature.h:65
policer_classify_main_t policer_classify_main
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:127
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
int i
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]
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
vlib_main_t * vm
Definition: buffer.c:294
#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:271
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:70
static clib_error_t * show_policer_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static uword unformat_table_type(unformat_input_t *input, va_list *va)
#define vec_elt(v, i)
Get vector value at index i.
u32 l2input_intf_bitmap_enable(u32 sw_if_index, u32 feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:520
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:165
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:486
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
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:233
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170