2019-01-21 08:17:54 +00:00
/*
* BIRD Internet Routing Daemon - - Filter instructions
*
2019-02-07 20:25:38 +00:00
* ( c ) 1999 Pavel Machek < pavel @ ucw . cz >
2019-01-21 08:17:54 +00:00
* ( c ) 2018 - - 2019 Maria Matejka < mq @ jmq . cz >
*
* Can be freely distributed and used under the terms of the GNU GPL .
2019-03-06 14:01:10 +00:00
*
* Filter interpreter data structures and internal API .
2019-07-15 11:19:01 +00:00
* See filter / f - inst . c for documentation .
2019-01-21 08:17:54 +00:00
*/
2019-02-07 20:25:38 +00:00
# ifndef _BIRD_F_INST_H_
# define _BIRD_F_INST_H_
2019-02-08 12:38:12 +00:00
# include "nest/bird.h"
# include "conf/conf.h"
2019-02-07 20:25:38 +00:00
# include "filter/filter.h"
2019-02-08 12:38:12 +00:00
# include "filter/data.h"
2021-02-07 18:21:42 +00:00
# include "lib/buffer.h"
2019-12-09 03:23:01 +00:00
# include "lib/flowspec.h"
2023-08-24 02:30:42 +00:00
# include "lib/string.h"
2019-02-07 20:25:38 +00:00
2019-02-15 22:59:44 +00:00
/* Flags for instructions */
enum f_instruction_flags {
2022-03-06 01:18:01 +00:00
FIF_RECURSIVE = 1 , /* FI_CALL: function is directly recursive */
2019-02-15 22:59:44 +00:00
} PACKED ;
2019-02-08 12:38:12 +00:00
/* Include generated filter instruction declarations */
2019-02-11 15:44:14 +00:00
# include "filter/inst-gen.h"
2019-02-07 20:25:38 +00:00
2019-02-08 12:38:12 +00:00
# define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
2019-01-21 08:17:54 +00:00
/* Convert the instruction back to the enum name */
2019-11-05 14:13:57 +00:00
const char * f_instruction_name_ ( enum f_instruction_code fi ) ;
static inline const char * f_instruction_name ( enum f_instruction_code fi )
{ return f_instruction_name_ ( fi ) + 3 ; }
2019-01-21 08:17:54 +00:00
2023-07-25 15:43:52 +00:00
int f_const_promotion_ ( struct f_inst * arg , enum f_type want , int update ) ;
static inline int f_const_promotion ( struct f_inst * arg , enum f_type want )
{ return f_const_promotion_ ( arg , want , 1 ) ; }
static inline int f_try_const_promotion ( struct f_inst * arg , enum f_type want )
{ return f_const_promotion_ ( arg , want , 0 ) ; }
2022-03-03 02:38:12 +00:00
struct f_arg {
struct symbol * arg ;
struct f_arg * next ;
} ;
2019-02-07 20:25:38 +00:00
/* Filter structures for execution */
/* Line of instructions to be unconditionally executed one after another */
struct f_line {
uint len ; /* Line length */
2019-02-26 15:44:24 +00:00
u8 args ; /* Function: Args required */
2019-05-21 16:33:37 +00:00
u8 vars ;
2022-03-09 01:32:29 +00:00
u8 results ; /* Results left on stack: cmd -> 0, term -> 1 */
2023-06-15 11:25:40 +00:00
u8 return_type ; /* Type which the function returns */
2022-03-03 02:38:12 +00:00
struct f_arg * arg_list ;
2019-02-07 20:25:38 +00:00
struct f_line_item items [ 0 ] ; /* The items themselves */
} ;
2019-01-21 08:17:54 +00:00
2019-02-07 20:25:38 +00:00
/* Convert the f_inst infix tree to the f_line structures */
2022-03-09 01:32:29 +00:00
struct f_line * f_linearize_concat ( const struct f_inst * const inst [ ] , uint count , uint results ) ;
static inline struct f_line * f_linearize ( const struct f_inst * root , uint results )
{ return f_linearize_concat ( & root , 1 , results ) ; }
2019-02-07 20:25:38 +00:00
2019-02-15 22:59:44 +00:00
void f_dump_line ( const struct f_line * , uint indent ) ;
2021-02-07 18:21:42 +00:00
/* Recursive iteration over filter instructions */
struct filter_iterator {
BUFFER_ ( const struct f_line * ) lines ;
} ;
void f_add_lines ( const struct f_line_item * what , struct filter_iterator * fit ) ;
# define FILTER_ITERATE_INIT(fit, filter, pool) \
( { \
BUFFER_INIT ( ( fit ) - > lines , ( pool ) , 32 ) ; \
BUFFER_PUSH ( ( fit ) - > lines ) = ( filter ) - > root ; \
} )
# define FILTER_ITERATE(fit, fi) ({ \
const struct f_line * fl_ ; \
while ( ! BUFFER_EMPTY ( ( fit ) - > lines ) ) \
{ \
BUFFER_POP ( ( fit ) - > lines ) ; \
fl_ = ( fit ) - > lines . data [ ( fit ) - > lines . used ] ; \
for ( uint i_ = 0 ; i_ < fl_ - > len ; i_ + + ) \
{ \
const struct f_line_item * fi = & fl_ - > items [ i_ ] ; \
f_add_lines ( fi , ( fit ) ) ;
# define FILTER_ITERATE_END } } })
# define FILTER_ITERATE_CLEANUP(fit) \
( { \
mb_free ( ( fit ) - > lines . data ) ; \
memset ( ( fit ) , 0 , sizeof ( struct filter_iterator ) ) ; \
} )
2019-06-28 09:08:48 +00:00
struct filter * f_new_where ( struct f_inst * ) ;
2023-09-12 16:44:20 +00:00
struct f_inst * f_dispatch_method ( struct symbol * sym , struct f_inst * obj , struct f_inst * args , int skip ) ;
2023-07-03 15:00:58 +00:00
struct f_inst * f_dispatch_method_x ( const char * name , enum f_type t , struct f_inst * obj , struct f_inst * args ) ;
2023-06-18 20:50:45 +00:00
struct f_inst * f_for_cycle ( struct symbol * var , struct f_inst * term , struct f_inst * block ) ;
2023-06-19 15:24:30 +00:00
struct f_inst * f_print ( struct f_inst * vars , int flush , enum filter_return fret ) ;
2023-06-18 20:50:45 +00:00
2019-07-02 22:00:11 +00:00
static inline struct f_dynamic_attr f_new_dynamic_attr ( u8 type , enum f_type f_type , uint code ) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return ( struct f_dynamic_attr ) { . type = type , . f_type = f_type , . ea_code = code } ; } /* f_type currently unused; will be handy for static type checking */
static inline struct f_dynamic_attr f_new_dynamic_attr_bit ( u8 bit , enum f_type f_type , uint code ) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return ( struct f_dynamic_attr ) { . type = EAF_TYPE_BITFIELD , . bit = bit , . f_type = f_type , . ea_code = code } ; } /* f_type currently unused; will be handy for static type checking */
2019-02-07 20:25:38 +00:00
static inline struct f_static_attr f_new_static_attr ( int f_type , int code , int readonly )
{ return ( struct f_static_attr ) { . f_type = f_type , . sa_code = code , . readonly = readonly } ; }
2023-09-19 09:11:24 +00:00
static inline int f_type_attr ( int f_type ) {
switch ( f_type ) {
case T_INT : return EAF_TYPE_INT ;
case T_IP : return EAF_TYPE_IP_ADDRESS ;
case T_QUAD : return EAF_TYPE_ROUTER_ID ;
case T_PATH : return EAF_TYPE_AS_PATH ;
case T_CLIST : return EAF_TYPE_INT_SET ;
case T_ECLIST : return EAF_TYPE_EC_SET ;
case T_LCLIST : return EAF_TYPE_LC_SET ;
case T_BYTESTRING : return EAF_TYPE_OPAQUE ;
default :
cf_error ( " Custom route attribute of unsupported type " ) ;
}
}
2019-02-07 20:25:38 +00:00
/* Hook for call bt_assert() function in configuration */
extern void ( * bt_assert_hook ) ( int result , const struct f_line_item * assert ) ;
/* Bird Tests */
struct f_bt_test_suite {
node n ; /* Node in config->tests */
2019-02-15 12:53:17 +00:00
const struct f_line * fn ; /* Root of function */
const struct f_line * cmp ; /* Compare to this function */
2019-02-07 20:25:38 +00:00
const char * fn_name ; /* Name of test */
const char * dsc ; /* Description */
2019-02-13 11:25:30 +00:00
int result ; /* Desired result */
2019-01-21 08:17:54 +00:00
} ;
2019-02-07 20:25:38 +00:00
# endif