FD.io VPP  v18.07.1-11-g31aa6f2
Vector Packet Processing
feature.h
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 #ifndef included_features_h
17 #define included_features_h
18 
19 #include <vnet/vnet.h>
20 #include <vnet/api_errno.h>
21 #include <vnet/devices/devices.h>
22 
23 /** feature registration object */
24 typedef struct _vnet_feature_arc_registration
25 {
26  /** next registration in list of all registrations*/
27  struct _vnet_feature_arc_registration *next;
28  /** Feature Arc name */
29  char *arc_name;
30  /** Start nodes */
31  char **start_nodes;
32  int n_start_nodes;
33  /* Feature arc index, assigned by init function */
34  u8 feature_arc_index;
35  u8 *arc_index_ptr;
37 
38 /* Enable feature callback. */
40  (u32 sw_if_index, int enable_disable);
41 
42 /** feature registration object */
43 typedef struct _vnet_feature_registration
44 {
45  /** next registration in list of all registrations*/
46  struct _vnet_feature_registration *next, *next_in_arc;
47  /** Feature arc name */
48  char *arc_name;
49  /** Graph node name */
50  char *node_name;
51  /** Pointer to this feature index, filled in by vnet_feature_arc_init */
52  u32 *feature_index_ptr;
53  u32 feature_index;
54  /** Constraints of the form "this feature runs before X" */
55  char **runs_before;
56  /** Constraints of the form "this feature runs after Y" */
57  char **runs_after;
58 
59  /** Function to enable/disable feature **/
60  vnet_feature_enable_disable_function_t *enable_disable_cb;
62 
64 {
68 
69 typedef struct
70 {
71  /** feature arc configuration list */
74 
75  /** feature path configuration lists */
79 
80  /** feature config main objects */
82 
83  /** Save partial order results for show command */
84  char ***feature_nodes;
85 
86  /** bitmap of interfaces which have driver rx features configured */
88 
89  /** feature reference counts by interface */
91 
92  /** Feature arc index for device-input */
94 
95  /** convenience */
99 
101 
102 #define VNET_FEATURE_ARC_INIT(x,...) \
103  __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x;\
104 static void __vnet_add_feature_arc_registration_##x (void) \
105  __attribute__((__constructor__)) ; \
106 static void __vnet_add_feature_arc_registration_##x (void) \
107 { \
108  vnet_feature_main_t * fm = &feature_main; \
109  vnet_feat_arc_##x.next = fm->next_arc; \
110  fm->next_arc = & vnet_feat_arc_##x; \
111 } \
112 static void __vnet_rm_feature_arc_registration_##x (void) \
113  __attribute__((__destructor__)) ; \
114 static void __vnet_rm_feature_arc_registration_##x (void) \
115 { \
116  vnet_feature_main_t * fm = &feature_main; \
117  vnet_feature_arc_registration_t *r = &vnet_feat_arc_##x; \
118  VLIB_REMOVE_FROM_LINKED_LIST (fm->next_arc, r, next); \
119 } \
120 __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x
121 
122 #define VNET_FEATURE_INIT(x,...) \
123  __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x; \
124 static void __vnet_add_feature_registration_##x (void) \
125  __attribute__((__constructor__)) ; \
126 static void __vnet_add_feature_registration_##x (void) \
127 { \
128  vnet_feature_main_t * fm = &feature_main; \
129  vnet_feat_##x.next = fm->next_feature; \
130  fm->next_feature = & vnet_feat_##x; \
131 } \
132 static void __vnet_rm_feature_registration_##x (void) \
133  __attribute__((__destructor__)) ; \
134 static void __vnet_rm_feature_registration_##x (void) \
135 { \
136  vnet_feature_main_t * fm = &feature_main; \
137  vnet_feature_registration_t *r = &vnet_feat_##x; \
138  VLIB_REMOVE_FROM_LINKED_LIST (fm->next_feature, r, next); \
139 } \
140 __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x
141 
142 void
144  u32 sw_if_index, int is_add);
145 
146 u32 vnet_get_feature_index (u8 arc, const char *s);
147 u8 vnet_get_feature_arc_index (const char *s);
149  const char *node_name);
150 
151 
152 int
153 vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index,
154  u32 sw_if_index, int enable_disable,
155  void *feature_config,
156  u32 n_feature_config_bytes);
157 
158 int
159 vnet_feature_enable_disable (const char *arc_name, const char *node_name,
160  u32 sw_if_index, int enable_disable,
161  void *feature_config,
162  u32 n_feature_config_bytes);
163 
164 static inline vnet_feature_config_main_t *
166 {
168 
169  if (arc_index == (u8) ~ 0)
170  return 0;
171 
172  return &fm->feature_config_mains[arc_index];
173 }
174 
177 {
179  return &fm->feature_config_mains[arc];
180 }
181 
183 vnet_have_features (u8 arc, u32 sw_if_index)
184 {
186  return clib_bitmap_get (fm->sw_if_index_has_features[arc], sw_if_index);
187 }
188 
191 {
194  return vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
195 }
196 
198 vnet_feature_arc_start_with_data (u8 arc, u32 sw_if_index, u32 * next,
199  vlib_buffer_t * b, u32 n_data_bytes)
200 {
203  cm = &fm->feature_config_mains[arc];
204 
205  if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
206  {
207  vnet_buffer (b)->feature_arc_index = arc;
209  vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
211  next, n_data_bytes);
212  }
213  return 0;
214 }
215 
217 vnet_feature_arc_start (u8 arc, u32 sw_if_index, u32 * next0,
218  vlib_buffer_t * b0)
219 {
220  vnet_feature_arc_start_with_data (arc, sw_if_index, next0, b0, 0);
221 }
222 
224 vnet_feature_next_with_data (u32 sw_if_index, u32 * next0,
225  vlib_buffer_t * b0, u32 n_data_bytes)
226 {
228  u8 arc = vnet_buffer (b0)->feature_arc_index;
230 
231  return vnet_get_config_data (&cm->config_main,
232  &b0->current_config_index, next0,
233  n_data_bytes);
234 }
235 
237 vnet_feature_next (u32 sw_if_index, u32 * next0, vlib_buffer_t * b0)
238 {
239  vnet_feature_next_with_data (sw_if_index, next0, b0, 0);
240 }
241 
244 {
246  return vnet_have_features (fm->device_input_feature_arc_index, sw_if_index);
247 }
248 
251  vlib_buffer_t * b0)
252 {
255  u8 feature_arc_index = fm->device_input_feature_arc_index;
256  cm = &fm->feature_config_mains[feature_arc_index];
257 
258  if (PREDICT_FALSE
260  (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
261  {
262  /*
263  * Save next0 so that the last feature in the chain
264  * can skip ethernet-input if indicated...
265  */
266  u16 adv;
267 
268  vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
269  adv = device_input_next_node_advance[*next0];
270  vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
271  vlib_buffer_advance (b0, -adv);
272 
273  vnet_buffer (b0)->feature_arc_index = feature_arc_index;
275  vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
277  next0, /* # bytes of config data */ 0);
278  }
279 }
280 
283  u32 * next0,
284  u32 * next1,
285  vlib_buffer_t * b0, vlib_buffer_t * b1)
286 {
289  u8 feature_arc_index = fm->device_input_feature_arc_index;
290  cm = &fm->feature_config_mains[feature_arc_index];
291 
292  if (PREDICT_FALSE
294  (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
295  {
296  /*
297  * Save next0 so that the last feature in the chain
298  * can skip ethernet-input if indicated...
299  */
300  u16 adv;
301 
302  vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
303  adv = device_input_next_node_advance[*next0];
304  vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
305  vlib_buffer_advance (b0, -adv);
306 
307  vnet_buffer (b1)->device_input_feat.saved_next_index = *next1;
308  adv = device_input_next_node_advance[*next1];
309  vnet_buffer (b1)->device_input_feat.buffer_advance = adv;
310  vlib_buffer_advance (b1, -adv);
311 
312  vnet_buffer (b0)->feature_arc_index = feature_arc_index;
313  vnet_buffer (b1)->feature_arc_index = feature_arc_index;
315  vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
318  next0, /* # bytes of config data */ 0);
320  next1, /* # bytes of config data */ 0);
321  }
322 }
323 
326  u32 * next0,
327  u32 * next1,
328  u32 * next2,
329  u32 * next3,
330  vlib_buffer_t * b0,
331  vlib_buffer_t * b1,
332  vlib_buffer_t * b2, vlib_buffer_t * b3)
333 {
336  u8 feature_arc_index = fm->device_input_feature_arc_index;
337  cm = &fm->feature_config_mains[feature_arc_index];
338 
339  if (PREDICT_FALSE
341  (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
342  {
343  /*
344  * Save next0 so that the last feature in the chain
345  * can skip ethernet-input if indicated...
346  */
347  u16 adv;
348 
349  vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
350  adv = device_input_next_node_advance[*next0];
351  vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
352  vlib_buffer_advance (b0, -adv);
353 
354  vnet_buffer (b1)->device_input_feat.saved_next_index = *next1;
355  adv = device_input_next_node_advance[*next1];
356  vnet_buffer (b1)->device_input_feat.buffer_advance = adv;
357  vlib_buffer_advance (b1, -adv);
358 
359  vnet_buffer (b2)->device_input_feat.saved_next_index = *next2;
360  adv = device_input_next_node_advance[*next2];
361  vnet_buffer (b2)->device_input_feat.buffer_advance = adv;
362  vlib_buffer_advance (b2, -adv);
363 
364  vnet_buffer (b3)->device_input_feat.saved_next_index = *next3;
365  adv = device_input_next_node_advance[*next3];
366  vnet_buffer (b3)->device_input_feat.buffer_advance = adv;
367  vlib_buffer_advance (b3, -adv);
368 
369  vnet_buffer (b0)->feature_arc_index = feature_arc_index;
370  vnet_buffer (b1)->feature_arc_index = feature_arc_index;
371  vnet_buffer (b2)->feature_arc_index = feature_arc_index;
372  vnet_buffer (b3)->feature_arc_index = feature_arc_index;
373 
375  vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
379 
381  next0, /* # bytes of config data */ 0);
383  next1, /* # bytes of config data */ 0);
385  next2, /* # bytes of config data */ 0);
387  next3, /* # bytes of config data */ 0);
388  }
389 }
390 
391 #define VNET_FEATURES(...) (char*[]) { __VA_ARGS__, 0}
392 
394  vnet_config_main_t * vcm,
395  char **feature_start_nodes,
396  int num_feature_start_nodes,
398  first_reg, char ***feature_nodes);
399 
400 void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
401  int verbose);
402 
403 #endif /* included_feature_h */
404 
405 /*
406  * fd.io coding-style-patch-verification: ON
407  *
408  * Local Variables:
409  * eval: (c-set-style "gnu")
410  * End:
411  */
vnet_config_main_t config_main
Definition: feature.h:65
struct vnet_feature_config_main_t_ vnet_feature_config_main_t
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:132
char *** feature_nodes
Save partial order results for show command.
Definition: feature.h:84
vnet_feature_registration_t * next_feature
feature path configuration lists
Definition: feature.h:76
static_always_inline void vnet_feature_start_device_input_x4(u32 sw_if_index, u32 *next0, u32 *next1, u32 *next2, u32 *next3, vlib_buffer_t *b0, vlib_buffer_t *b1, vlib_buffer_t *b2, vlib_buffer_t *b3)
Definition: feature.h:325
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
Definition: feature.h:183
void vnet_config_update_feature_count(vnet_feature_main_t *fm, u8 arc, u32 sw_if_index, int is_add)
unsigned char u8
Definition: types.h:56
vnet_main_t * vnet_main
Definition: feature.h:97
#define static_always_inline
Definition: clib.h:93
u8 vnet_get_feature_arc_index(const char *s)
Definition: feature.c:127
vlib_main_t * vlib_main
convenience
Definition: feature.h:96
static_always_inline int vnet_device_input_have_features(u32 sw_if_index)
Definition: feature.h:243
void vnet_interface_features_show(vlib_main_t *vm, u32 sw_if_index, int verbose)
Display the set of driver features configured on a specific interface Called by "show interface" hand...
Definition: feature.c:338
vnet_feature_main_t feature_main
Definition: feature.c:19
unsigned int u32
Definition: types.h:88
const u32 device_input_next_node_advance[((VNET_DEVICE_INPUT_N_NEXT_NODES/CLIB_CACHE_LINE_BYTES)+1)*CLIB_CACHE_LINE_BYTES]
Definition: devices.c:47
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:118
unsigned short u16
Definition: types.h:57
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:122
#define PREDICT_FALSE(x)
Definition: clib.h:105
static_always_inline void vnet_feature_next(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:237
uword ** next_feature_by_name
Definition: feature.h:78
static_always_inline void vnet_feature_start_device_input_x2(u32 sw_if_index, u32 *next0, u32 *next1, vlib_buffer_t *b0, vlib_buffer_t *b1)
Definition: feature.h:282
int vnet_feature_enable_disable_with_index(u8 arc_index, u32 feature_index, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:181
vlib_main_t * vm
Definition: buffer.c:294
u32 vnet_get_feature_index(u8 arc, const char *s)
Definition: feature.c:163
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
uword ** arc_index_by_name
Definition: feature.h:73
i16 ** feature_count_by_sw_if_index
feature reference counts by interface
Definition: feature.h:90
vnet_feature_registration_t ** next_feature_by_arc
Definition: feature.h:77
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:215
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:233
clib_error_t *( vnet_feature_enable_disable_function_t)(u32 sw_if_index, int enable_disable)
Definition: feature.h:40
#define vec_elt(v, i)
Get vector value at index i.
u8 device_input_feature_arc_index
Feature arc index for device-input.
Definition: feature.h:93
static_always_inline u32 vnet_get_feature_config_index(u8 arc, u32 sw_if_index)
Definition: feature.h:190
static_always_inline void * vnet_feature_arc_start_with_data(u8 arc, u32 sw_if_index, u32 *next, vlib_buffer_t *b, u32 n_data_bytes)
Definition: feature.h:198
u64 uword
Definition: types.h:112
static vnet_feature_config_main_t * vnet_get_feature_arc_config_main(u8 arc_index)
Definition: feature.h:165
static_always_inline void * vnet_feature_next_with_data(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0, u32 n_data_bytes)
Definition: feature.h:224
struct _vnet_feature_arc_registration vnet_feature_arc_registration_t
feature registration object
#define vnet_buffer(b)
Definition: buffer.h:360
vnet_feature_arc_registration_t * next_arc
feature arc configuration list
Definition: feature.h:72
static_always_inline void vnet_feature_start_device_input_x1(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:250
uword ** sw_if_index_has_features
bitmap of interfaces which have driver rx features configured
Definition: feature.h:87
vnet_feature_registration_t * vnet_get_feature_reg(const char *arc_name, const char *node_name)
Definition: feature.c:142
vnet_feature_config_main_t * feature_config_mains
feature config main objects
Definition: feature.h:81
static_always_inline vnet_feature_config_main_t * vnet_feature_get_config_main(u16 arc)
Definition: feature.h:176
struct _vnet_feature_registration vnet_feature_registration_t
feature registration object
signed short i16
Definition: types.h:46
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:217