FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
flow_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 {
27  u8 arc;
28 
29  if (tid == FLOW_CLASSIFY_TABLE_IP4)
30  {
31  vnet_feature_enable_disable ("ip4-unicast", "ip4-flow-classify",
32  sw_if_index, feature_enable, 0, 0);
33  arc = vnet_get_feature_arc_index ("ip4-unicast");
34  }
35  else
36  {
37  vnet_feature_enable_disable ("ip6-unicast", "ip6-flow-classify",
38  sw_if_index, feature_enable, 0, 0);
39  arc = vnet_get_feature_arc_index ("ip6-unicast");
40  }
41 
43  fcm->vnet_config_main[tid] = &vfcm->config_main;
44 }
45 
46 int
48  u32 ip4_table_index, u32 ip6_table_index,
49  u32 is_add)
50 {
53  u32 pct[FLOW_CLASSIFY_N_TABLES] = { ip4_table_index, ip6_table_index };
54  u32 ti;
55 
56  /* Assume that we've validated sw_if_index in the API layer */
57 
58  for (ti = 0; ti < FLOW_CLASSIFY_N_TABLES; ti++)
59  {
60  if (pct[ti] == ~0)
61  continue;
62 
63  if (pool_is_free_index (vcm->tables, pct[ti]))
64  return VNET_API_ERROR_NO_SUCH_TABLE;
65 
67  (fcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
68 
69  /* Reject any DEL operation with wrong sw_if_index */
70  if (!is_add &&
71  (pct[ti] !=
72  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
73  {
75  ("Non-existent intf_idx=%d with table_index=%d for delete",
76  sw_if_index, pct[ti]);
77  return VNET_API_ERROR_NO_SUCH_TABLE;
78  }
79 
80  /* Return ok on ADD operaton if feature is already enabled */
81  if (is_add &&
82  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
83  return 0;
84 
85  vnet_flow_classify_feature_enable (vm, fcm, sw_if_index, ti, is_add);
86 
87  if (is_add)
88  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = pct[ti];
89  else
90  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = ~0;
91  }
92 
93 
94  return 0;
95 }
96 
97 static clib_error_t *
99  unformat_input_t * input,
100  vlib_cli_command_t * cmd)
101 {
102  vnet_main_t *vnm = vnet_get_main ();
103  u32 sw_if_index = ~0;
104  u32 ip4_table_index = ~0;
105  u32 ip6_table_index = ~0;
106  u32 is_add = 1;
107  u32 idx_cnt = 0;
108  int rv;
109 
111  {
112  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
113  vnm, &sw_if_index))
114  ;
115  else if (unformat (input, "ip4-table %d", &ip4_table_index))
116  idx_cnt++;
117  else if (unformat (input, "ip6-table %d", &ip6_table_index))
118  idx_cnt++;
119  else if (unformat (input, "del"))
120  is_add = 0;
121  else
122  break;
123  }
124 
125  if (sw_if_index == ~0)
126  return clib_error_return (0, "Interface must be specified.");
127 
128  if (!idx_cnt)
129  return clib_error_return (0, "Table index should be specified.");
130 
131  if (idx_cnt > 1)
132  return clib_error_return (0, "Only one table index per API is allowed.");
133 
134  rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
135  ip6_table_index, is_add);
136 
137  switch (rv)
138  {
139  case 0:
140  break;
141 
142  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
143  return clib_error_return (0, "No such interface");
144 
145  case VNET_API_ERROR_NO_SUCH_ENTRY:
146  return clib_error_return (0, "No such classifier table");
147  }
148  return 0;
149 }
150 
151 /* *INDENT-OFF* */
152 VLIB_CLI_COMMAND (set_input_acl_command, static) = {
153  .path = "set flow classify",
154  .short_help =
155  "set flow classify interface <int> [ip4-table <index>]\n"
156  " [ip6-table <index>] [del]",
157  .function = set_flow_classify_command_fn,
158 };
159 /* *INDENT-ON* */
160 
161 static uword
162 unformat_table_type (unformat_input_t * input, va_list * va)
163 {
164  u32 *r = va_arg (*va, u32 *);
165  u32 tid;
166 
167  if (unformat (input, "ip4"))
169  else if (unformat (input, "ip6"))
171  else
172  return 0;
173 
174  *r = tid;
175  return 1;
176 }
177 
178 static clib_error_t *
180  unformat_input_t * input,
181  vlib_cli_command_t * cmd)
182 {
185  u32 *vec_tbl;
186  int i;
187 
188  if (unformat (input, "type %U", unformat_table_type, &type))
189  ;
190  else
191  return clib_error_return (0, "Type must be specified.");;
192 
193  if (type == FLOW_CLASSIFY_N_TABLES)
194  return clib_error_return (0, "Invalid table type.");
195 
196  vec_tbl = fcm->classify_table_index_by_sw_if_index[type];
197 
198  if (vec_len (vec_tbl))
199  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
200  "Interface name");
201  else
202  vlib_cli_output (vm, "No tables configured.");
203 
204  for (i = 0; i < vec_len (vec_tbl); i++)
205  {
206  if (vec_elt (vec_tbl, i) == ~0)
207  continue;
208 
209  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt (vec_tbl, i),
211  }
212 
213  return 0;
214 }
215 
216 /* *INDENT-OFF* */
217 VLIB_CLI_COMMAND (show_flow_classify_command, static) = {
218  .path = "show classify flow",
219  .short_help = "show classify flow type [ip4|ip6]",
220  .function = show_flow_classify_command_fn,
221 };
222 /* *INDENT-ON* */
223 
224 /*
225  * fd.io coding-style-patch-verification: ON
226  *
227  * Local Variables:
228  * eval: (c-set-style "gnu")
229  * End:
230  */
vnet_config_main_t config_main
Definition: feature.h:65
vnet_config_main_t * vnet_config_main[FLOW_CLASSIFY_N_TABLES]
Definition: flow_classify.h:45
static void vnet_flow_classify_feature_enable(vlib_main_t *vnm, flow_classify_main_t *fcm, u32 sw_if_index, flow_classify_table_id_t tid, int feature_enable)
Definition: flow_classify.c:20
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:47
flow_classify_table_id_t
Definition: flow_classify.h:23
unformat_function_t unformat_vnet_sw_interface
format_function_t format_vnet_sw_if_index_name
u32 * classify_table_index_by_sw_if_index[FLOW_CLASSIFY_N_TABLES]
Definition: flow_classify.h:39
#define clib_error_return(e, args...)
Definition: error.h:99
vnet_main_t * vnet_main
Definition: flow_classify.h:43
struct _unformat_input_t unformat_input_t
flow_classify_main_t flow_classify_main
Definition: flow_classify.c:17
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:283
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:47
#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:268
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:73
static clib_error_t * set_flow_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: flow_classify.c:98
unsigned int u32
Definition: types.h:88
static uword unformat_table_type(unformat_input_t *input, va_list *va)
static clib_error_t * show_flow_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
vnet_classify_main_t * vnet_classify_main
Definition: flow_classify.h:44
#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
#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