LCOV - code coverage report
Current view: top level - vnet/feature - feature.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 56 63 88.9 %
Date: 2023-07-05 22:20:52 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        2180 : vnet_feature_get_config_main (u16 arc)
     249             : {
     250        2180 :   vnet_feature_main_t *fm = &feature_main;
     251        2180 :   return &fm->feature_config_mains[arc];
     252             : }
     253             : 
     254             : static_always_inline int
     255    53484523 : vnet_have_features (u8 arc, u32 sw_if_index)
     256             : {
     257    53484523 :   vnet_feature_main_t *fm = &feature_main;
     258    53484523 :   return clib_bitmap_get (fm->sw_if_index_has_features[arc], sw_if_index);
     259             : }
     260             : 
     261             : static_always_inline u32
     262           9 : vnet_get_feature_config_index (u8 arc, u32 sw_if_index)
     263             : {
     264           9 :   vnet_feature_main_t *fm = &feature_main;
     265           9 :   vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
     266           9 :   return vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     267             : }
     268             : 
     269             : static_always_inline void *
     270    30113735 : 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    30113735 :   vnet_feature_main_t *fm = &feature_main;
     274             :   vnet_feature_config_main_t *cm;
     275    30113735 :   cm = &fm->feature_config_mains[arc];
     276             : 
     277    30113735 :   if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
     278             :     {
     279    21380351 :       vnet_buffer (b)->feature_arc_index = arc;
     280    21380330 :       b->current_config_index =
     281    21380351 :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     282    21380330 :       return vnet_get_config_data (&cm->config_main, &b->current_config_index,
     283             :                                    next, n_data_bytes);
     284             :     }
     285     8733425 :   return 0;
     286             : }
     287             : 
     288             : static_always_inline void *
     289     3383100 : 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     3383100 :   vnet_feature_main_t *fm = &feature_main;
     295             :   vnet_feature_config_main_t *cm;
     296     3383100 :   cm = &fm->feature_config_mains[arc];
     297             : 
     298     3383100 :   vnet_buffer (b)->feature_arc_index = arc;
     299     3383100 :   b->current_config_index = cfg_index;
     300             : 
     301     3383100 :   return vnet_get_config_data (&cm->config_main, &b->current_config_index,
     302             :                                next, 0);
     303             : }
     304             : 
     305             : static_always_inline void
     306    30113725 : vnet_feature_arc_start (u8 arc, u32 sw_if_index, u32 * next0,
     307             :                         vlib_buffer_t * b0)
     308             : {
     309    30113725 :   vnet_feature_arc_start_with_data (arc, sw_if_index, next0, b0, 0);
     310    30113735 : }
     311             : 
     312             : static_always_inline void *
     313    30224176 : vnet_feature_next_with_data (u32 * next0, vlib_buffer_t * b0,
     314             :                              u32 n_data_bytes)
     315             : {
     316    30224176 :   vnet_feature_main_t *fm = &feature_main;
     317    30224176 :   u8 arc = vnet_buffer (b0)->feature_arc_index;
     318    30224176 :   vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
     319             : 
     320    30224176 :   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    29798443 : vnet_feature_next (u32 * next0, vlib_buffer_t * b0)
     327             : {
     328    29798443 :   vnet_feature_next_with_data (next0, b0, 0);
     329    29798474 : }
     330             : 
     331             : static_always_inline void
     332       12360 : vnet_feature_next_u16 (u16 * next0, vlib_buffer_t * b0)
     333             : {
     334             :   u32 next32;
     335       12360 :   vnet_feature_next_with_data (&next32, b0, 0);
     336       12360 :   *next0 = next32;
     337       12360 : }
     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     1873551 : vnet_feature_start_device_input_x1 (u32 sw_if_index, u32 * next0,
     348             :                                     vlib_buffer_t * b0)
     349             : {
     350     1873551 :   vnet_feature_main_t *fm = &feature_main;
     351             :   vnet_feature_config_main_t *cm;
     352     1873551 :   u8 feature_arc_index = fm->device_input_feature_arc_index;
     353     1873551 :   cm = &fm->feature_config_mains[feature_arc_index];
     354             : 
     355     1873551 :   if (PREDICT_FALSE
     356             :       (clib_bitmap_get
     357             :        (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
     358             :     {
     359             :       /*
     360             :        * Save next0 so that the last feature in the chain
     361             :        * can skip ethernet-input if indicated...
     362             :        */
     363             :       u16 adv;
     364             : 
     365          21 :       adv = device_input_next_node_advance[*next0];
     366          21 :       vlib_buffer_advance (b0, -adv);
     367             : 
     368          21 :       vnet_buffer (b0)->feature_arc_index = feature_arc_index;
     369          21 :       b0->current_config_index =
     370          21 :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     371          21 :       vnet_get_config_data (&cm->config_main, &b0->current_config_index,
     372             :                             next0, /* # bytes of config data */ 0);
     373             :     }
     374     1873551 : }
     375             : 
     376             : static_always_inline void
     377             : vnet_feature_start_device_input_x2 (u32 sw_if_index,
     378             :                                     u32 * next0,
     379             :                                     u32 * next1,
     380             :                                     vlib_buffer_t * b0, vlib_buffer_t * b1)
     381             : {
     382             :   vnet_feature_main_t *fm = &feature_main;
     383             :   vnet_feature_config_main_t *cm;
     384             :   u8 feature_arc_index = fm->device_input_feature_arc_index;
     385             :   cm = &fm->feature_config_mains[feature_arc_index];
     386             : 
     387             :   if (PREDICT_FALSE
     388             :       (clib_bitmap_get
     389             :        (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
     390             :     {
     391             :       /*
     392             :        * Save next0 so that the last feature in the chain
     393             :        * can skip ethernet-input if indicated...
     394             :        */
     395             :       u16 adv;
     396             : 
     397             :       adv = device_input_next_node_advance[*next0];
     398             :       vlib_buffer_advance (b0, -adv);
     399             : 
     400             :       adv = device_input_next_node_advance[*next1];
     401             :       vlib_buffer_advance (b1, -adv);
     402             : 
     403             :       vnet_buffer (b0)->feature_arc_index = feature_arc_index;
     404             :       vnet_buffer (b1)->feature_arc_index = feature_arc_index;
     405             :       b0->current_config_index =
     406             :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     407             :       b1->current_config_index = b0->current_config_index;
     408             :       vnet_get_config_data (&cm->config_main, &b0->current_config_index,
     409             :                             next0, /* # bytes of config data */ 0);
     410             :       vnet_get_config_data (&cm->config_main, &b1->current_config_index,
     411             :                             next1, /* # bytes of config data */ 0);
     412             :     }
     413             : }
     414             : 
     415             : static_always_inline void
     416             : vnet_feature_start_device_input_x4 (u32 sw_if_index,
     417             :                                     u32 * next0,
     418             :                                     u32 * next1,
     419             :                                     u32 * next2,
     420             :                                     u32 * next3,
     421             :                                     vlib_buffer_t * b0,
     422             :                                     vlib_buffer_t * b1,
     423             :                                     vlib_buffer_t * b2, vlib_buffer_t * b3)
     424             : {
     425             :   vnet_feature_main_t *fm = &feature_main;
     426             :   vnet_feature_config_main_t *cm;
     427             :   u8 feature_arc_index = fm->device_input_feature_arc_index;
     428             :   cm = &fm->feature_config_mains[feature_arc_index];
     429             : 
     430             :   if (PREDICT_FALSE
     431             :       (clib_bitmap_get
     432             :        (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
     433             :     {
     434             :       /*
     435             :        * Save next0 so that the last feature in the chain
     436             :        * can skip ethernet-input if indicated...
     437             :        */
     438             :       u16 adv;
     439             : 
     440             :       adv = device_input_next_node_advance[*next0];
     441             :       vlib_buffer_advance (b0, -adv);
     442             : 
     443             :       adv = device_input_next_node_advance[*next1];
     444             :       vlib_buffer_advance (b1, -adv);
     445             : 
     446             :       adv = device_input_next_node_advance[*next2];
     447             :       vlib_buffer_advance (b2, -adv);
     448             : 
     449             :       adv = device_input_next_node_advance[*next3];
     450             :       vlib_buffer_advance (b3, -adv);
     451             : 
     452             :       vnet_buffer (b0)->feature_arc_index = feature_arc_index;
     453             :       vnet_buffer (b1)->feature_arc_index = feature_arc_index;
     454             :       vnet_buffer (b2)->feature_arc_index = feature_arc_index;
     455             :       vnet_buffer (b3)->feature_arc_index = feature_arc_index;
     456             : 
     457             :       b0->current_config_index =
     458             :         vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
     459             :       b1->current_config_index = b0->current_config_index;
     460             :       b2->current_config_index = b0->current_config_index;
     461             :       b3->current_config_index = b0->current_config_index;
     462             : 
     463             :       vnet_get_config_data (&cm->config_main, &b0->current_config_index,
     464             :                             next0, /* # bytes of config data */ 0);
     465             :       vnet_get_config_data (&cm->config_main, &b1->current_config_index,
     466             :                             next1, /* # bytes of config data */ 0);
     467             :       vnet_get_config_data (&cm->config_main, &b2->current_config_index,
     468             :                             next2, /* # bytes of config data */ 0);
     469             :       vnet_get_config_data (&cm->config_main, &b3->current_config_index,
     470             :                             next3, /* # bytes of config data */ 0);
     471             :     }
     472             : }
     473             : 
     474             : #define VNET_FEATURES(...)  (char*[]) { __VA_ARGS__, 0}
     475             : 
     476             : clib_error_t *vnet_feature_arc_init
     477             :   (vlib_main_t * vm,
     478             :    vnet_config_main_t * vcm,
     479             :    char **feature_start_nodes,
     480             :    int num_feature_start_nodes,
     481             :    char *last_in_arc,
     482             :    vnet_feature_registration_t * first_reg,
     483             :    vnet_feature_constraint_registration_t * first_const_set,
     484             :    char ***in_feature_nodes);
     485             : 
     486             : void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
     487             :                                    int verbose);
     488             : 
     489             : typedef void (*vnet_feature_update_cb_t) (u32 sw_if_index,
     490             :                                           u8 arc_index,
     491             :                                           u8 is_enable, void *cb);
     492             : 
     493             : extern void vnet_feature_register (vnet_feature_update_cb_t cb, void *data);
     494             : 
     495             : int
     496             : vnet_feature_is_enabled (const char *arc_name, const char *feature_node_name,
     497             :                          u32 sw_if_index);
     498             : 
     499             : #endif /* included_feature_h */
     500             : 
     501             : /*
     502             :  * fd.io coding-style-patch-verification: ON
     503             :  *
     504             :  * Local Variables:
     505             :  * eval: (c-set-style "gnu")
     506             :  * End:
     507             :  */

Generated by: LCOV version 1.14