FD.io VPP  v17.10-9-gd594711
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 
17 static void
20  u32 sw_if_index,
22  int feature_enable)
23 {
24  if (tid == POLICER_CLASSIFY_TABLE_L2)
25  {
26  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_POLICER_CLAS,
27  feature_enable);
28  }
29  else
30  {
32  u8 arc;
33 
34  if (tid == POLICER_CLASSIFY_TABLE_IP4)
35  {
36  vnet_feature_enable_disable ("ip4-unicast", "ip4-policer-classify",
37  sw_if_index, feature_enable, 0, 0);
38  arc = vnet_get_feature_arc_index ("ip4-unicast");
39  }
40 
41  else
42  {
43  vnet_feature_enable_disable ("ip6-unicast", "ip6-policer-classify",
44  sw_if_index, feature_enable, 0, 0);
45  arc = vnet_get_feature_arc_index ("ip6-unicast");
46  }
47 
49  pcm->vnet_config_main[tid] = &fcm->config_main;
50  }
51 }
52 
54  u32 ip4_table_index, u32 ip6_table_index,
55  u32 l2_table_index, u32 is_add)
56 {
59  u32 pct[POLICER_CLASSIFY_N_TABLES] = {ip4_table_index, ip6_table_index,
60  l2_table_index};
61  u32 ti;
62 
63  /* Assume that we've validated sw_if_index in the API layer */
64 
65  for (ti = 0; ti < POLICER_CLASSIFY_N_TABLES; ti++)
66  {
67  if (pct[ti] == ~0)
68  continue;
69 
70  if (pool_is_free_index (vcm->tables, pct[ti]))
71  return VNET_API_ERROR_NO_SUCH_TABLE;
72 
74  (pcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
75 
76  /* Reject any DEL operation with wrong sw_if_index */
77  if (!is_add &&
78  (pct[ti] != pcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
79  {
80  clib_warning ("Non-existent intf_idx=%d with table_index=%d for delete",
81  sw_if_index, pct[ti]);
82  return VNET_API_ERROR_NO_SUCH_TABLE;
83  }
84 
85  /* Return ok on ADD operaton if feature is already enabled */
86  if (is_add &&
87  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
88  return 0;
89 
90  vnet_policer_classify_feature_enable (vm, pcm, sw_if_index, ti, is_add);
91 
92  if (is_add)
93  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = pct[ti];
94  else
95  pcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = ~0;
96  }
97 
98 
99  return 0;
100 }
101 
102 static clib_error_t *
104  unformat_input_t * input,
105  vlib_cli_command_t * cmd)
106 {
107  vnet_main_t * vnm = vnet_get_main();
108  u32 sw_if_index = ~0;
109  u32 ip4_table_index = ~0;
110  u32 ip6_table_index = ~0;
111  u32 l2_table_index = ~0;
112  u32 is_add = 1;
113  u32 idx_cnt = 0;
114  int rv;
115 
117  {
118  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
119  vnm, &sw_if_index))
120  ;
121  else if (unformat (input, "ip4-table %d", &ip4_table_index))
122  idx_cnt++;
123  else if (unformat (input, "ip6-table %d", &ip6_table_index))
124  idx_cnt++;
125  else if (unformat (input, "l2-table %d", &l2_table_index))
126  idx_cnt++;
127  else if (unformat (input, "del"))
128  is_add = 0;
129  else
130  break;
131  }
132 
133  if (sw_if_index == ~0)
134  return clib_error_return (0, "Interface must be specified.");
135 
136  if (!idx_cnt)
137  return clib_error_return (0, "Table index should be specified.");
138 
139  if (idx_cnt > 1)
140  return clib_error_return (0, "Only one table index per API is allowed.");
141 
142  rv = vnet_set_policer_classify_intfc(vm, sw_if_index, ip4_table_index,
143  ip6_table_index, l2_table_index, is_add);
144 
145  switch (rv)
146  {
147  case 0:
148  break;
149 
150  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
151  return clib_error_return (0, "No such interface");
152 
153  case VNET_API_ERROR_NO_SUCH_ENTRY:
154  return clib_error_return (0, "No such classifier table");
155  }
156  return 0;
157 }
158 
159 VLIB_CLI_COMMAND (set_policer_classify_command, static) = {
160  .path = "set policer classify",
161  .short_help =
162  "set policer classify interface <int> [ip4-table <index>]\n"
163  " [ip6-table <index>] [l2-table <index>] [del]",
165 };
166 
167 static uword
168 unformat_table_type (unformat_input_t * input, va_list * va)
169 {
170  u32 * r = va_arg (*va, u32 *);
171  u32 tid;
172 
173  if (unformat (input, "ip4"))
175  else if (unformat (input, "ip6"))
177  else if (unformat (input, "l2"))
179  else
180  return 0;
181 
182  *r = tid;
183  return 1;
184 }
185 static clib_error_t *
187  unformat_input_t * input,
188  vlib_cli_command_t * cmd)
189 {
192  u32 * vec_tbl;
193  int i;
194 
195  if (unformat (input, "type %U", unformat_table_type, &type))
196  ;
197  else
198  return clib_error_return (0, "Type must be specified.");;
199 
200  if (type == POLICER_CLASSIFY_N_TABLES)
201  return clib_error_return (0, "Invalid table type.");
202 
203  vec_tbl = pcm->classify_table_index_by_sw_if_index[type];
204 
205  if (vec_len(vec_tbl))
206  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
207  "Interface name");
208  else
209  vlib_cli_output (vm, "No tables configured.");
210 
211  for (i = 0; i < vec_len (vec_tbl); i++)
212  {
213  if (vec_elt(vec_tbl, i) == ~0)
214  continue;
215 
216  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt(vec_tbl, i),
218  }
219 
220  return 0;
221 }
222 
223 VLIB_CLI_COMMAND (show_policer_classify_command, static) = {
224  .path = "show classify policer",
225  .short_help = "show classify policer type [ip4|ip6|l2]",
227 };
vnet_config_main_t config_main
Definition: feature.h:65
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:127
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
policer_classify_table_id_t
#define clib_error_return(e, args...)
Definition: error.h:99
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:143
vlib_main_t * vm
Definition: buffer.c:283
#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:267
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:72
unsigned int u32
Definition: types.h:88
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)
u64 uword
Definition: types.h:112
#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:534
vnet_classify_main_t * vnet_classify_main
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
static vnet_feature_config_main_t * vnet_get_feature_arc_config_main(u8 arc_index)
Definition: feature.h:149
policer_classify_main_t policer_classify_main
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:481
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
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:229
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169