LCOV - code coverage report
Current view: top level - vnet/feature - feature.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 54 61 88.5 %
Date: 2023-10-26 01:39:38 Functions: 11 13 84.6 %

          Line data    Source code
       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             :   /** End of the arc (optional, for consistency-checking) */
      34             :   char *last_in_arc;
      35             :   /* Feature arc index, assigned by init function */
      36             :   u8 feature_arc_index;
      37             :   u8 *arc_index_ptr;
      38             : } vnet_feature_arc_registration_t;
      39             : 
      40             : /* Enable feature callback. */
      41             : typedef clib_error_t *(vnet_feature_enable_disable_function_t)
      42             :   (u32 sw_if_index, int enable_disable);
      43             : 
      44             : /** feature registration object */
      45             : typedef struct _vnet_feature_registration
      46             : {
      47             :   /** next registration in list of all registrations*/
      48             :   struct _vnet_feature_registration *next, *next_in_arc;
      49             :   /** Feature arc name */
      50             :   char *arc_name;
      51             :   /** Graph node name */
      52             :   char *node_name;
      53             :   /** Pointer to this feature index, filled in by vnet_feature_arc_init */
      54             :   u32 *feature_index_ptr;
      55             :   u32 feature_index;
      56             :   /** Constraints of the form "this feature runs before X" */
      57             :   char **runs_before;
      58             :   /** Constraints of the form "this feature runs after Y" */
      59             :   char **runs_after;
      60             : 
      61             :   /** Function to enable/disable feature  **/
      62             :   vnet_feature_enable_disable_function_t *enable_disable_cb;
      63             : } vnet_feature_registration_t;
      64             : 
      65             : /** constraint registration object */
      66             : typedef struct _vnet_feature_constraint_registration
      67             : {
      68             :   /** next constraint set in list of all registrations*/
      69             :   struct _vnet_feature_constraint_registration *next, *next_in_arc;
      70             :   /** Feature arc name */
      71             :   char *arc_name;
      72             : 
      73             :   /** Feature arc index, assigned by init function */
      74             :   u8 feature_arc_index;
      75             : 
      76             :   /** Node names, to run in the specified order */
      77             :   char **node_names;
      78             : } vnet_feature_constraint_registration_t;
      79             : 
      80             : typedef struct vnet_feature_config_main_t_
      81             : {
      82             :   vnet_config_main_t config_main;
      83             :   u32 *config_index_by_sw_if_index;
      84             : } vnet_feature_config_main_t;
      85             : 
      86             : typedef struct
      87             : {
      88             :   /** feature arc configuration list */
      89             :   vnet_feature_arc_registration_t *next_arc;
      90             :   uword **arc_index_by_name;
      91             : 
      92             :   /** feature path configuration lists */
      93             :   vnet_feature_registration_t *next_feature;
      94             :   vnet_feature_registration_t **next_feature_by_arc;
      95             :   vnet_feature_constraint_registration_t *next_constraint;
      96             :   vnet_feature_constraint_registration_t **next_constraint_by_arc;
      97             :   uword **next_feature_by_name;
      98             : 
      99             :   /** feature config main objects */
     100             :   vnet_feature_config_main_t *feature_config_mains;
     101             : 
     102             :   /** Save partial order results for show command */
     103             :   char ***feature_nodes;
     104             : 
     105             :   /** bitmap of interfaces which have driver rx features configured */
     106             :   uword **sw_if_index_has_features;
     107             : 
     108             :   /** feature reference counts by interface */
     109             :   i16 **feature_count_by_sw_if_index;
     110             : 
     111             :   /** Feature arc index for device-input */
     112             :   u8 device_input_feature_arc_index;
     113             : 
     114             :   /** convenience */
     115             :   vlib_main_t *vlib_main;
     116             :   vnet_main_t *vnet_main;
     117             : } vnet_feature_main_t;
     118             : 
     119             : extern vnet_feature_main_t feature_main;
     120             : 
     121             : #ifndef CLIB_MARCH_VARIANT
     122             : #define VNET_FEATURE_ARC_INIT(x,...)                            \
     123             :   __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x;\
     124             : static void __vnet_add_feature_arc_registration_##x (void)      \
     125             :   __attribute__((__constructor__)) ;                            \
     126             : static void __vnet_add_feature_arc_registration_##x (void)      \
     127             : {                                                               \
     128             :   vnet_feature_main_t * fm = &feature_main;                 \
     129             :   vnet_feat_arc_##x.next = fm->next_arc;                     \
     130             :   fm->next_arc = & vnet_feat_arc_##x;                            \
     131             : }                                                               \
     132             : static void __vnet_rm_feature_arc_registration_##x (void)       \
     133             :   __attribute__((__destructor__)) ;                             \
     134             : static void __vnet_rm_feature_arc_registration_##x (void)       \
     135             : {                                                               \
     136             :   vnet_feature_main_t * fm = &feature_main;                 \
     137             :   vnet_feature_arc_registration_t *r = &vnet_feat_arc_##x;  \
     138             :   VLIB_REMOVE_FROM_LINKED_LIST (fm->next_arc, r, next);              \
     139             : }                                                               \
     140             : __VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x
     141             : 
     142             : #define VNET_FEATURE_INIT(x,...)                                \
     143             :   __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x;        \
     144             : static void __vnet_add_feature_registration_##x (void)          \
     145             :   __attribute__((__constructor__)) ;                            \
     146             : static void __vnet_add_feature_registration_##x (void)          \
     147             : {                                                               \
     148             :   vnet_feature_main_t * fm = &feature_main;                 \
     149             :   vnet_feat_##x.next = fm->next_feature;                     \
     150             :   fm->next_feature = & vnet_feat_##x;                            \
     151             : }                                                               \
     152             : static void __vnet_rm_feature_registration_##x (void)           \
     153             :   __attribute__((__destructor__)) ;                             \
     154             : static void __vnet_rm_feature_registration_##x (void)           \
     155             : {                                                               \
     156             :   vnet_feature_main_t * fm = &feature_main;                 \
     157             :   vnet_feature_registration_t *r = &vnet_feat_##x;          \
     158             :   VLIB_REMOVE_FROM_LINKED_LIST (fm->next_feature, r, next);  \
     159             : }                                                               \
     160             : __VA_ARGS__ vnet_feature_registration_t vnet_feat_##x
     161             : 
     162             : #define VNET_FEATURE_ARC_ORDER(x,...)                                   \
     163             :   __VA_ARGS__ vnet_feature_constraint_registration_t                    \
     164             : vnet_feature_constraint_##x;                                            \
     165             : static void __vnet_add_constraint_registration_##x (void)               \
     166             :   __attribute__((__constructor__)) ;                                    \
     167             : static void __vnet_add_constraint_registration_##x (void)               \
     168             : {                                                                       \
     169             :   vnet_feature_main_t * fm = &feature_main;                             \
     170             :   vnet_feature_constraint_##x.next = fm->next_constraint;               \
     171             :   fm->next_constraint = & vnet_feature_constraint_##x;                  \
     172             : }                                                                       \
     173             : static void __vnet_rm_constraint_registration_##x (void)                \
     174             :   __attribute__((__destructor__)) ;                                     \
     175             : static void __vnet_rm_constraint_registration_##x (void)                \
     176             : {                                                                       \
     177             :   vnet_feature_main_t * fm = &feature_main;                             \
     178             :   vnet_feature_constraint_registration_t *r = &vnet_feature_constraint_##x; \
     179             :   VLIB_REMOVE_FROM_LINKED_LIST (fm->next_constraint, r, next);          \
     180             : }                                                                       \
     181             : __VA_ARGS__ vnet_feature_constraint_registration_t vnet_feature_constraint_##x
     182             : 
     183             : #else
     184             : #define VNET_FEATURE_ARC_INIT(x,...)                            \
     185             : extern vnet_feature_arc_registration_t __clib_unused vnet_feat_arc_##x; \
     186             : static vnet_feature_arc_registration_t __clib_unused __clib_unused_vnet_feat_arc_##x
     187             : #define VNET_FEATURE_INIT(x,...)                                \
     188             : extern vnet_feature_registration_t __clib_unused vnet_feat_##x; \
     189             : static vnet_feature_registration_t __clib_unused __clib_unused_vnet_feat_##x
     190             : 
     191             : #define VNET_FEATURE_ARC_ORDER(x,...)                           \
     192             : extern vnet_feature_constraint_registration_t                   \
     193             : __clib_unused vnet_feature_constraint_##x;                      \
     194             : static vnet_feature_constraint_registration_t __clib_unused     \
     195             : __clib_unused_vnet_feature_constraint_##x
     196             : 
     197             : 
     198             : #endif
     199             : 
     200             : void
     201             : vnet_config_update_feature_count (vnet_feature_main_t * fm, u8 arc,
     202             :                                   u32 sw_if_index, int is_add);
     203             : 
     204             : u32 vnet_get_feature_index (u8 arc, const char *s);
     205             : u8 vnet_get_feature_arc_index (const char *s);
     206             : vnet_feature_registration_t *vnet_get_feature_reg (const char *arc_name,
     207             :                                                    const char *node_name);
     208             : 
     209             : 
     210             : int
     211             : vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index,
     212             :                                         u32 sw_if_index, int enable_disable,
     213             :                                         void *feature_config,
     214             :                                         u32 n_feature_config_bytes);
     215             : 
     216             : int
     217             : vnet_feature_enable_disable (const char *arc_name, const char *node_name,
     218             :                              u32 sw_if_index, int enable_disable,
     219             :                              void *feature_config,
     220             :                              u32 n_feature_config_bytes);
     221             : 
     222             : u32
     223             : vnet_feature_modify_end_node (u8 arc_index, u32 sw_if_index, u32 node_index);
     224             : 
     225             : u32 vnet_feature_get_end_node (u8 arc_index, u32 sw_if_index);
     226             : 
     227             : u32 vnet_feature_reset_end_node (u8 arc_index, u32 sw_if_index);
     228             : 
     229             : static_always_inline u32
     230           0 : vnet_get_feature_count (u8 arc, u32 sw_if_index)
     231             : {
     232           0 :   vnet_feature_main_t *fm = &feature_main;
     233           0 :   return (fm->feature_count_by_sw_if_index[arc][sw_if_index]);
     234             : }
     235             : 
     236             : static inline vnet_feature_config_main_t *
     237         352 : vnet_get_feature_arc_config_main (u8 arc_index)
     238             : {
     239         352 :   vnet_feature_main_t *fm = &feature_main;
     240             : 
     241         352 :   if (arc_index == (u8) ~ 0)
     242           0 :     return 0;
     243             : 
     244         352 :   return &fm->feature_config_mains[arc_index];
     245             : }
     246             : 
     247             : static_always_inline vnet_feature_config_main_t *
     248        2239 : vnet_feature_get_config_main (u16 arc)
     249             : {
     250        2239 :   vnet_feature_main_t *fm = &feature_main;
     251        2239 :   return &fm->feature_config_mains[arc];
     252             : }
     253             : 
     254             : static_always_inline int
     255    63229555 : vnet_have_features (u8 arc, u32 sw_if_index)
     256             : {
     257    63229555 :   vnet_feature_main_t *fm = &feature_main;
     258    63229555 :   return clib_bitmap_get (fm->sw_if_index_has_features[arc], sw_if_index);
     259             : }
     260             : 
     261             : static_always_inline u32
     262          11 : vnet_get_feature_config_index (u8 arc, u32 sw_if_index)
     263             : {
     264          11 :   vnet_feature_main_t *fm = &feature_main;
     265          11 :   vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
     266          11 :   return vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     267             : }
     268             : 
     269             : static_always_inline void *
     270    36589535 : vnet_feature_arc_start_with_data (u8 arc, u32 sw_if_index, u32 * next,
     271             :                                   vlib_buffer_t * b, u32 n_data_bytes)
     272             : {
     273    36589535 :   vnet_feature_main_t *fm = &feature_main;
     274             :   vnet_feature_config_main_t *cm;
     275    36589535 :   cm = &fm->feature_config_mains[arc];
     276             : 
     277    36589535 :   if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
     278             :     {
     279    24217557 :       vnet_buffer (b)->feature_arc_index = arc;
     280    24217545 :       b->current_config_index =
     281    24217557 :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     282    24217545 :       return vnet_get_config_data (&cm->config_main, &b->current_config_index,
     283             :                                    next, n_data_bytes);
     284             :     }
     285    12372026 :   return 0;
     286             : }
     287             : 
     288             : static_always_inline void *
     289    11757890 : vnet_feature_arc_start_w_cfg_index (u8 arc,
     290             :                                     u32 sw_if_index,
     291             :                                     u32 * next,
     292             :                                     vlib_buffer_t * b, u32 cfg_index)
     293             : {
     294    11757890 :   vnet_feature_main_t *fm = &feature_main;
     295             :   vnet_feature_config_main_t *cm;
     296    11757890 :   cm = &fm->feature_config_mains[arc];
     297             : 
     298    11757890 :   vnet_buffer (b)->feature_arc_index = arc;
     299    11757890 :   b->current_config_index = cfg_index;
     300             : 
     301    11757890 :   return vnet_get_config_data (&cm->config_main, &b->current_config_index,
     302             :                                next, 0);
     303             : }
     304             : 
     305             : static_always_inline void
     306    36589535 : vnet_feature_arc_start (u8 arc, u32 sw_if_index, u32 * next0,
     307             :                         vlib_buffer_t * b0)
     308             : {
     309    36589535 :   vnet_feature_arc_start_with_data (arc, sw_if_index, next0, b0, 0);
     310    36589545 : }
     311             : 
     312             : static_always_inline void *
     313    40974149 : vnet_feature_next_with_data (u32 * next0, vlib_buffer_t * b0,
     314             :                              u32 n_data_bytes)
     315             : {
     316    40974149 :   vnet_feature_main_t *fm = &feature_main;
     317    40974149 :   u8 arc = vnet_buffer (b0)->feature_arc_index;
     318    40974149 :   vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
     319             : 
     320    40974149 :   return vnet_get_config_data (&cm->config_main,
     321             :                                &b0->current_config_index, next0,
     322             :                                n_data_bytes);
     323             : }
     324             : 
     325             : static_always_inline void
     326    40501860 : vnet_feature_next (u32 * next0, vlib_buffer_t * b0)
     327             : {
     328    40501860 :   vnet_feature_next_with_data (next0, b0, 0);
     329    40501899 : }
     330             : 
     331             : static_always_inline void
     332       12777 : vnet_feature_next_u16 (u16 * next0, vlib_buffer_t * b0)
     333             : {
     334             :   u32 next32;
     335       12777 :   vnet_feature_next_with_data (&next32, b0, 0);
     336       12777 :   *next0 = next32;
     337       12777 : }
     338             : 
     339             : static_always_inline int
     340           0 : vnet_device_input_have_features (u32 sw_if_index)
     341             : {
     342           0 :   vnet_feature_main_t *fm = &feature_main;
     343           0 :   return vnet_have_features (fm->device_input_feature_arc_index, sw_if_index);
     344             : }
     345             : 
     346             : static_always_inline void
     347     2123973 : vnet_feature_start_device_input (u32 sw_if_index, u32 *next0,
     348             :                                  vlib_buffer_t *b0)
     349             : {
     350     2123973 :   vnet_feature_main_t *fm = &feature_main;
     351             :   vnet_feature_config_main_t *cm;
     352     2123973 :   u8 feature_arc_index = fm->device_input_feature_arc_index;
     353     2123973 :   cm = &fm->feature_config_mains[feature_arc_index];
     354             : 
     355     2123973 :   if (PREDICT_FALSE
     356             :       (clib_bitmap_get
     357             :        (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
     358             :     {
     359          21 :       vnet_buffer (b0)->feature_arc_index = feature_arc_index;
     360          21 :       b0->current_config_index =
     361          21 :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     362          21 :       vnet_get_config_data (&cm->config_main, &b0->current_config_index,
     363             :                             next0, /* # bytes of config data */ 0);
     364             :     }
     365     2123973 : }
     366             : 
     367             : #define VNET_FEATURES(...)  (char*[]) { __VA_ARGS__, 0}
     368             : 
     369             : clib_error_t *vnet_feature_arc_init
     370             :   (vlib_main_t * vm,
     371             :    vnet_config_main_t * vcm,
     372             :    char **feature_start_nodes,
     373             :    int num_feature_start_nodes,
     374             :    char *last_in_arc,
     375             :    vnet_feature_registration_t * first_reg,
     376             :    vnet_feature_constraint_registration_t * first_const_set,
     377             :    char ***in_feature_nodes);
     378             : 
     379             : void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
     380             :                                    int verbose);
     381             : 
     382             : typedef void (*vnet_feature_update_cb_t) (u32 sw_if_index,
     383             :                                           u8 arc_index,
     384             :                                           u8 is_enable, void *cb);
     385             : 
     386             : extern void vnet_feature_register (vnet_feature_update_cb_t cb, void *data);
     387             : 
     388             : int
     389             : vnet_feature_is_enabled (const char *arc_name, const char *feature_node_name,
     390             :                          u32 sw_if_index);
     391             : 
     392             : #endif /* included_feature_h */
     393             : 
     394             : /*
     395             :  * fd.io coding-style-patch-verification: ON
     396             :  *
     397             :  * Local Variables:
     398             :  * eval: (c-set-style "gnu")
     399             :  * End:
     400             :  */

Generated by: LCOV version 1.14