FD.io VPP  v17.07.01-10-g3be13f0
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 
17 static void
20  u32 sw_if_index,
22  int feature_enable)
23 {
25  u8 arc;
26 
27  if (tid == FLOW_CLASSIFY_TABLE_IP4)
28  {
29  vnet_feature_enable_disable ("ip4-unicast", "ip4-flow-classify",
30  sw_if_index, feature_enable, 0, 0);
31  arc = vnet_get_feature_arc_index ("ip4-unicast");
32  }
33  else
34  {
35  vnet_feature_enable_disable ("ip6-unicast", "ip6-flow-classify",
36  sw_if_index, feature_enable, 0, 0);
37  arc = vnet_get_feature_arc_index ("ip6-unicast");
38  }
39 
41  fcm->vnet_config_main[tid] = &vfcm->config_main;
42 }
43 
45  u32 ip4_table_index, u32 ip6_table_index,
46  u32 is_add)
47 {
50  u32 pct[FLOW_CLASSIFY_N_TABLES] = {ip4_table_index, ip6_table_index};
51  u32 ti;
52 
53  /* Assume that we've validated sw_if_index in the API layer */
54 
55  for (ti = 0; ti < FLOW_CLASSIFY_N_TABLES; ti++)
56  {
57  if (pct[ti] == ~0)
58  continue;
59 
60  if (pool_is_free_index (vcm->tables, pct[ti]))
61  return VNET_API_ERROR_NO_SUCH_TABLE;
62 
64  (fcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
65 
66  /* Reject any DEL operation with wrong sw_if_index */
67  if (!is_add &&
68  (pct[ti] != fcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
69  {
70  clib_warning ("Non-existent intf_idx=%d with table_index=%d for delete",
71  sw_if_index, pct[ti]);
72  return VNET_API_ERROR_NO_SUCH_TABLE;
73  }
74 
75  /* Return ok on ADD operaton if feature is already enabled */
76  if (is_add &&
77  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
78  return 0;
79 
80  vnet_flow_classify_feature_enable (vm, fcm, sw_if_index, ti, is_add);
81 
82  if (is_add)
83  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = pct[ti];
84  else
85  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = ~0;
86  }
87 
88 
89  return 0;
90 }
91 
92 static clib_error_t *
94  unformat_input_t * input,
95  vlib_cli_command_t * cmd)
96 {
97  vnet_main_t * vnm = vnet_get_main();
98  u32 sw_if_index = ~0;
99  u32 ip4_table_index = ~0;
100  u32 ip6_table_index = ~0;
101  u32 is_add = 1;
102  u32 idx_cnt = 0;
103  int rv;
104 
106  {
107  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
108  vnm, &sw_if_index))
109  ;
110  else if (unformat (input, "ip4-table %d", &ip4_table_index))
111  idx_cnt++;
112  else if (unformat (input, "ip6-table %d", &ip6_table_index))
113  idx_cnt++;
114  else if (unformat (input, "del"))
115  is_add = 0;
116  else
117  break;
118  }
119 
120  if (sw_if_index == ~0)
121  return clib_error_return (0, "Interface must be specified.");
122 
123  if (!idx_cnt)
124  return clib_error_return (0, "Table index should be specified.");
125 
126  if (idx_cnt > 1)
127  return clib_error_return (0, "Only one table index per API is allowed.");
128 
129  rv = vnet_set_flow_classify_intfc(vm, sw_if_index, ip4_table_index,
130  ip6_table_index, is_add);
131 
132  switch (rv)
133  {
134  case 0:
135  break;
136 
137  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
138  return clib_error_return (0, "No such interface");
139 
140  case VNET_API_ERROR_NO_SUCH_ENTRY:
141  return clib_error_return (0, "No such classifier table");
142  }
143  return 0;
144 }
145 
146 VLIB_CLI_COMMAND (set_input_acl_command, static) = {
147  .path = "set flow classify",
148  .short_help =
149  "set flow classify interface <int> [ip4-table <index>]\n"
150  " [ip6-table <index>] [del]",
151  .function = set_flow_classify_command_fn,
152 };
153 
154 static uword
155 unformat_table_type (unformat_input_t * input, va_list * va)
156 {
157  u32 * r = va_arg (*va, u32 *);
158  u32 tid;
159 
160  if (unformat (input, "ip4"))
162  else if (unformat (input, "ip6"))
164  else
165  return 0;
166 
167  *r = tid;
168  return 1;
169 }
170 static clib_error_t *
172  unformat_input_t * input,
173  vlib_cli_command_t * cmd)
174 {
177  u32 * vec_tbl;
178  int i;
179 
180  if (unformat (input, "type %U", unformat_table_type, &type))
181  ;
182  else
183  return clib_error_return (0, "Type must be specified.");;
184 
185  if (type == FLOW_CLASSIFY_N_TABLES)
186  return clib_error_return (0, "Invalid table type.");
187 
188  vec_tbl = fcm->classify_table_index_by_sw_if_index[type];
189 
190  if (vec_len(vec_tbl))
191  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
192  "Interface name");
193  else
194  vlib_cli_output (vm, "No tables configured.");
195 
196  for (i = 0; i < vec_len (vec_tbl); i++)
197  {
198  if (vec_elt(vec_tbl, i) == ~0)
199  continue;
200 
201  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt(vec_tbl, i),
203  }
204 
205  return 0;
206 }
207 
208 VLIB_CLI_COMMAND (show_flow_classify_command, static) = {
209  .path = "show classify flow",
210  .short_help = "show classify flow type [ip4|ip6]",
211  .function = show_flow_classify_command_fn,
212 };
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:42
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:18
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:123
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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:36
#define clib_error_return(e, args...)
Definition: error.h:99
flow_classify_main_t flow_classify_main
Definition: flow_classify.h:45
vnet_main_t * vnet_main
Definition: flow_classify.h:40
struct _unformat_input_t unformat_input_t
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
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:44
#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:238
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:72
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:93
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:41
#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:485
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:225
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169