FD.io VPP  v16.12-rc0-308-g931be3a
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 {
24  ip_lookup_main_t * lm;
26  u32 ftype;
27  u32 ci;
28 
29  if (tid == FLOW_CLASSIFY_TABLE_IP4)
30  {
31  lm = &ip4_main.lookup_main;
33  }
34  else
35  {
36  lm = &ip6_main.lookup_main;
38  }
39 
41 
42  ci = ifcm->config_index_by_sw_if_index[sw_if_index];
43  ci = (feature_enable ? vnet_config_add_feature : vnet_config_del_feature)
44  (vnm, &ifcm->config_main, ci, ftype, 0, 0);
45 
46  ifcm->config_index_by_sw_if_index[sw_if_index] = ci;
47  fcm->vnet_config_main[tid] = &ifcm->config_main;
48 }
49 
51  u32 ip4_table_index, u32 ip6_table_index,
52  u32 is_add)
53 {
56  u32 pct[FLOW_CLASSIFY_N_TABLES] = {ip4_table_index, ip6_table_index};
57  u32 ti;
58 
59  /* Assume that we've validated sw_if_index in the API layer */
60 
61  for (ti = 0; ti < FLOW_CLASSIFY_N_TABLES; ti++)
62  {
63  if (pct[ti] == ~0)
64  continue;
65 
66  if (pool_is_free_index (vcm->tables, pct[ti]))
67  return VNET_API_ERROR_NO_SUCH_TABLE;
68 
70  (fcm->classify_table_index_by_sw_if_index[ti], sw_if_index, ~0);
71 
72  /* Reject any DEL operation with wrong sw_if_index */
73  if (!is_add &&
74  (pct[ti] != fcm->classify_table_index_by_sw_if_index[ti][sw_if_index]))
75  {
76  clib_warning ("Non-existent intf_idx=%d with table_index=%d for delete",
77  sw_if_index, pct[ti]);
78  return VNET_API_ERROR_NO_SUCH_TABLE;
79  }
80 
81  /* Return ok on ADD operaton if feature is already enabled */
82  if (is_add &&
83  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] != ~0)
84  return 0;
85 
86  vnet_flow_classify_feature_enable (vm, fcm, sw_if_index, ti, is_add);
87 
88  if (is_add)
89  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = pct[ti];
90  else
91  fcm->classify_table_index_by_sw_if_index[ti][sw_if_index] = ~0;
92  }
93 
94 
95  return 0;
96 }
97 
98 static clib_error_t *
100  unformat_input_t * input,
101  vlib_cli_command_t * cmd)
102 {
103  vnet_main_t * vnm = vnet_get_main();
104  u32 sw_if_index = ~0;
105  u32 ip4_table_index = ~0;
106  u32 ip6_table_index = ~0;
107  u32 is_add = 1;
108  u32 idx_cnt = 0;
109  int rv;
110 
112  {
113  if (unformat (input, "interface %U", unformat_vnet_sw_interface,
114  vnm, &sw_if_index))
115  ;
116  else if (unformat (input, "ip4-table %d", &ip4_table_index))
117  idx_cnt++;
118  else if (unformat (input, "ip6-table %d", &ip6_table_index))
119  idx_cnt++;
120  else if (unformat (input, "del"))
121  is_add = 0;
122  else
123  break;
124  }
125 
126  if (sw_if_index == ~0)
127  return clib_error_return (0, "Interface must be specified.");
128 
129  if (!idx_cnt)
130  return clib_error_return (0, "Table index should be specified.");
131 
132  if (idx_cnt > 1)
133  return clib_error_return (0, "Only one table index per API is allowed.");
134 
135  rv = vnet_set_flow_classify_intfc(vm, sw_if_index, ip4_table_index,
136  ip6_table_index, is_add);
137 
138  switch (rv)
139  {
140  case 0:
141  break;
142 
143  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
144  return clib_error_return (0, "No such interface");
145 
146  case VNET_API_ERROR_NO_SUCH_ENTRY:
147  return clib_error_return (0, "No such classifier table");
148  }
149  return 0;
150 }
151 
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 
160 static uword
161 unformat_table_type (unformat_input_t * input, va_list * va)
162 {
163  u32 * r = va_arg (*va, u32 *);
164  u32 tid;
165 
166  if (unformat (input, "ip4"))
168  else if (unformat (input, "ip6"))
170  else
171  return 0;
172 
173  *r = tid;
174  return 1;
175 }
176 static clib_error_t *
178  unformat_input_t * input,
179  vlib_cli_command_t * cmd)
180 {
183  u32 * vec_tbl;
184  int i;
185 
186  if (unformat (input, "type %U", unformat_table_type, &type))
187  ;
188  else
189  return clib_error_return (0, "Type must be specified.");;
190 
191  if (type == FLOW_CLASSIFY_N_TABLES)
192  return clib_error_return (0, "Invalid table type.");
193 
195 
196  if (vec_len(vec_tbl))
197  vlib_cli_output (vm, "%10s%20s\t\t%s", "Intfc idx", "Classify table",
198  "Interface name");
199  else
200  vlib_cli_output (vm, "No tables configured.");
201 
202  for (i = 0; i < vec_len (vec_tbl); i++)
203  {
204  if (vec_elt(vec_tbl, i) == ~0)
205  continue;
206 
207  vlib_cli_output (vm, "%10d%20d\t\t%U", i, vec_elt(vec_tbl, i),
209  }
210 
211  return 0;
212 }
213 
214 VLIB_CLI_COMMAND (show_flow_classify_command, static) = {
215  .path = "show classify flow",
216  .short_help = "show classify flow type [ip4|ip6]",
217  .function = show_flow_classify_command_fn,
218 };
vnet_config_main_t config_main
Definition: feature.h:55
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:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u32 vnet_config_del_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
Definition: config.c:300
ip_lookup_main_t lookup_main
Definition: ip4.h:96
flow_classify_table_id_t
Definition: flow_classify.h:23
unformat_function_t unformat_vnet_sw_interface
u32 ip6_unicast_rx_feature_flow_classify
Definition: ip6.h:169
u32 ip4_unicast_rx_feature_flow_classify
Built-in unicast feature path index, see vnet_feature_arc_init()
Definition: ip4.h:131
format_function_t format_vnet_sw_if_index_name
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u32 * classify_table_index_by_sw_if_index[FLOW_CLASSIFY_N_TABLES]
Definition: flow_classify.h:36
#define clib_warning(format, args...)
Definition: error.h:59
flow_classify_main_t flow_classify_main
Definition: flow_classify.h:45
vnet_main_t * vnet_main
Definition: flow_classify.h:40
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
vnet_feature_config_main_t feature_config_mains[VNET_N_IP_FEAT]
rx unicast, multicast, tx interface/feature configuration.
Definition: lookup.h:360
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:50
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:211
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:50
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:99
unsigned int u32
Definition: types.h:88
static uword unformat_table_type(unformat_input_t *input, va_list *va)
ip6_main_t ip6_main
Definition: ip6_forward.c:2655
ip_lookup_main_t lookup_main
Definition: ip6.h:132
static clib_error_t * show_flow_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 vnet_config_add_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
Definition: config.c:239
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)
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1060
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
#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:445