FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
feature.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>
17 
19 
20 static clib_error_t *
22 {
26  u32 arc_index = 0;
27 
28  fm->arc_index_by_name = hash_create_string (0, sizeof (uword));
29  areg = fm->next_arc;
30 
31  /* process feature arc registrations */
32  while (areg)
33  {
34  char *s;
35  int i = 0;
36  areg->feature_arc_index = arc_index;
37  hash_set_mem (fm->arc_index_by_name, areg->arc_name,
38  pointer_to_uword (areg));
39 
40  /* process start nodes */
41  while ((s = areg->start_nodes[i]))
42  {
43  vlib_node_t *n;
45  n = vlib_get_node_by_name (vm, (u8 *) s);
46 
47  if (n == 0)
48  return clib_error_return (0,
49  "Unknown start node '%s' on feature arc '%s'",
50  s, areg->arc_name);
51 
52  rt = vlib_node_get_runtime (vm, n->index);
53  rt->feature_arc_index = arc_index;
54  i++;
55  }
56  areg->n_start_nodes = i;
57 
58  /* next */
59  areg = areg->next;
60  arc_index++;
61  }
62 
63  vec_validate (fm->next_feature_by_arc, arc_index - 1);
64  vec_validate (fm->feature_nodes, arc_index - 1);
65  vec_validate (fm->feature_config_mains, arc_index - 1);
66  vec_validate (fm->next_feature_by_name, arc_index - 1);
67  vec_validate (fm->sw_if_index_has_features, arc_index - 1);
68  vec_validate (fm->feature_count_by_sw_if_index, arc_index - 1);
69 
70  freg = fm->next_feature;
71  while (freg)
72  {
73  vlib_node_t *n;
75  uword *p = hash_get_mem (fm->arc_index_by_name, freg->arc_name);
76  if (p == 0)
77  return clib_error_return (0, "Unknown feature arc '%s'",
78  freg->arc_name);
79 
81  arc_index = areg->feature_arc_index;
82 
83  /* set feature arc index in node runtime */
84  n = vlib_get_node_by_name (vm, (u8 *) freg->node_name);
85  if (n == 0)
86  return clib_error_return (0, "Unknown node '%s', freg->node_name");
87  rt = vlib_node_get_runtime (vm, n->index);
88  rt->feature_arc_index = arc_index;
89 
90  vec_add1 (fm->next_feature_by_arc[arc_index], *freg);
91 
92  /* next */
93  freg = freg->next;
94  }
95 
96  while (areg)
97  {
98  clib_error_t *error;
100  vnet_config_main_t *vcm;
101 
102  arc_index = areg->feature_arc_index;
103  cm = &fm->feature_config_mains[arc_index];
104  vcm = &cm->config_main;
105  if ((error = vnet_feature_arc_init (vm, vcm,
106  areg->start_nodes,
107  areg->n_start_nodes,
108  fm->next_feature_by_arc[arc_index],
109  &fm->feature_nodes[arc_index])))
110  {
111  return error;
112  }
113 
114  fm->next_feature_by_name[arc_index] =
115  hash_create_string (0, sizeof (uword));
116  freg = fm->next_feature_by_arc[arc_index];
117 
118  while (freg)
119  {
120  hash_set_mem (fm->next_feature_by_name[arc_index],
121  freg->node_name, pointer_to_uword (freg));
122  freg = freg->next;
123  }
124 
125  /* next */
126  areg = areg->next;
127  arc_index++;
128  }
129 
130  return 0;
131 }
132 
134 
135 void
137  u32 sw_if_index, int is_add)
138 {
139  uword bit_value;
140 
141  vec_validate (fm->feature_count_by_sw_if_index[arc], sw_if_index);
142 
143  fm->feature_count_by_sw_if_index[arc][sw_if_index] += is_add ? 1 : -1;
144 
145  ASSERT (fm->feature_count_by_sw_if_index[arc][sw_if_index] >= 0);
146 
147  bit_value = fm->feature_count_by_sw_if_index[arc][sw_if_index] > 0;
148 
149  fm->sw_if_index_has_features[arc] =
150  clib_bitmap_set (fm->sw_if_index_has_features[arc], sw_if_index,
151  bit_value);
152 }
153 
154 u16
156 {
159  uword *p;
160 
161  p = hash_get_mem (fm->arc_index_by_name, s);
162  if (p == 0)
163  return ~0;
164 
166  return reg->feature_arc_index;
167 }
168 
169 u32
171 {
174  uword *p;
175 
176  p = hash_get_mem (fm->next_feature_by_name[arc], s);
177  if (p == 0)
178  return ~0;
179 
181  return reg->feature_index_u32;
182 }
183 
184 void
185 vnet_feature_enable_disable (const char *arc_name, const char *node_name,
186  u32 sw_if_index, int enable_disable,
187  void *feature_config, u32 n_feature_config_bytes)
188 {
191  u32 feature_index, ci;
192  u16 arc_index;
193 
194  arc_index = vnet_feature_arc_index_from_node_name (arc_name);
195 
196  if (arc_index == ~0)
197  return;
198 
199  cm = &fm->feature_config_mains[arc_index];
201  feature_index = vnet_feature_index_from_node_name (arc_index, node_name);
202  if (feature_index == ~0)
203  return;
204  ci = cm->config_index_by_sw_if_index[sw_if_index];
205 
206  ci = (enable_disable
209  (vlib_get_main (), &cm->config_main, ci, feature_index, feature_config,
210  n_feature_config_bytes);
211  cm->config_index_by_sw_if_index[sw_if_index] = ci;
212 
213  vnet_config_update_feature_count (fm, arc_index, sw_if_index,
214  enable_disable);
215 
216 }
217 
218 
219 /** Display the set of available driver features.
220  Useful for verifying that expected features are present
221 */
222 
223 static clib_error_t *
225  unformat_input_t * input, vlib_cli_command_t * cmd)
226 {
230 
231  vlib_cli_output (vm, "Available feature paths");
232 
233  areg = fm->next_arc;
234  while (areg)
235  {
236  vlib_cli_output (vm, "%s:", areg->arc_name);
237  vec_foreach (freg, fm->next_feature_by_arc[areg->feature_arc_index])
238  {
239  vlib_cli_output (vm, " %s\n", freg->node_name);
240  }
241 
242 
243  /* next */
244  areg = areg->next;
245  }
246 
247  return 0;
248 }
249 
250 /*?
251  * Display the set of available driver features
252  *
253  * @cliexpar
254  * Example:
255  * @cliexcmd{show ip features}
256  * @cliexend
257  * @endparblock
258 ?*/
259 /* *INDENT-OFF* */
260 VLIB_CLI_COMMAND (show_features_command, static) = {
261  .path = "show features",
262  .short_help = "show features",
263  .function = show_features_command_fn,
264 };
265 /* *INDENT-ON* */
266 
267 /** Display the set of driver features configured on a specific interface
268  * Called by "show interface" handler
269  */
270 
271 void
273 {
275  u32 node_index, current_config_index;
276  u16 feature_arc;
279  vnet_config_main_t *vcm;
280  vnet_config_t *cfg;
281  u32 cfg_index;
282  vnet_config_feature_t *feat;
283  vlib_node_t *n;
284  int i;
285 
286  vlib_cli_output (vm, "Driver feature paths configured on %U...",
288  vnet_get_main (), sw_if_index);
289 
290  areg = fm->next_arc;
291  while (areg)
292  {
293  feature_arc = areg->feature_arc_index;
294  vcm = &(cm[feature_arc].config_main);
295 
296  vlib_cli_output (vm, "\n%s:", areg->arc_name);
297  areg = areg->next;
298 
299  if (NULL == cm[feature_arc].config_index_by_sw_if_index ||
300  vec_len (cm[feature_arc].config_index_by_sw_if_index) < sw_if_index)
301  {
302  vlib_cli_output (vm, " none configured");
303  continue;
304  }
305 
306  current_config_index =
307  vec_elt (cm[feature_arc].config_index_by_sw_if_index, sw_if_index);
308 
309  if (current_config_index == ~0)
310  {
311  vlib_cli_output (vm, " none configured");
312  continue;
313  }
314 
315  ASSERT (current_config_index
317 
318  cfg_index = vcm->config_pool_index_by_user_index[current_config_index];
319  cfg = pool_elt_at_index (vcm->config_pool, cfg_index);
320 
321  for (i = 0; i < vec_len (cfg->features); i++)
322  {
323  feat = cfg->features + i;
324  node_index = feat->node_index;
325  n = vlib_get_node (vm, node_index);
326  vlib_cli_output (vm, " %v", n->name);
327  }
328  }
329 }
330 
331 /*
332  * fd.io coding-style-patch-verification: ON
333  *
334  * Local Variables:
335  * eval: (c-set-style "gnu")
336  * End:
337  */
vnet_config_main_t config_main
Definition: feature.h:55
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
vnet_config_feature_t * features
Definition: config.h:71
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
char *** feature_nodes
Save partial order results for show command.
Definition: feature.h:74
vnet_feature_registration_t * next_feature
feature path configuration lists
Definition: feature.h:66
#define NULL
Definition: clib.h:55
u32 index
Definition: node.h:237
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
vnet_feature_main_t feature_main
Definition: feature.c:18
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
#define hash_set_mem(h, key, value)
Definition: hash.h:274
u32 vnet_feature_index_from_node_name(u16 arc, const char *s)
Definition: feature.c:170
u16 vnet_feature_arc_index_from_node_name(const char *s)
Definition: feature.c:155
format_function_t format_vnet_sw_if_index_name
void 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:185
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
void vnet_interface_features_show(vlib_main_t *vm, u32 sw_if_index)
Display the set of driver features configured on a specific interface Called by "show interface" hand...
Definition: feature.c:272
static clib_error_t * show_features_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Display the set of available driver features.
Definition: feature.c:224
static uword pointer_to_uword(const void *p)
Definition: types.h:131
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
clib_error_t * vnet_feature_arc_init(vlib_main_t *vm, vnet_config_main_t *vcm, char **feature_start_nodes, int num_feature_start_nodes, vnet_feature_registration_t *first_reg, char ***feature_nodes)
Initialize a feature graph arc.
Definition: registration.c:127
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
uword ** next_feature_by_name
Definition: feature.h:68
#define uword_to_pointer(u, type)
Definition: types.h:136
u8 * name
Definition: node.h:221
u32 * config_pool_index_by_user_index
Definition: config.h:104
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:88
uword ** arc_index_by_name
Definition: feature.h:63
i16 ** feature_count_by_sw_if_index
feature reference counts by interface
Definition: feature.h:80
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static clib_error_t * vnet_feature_init(vlib_main_t *vm)
Definition: feature.c:21
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void vnet_config_update_feature_count(vnet_feature_main_t *fm, u16 arc, u32 sw_if_index, int is_add)
Definition: feature.c:136
vnet_feature_registration_t ** next_feature_by_arc
Definition: feature.h:67
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.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
struct _vnet_feature_arc_registration vnet_feature_arc_registration_t
feature registration object
#define hash_get_mem(h, key)
Definition: hash.h:268
vnet_feature_arc_registration_t * next_arc
feature arc configuration list
Definition: feature.h:62
uword ** sw_if_index_has_features
bitmap of interfaces which have driver rx features configured
Definition: feature.h:77
vnet_config_t * config_pool
Definition: config.h:89
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
#define vec_foreach(var, vec)
Vector iterator.
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
vnet_feature_config_main_t * feature_config_mains
feature config main objects
Definition: feature.h:71
#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
u16 feature_arc_index
Definition: node.h:469
struct _vnet_feature_registration vnet_feature_registration_t
feature registration object