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