1999-01-16 00:49:17 +08:00
/*
1999-03-17 22:29:39 +08:00
* BIRD Internet Routing Daemon - - Filters
1999-01-16 00:49:17 +08:00
*
1999-03-17 22:29:39 +08:00
* ( c ) 1999 Pavel Machek < pavel @ ucw . cz >
1999-01-16 00:49:17 +08:00
*
* Can be freely distributed and used under the terms of the GNU GPL .
*/
# ifndef _BIRD_FILT_H_
# define _BIRD_FILT_H_
# include "lib/resource.h"
1999-04-07 20:11:08 +08:00
# include "lib/ip.h"
2008-10-27 05:45:09 +08:00
# include "nest/route.h"
2000-04-17 19:20:00 +08:00
# include "nest/attrs.h"
1999-01-16 00:49:17 +08:00
2017-10-19 18:39:44 +08:00
/* Filter instruction types */
# define FI__TWOCHAR(a,b) ((a<<8) | b)
# define FI__LIST \
F ( FI_ADD , 0 , ' + ' ) \
F ( FI_SUBTRACT , 0 , ' - ' ) \
F ( FI_MULTIPLY , 0 , ' * ' ) \
F ( FI_DIVIDE , 0 , ' / ' ) \
F ( FI_AND , 0 , ' & ' ) \
F ( FI_OR , 0 , ' | ' ) \
F ( FI_PAIR_CONSTRUCT , ' m ' , ' p ' ) \
F ( FI_EC_CONSTRUCT , ' m ' , ' c ' ) \
F ( FI_LC_CONSTRUCT , ' m ' , ' l ' ) \
2018-02-28 23:57:50 +08:00
F ( FI_PATHMASK_CONSTRUCT , ' m ' , ' P ' ) \
2017-10-19 18:39:44 +08:00
F ( FI_NEQ , ' ! ' , ' = ' ) \
F ( FI_EQ , ' = ' , ' = ' ) \
F ( FI_LT , 0 , ' < ' ) \
F ( FI_LTE , ' < ' , ' = ' ) \
F ( FI_NOT , 0 , ' ! ' ) \
F ( FI_MATCH , 0 , ' ~ ' ) \
F ( FI_NOT_MATCH , ' ! ' , ' ~ ' ) \
F ( FI_DEFINED , ' d ' , ' e ' ) \
2018-03-13 23:51:04 +08:00
F ( FI_TYPE , 0 , ' T ' ) \
F ( FI_IS_V4 , ' I ' , ' i ' ) \
2017-10-19 18:39:44 +08:00
F ( FI_SET , 0 , ' s ' ) \
F ( FI_CONSTANT , 0 , ' c ' ) \
F ( FI_VARIABLE , 0 , ' V ' ) \
F ( FI_CONSTANT_INDIRECT , 0 , ' C ' ) \
F ( FI_PRINT , 0 , ' p ' ) \
F ( FI_CONDITION , 0 , ' ? ' ) \
F ( FI_NOP , 0 , ' 0 ' ) \
F ( FI_PRINT_AND_DIE , ' p ' , ' , ' ) \
F ( FI_RTA_GET , 0 , ' a ' ) \
F ( FI_RTA_SET , ' a ' , ' S ' ) \
F ( FI_EA_GET , ' e ' , ' a ' ) \
F ( FI_EA_SET , ' e ' , ' S ' ) \
F ( FI_PREF_GET , 0 , ' P ' ) \
F ( FI_PREF_SET , ' P ' , ' S ' ) \
F ( FI_LENGTH , 0 , ' L ' ) \
2018-03-13 23:51:04 +08:00
F ( FI_ROA_MAXLEN , ' R ' , ' M ' ) \
F ( FI_ROA_ASN , ' R ' , ' A ' ) \
2018-05-16 17:19:29 +08:00
F ( FI_SADR_SRC , ' n ' , ' s ' ) \
2017-10-19 18:39:44 +08:00
F ( FI_IP , ' c ' , ' p ' ) \
2018-03-13 23:51:04 +08:00
F ( FI_ROUTE_DISTINGUISHER , ' R ' , ' D ' ) \
2017-10-19 18:39:44 +08:00
F ( FI_AS_PATH_FIRST , ' a ' , ' f ' ) \
F ( FI_AS_PATH_LAST , ' a ' , ' l ' ) \
F ( FI_AS_PATH_LAST_NAG , ' a ' , ' L ' ) \
F ( FI_RETURN , 0 , ' r ' ) \
F ( FI_CALL , ' c ' , ' a ' ) \
F ( FI_CLEAR_LOCAL_VARS , ' c ' , ' V ' ) \
F ( FI_SWITCH , ' S ' , ' W ' ) \
F ( FI_IP_MASK , ' i ' , ' M ' ) \
F ( FI_EMPTY , 0 , ' E ' ) \
F ( FI_PATH_PREPEND , ' A ' , ' p ' ) \
F ( FI_CLIST_ADD_DEL , ' C ' , ' a ' ) \
2018-03-13 23:51:04 +08:00
F ( FI_ROA_CHECK , ' R ' , ' C ' ) \
F ( FI_FORMAT , 0 , ' F ' ) \
F ( FI_ASSERT , ' a ' , ' s ' )
2017-10-19 18:39:44 +08:00
enum f_instruction_code {
# define F(c,a,b) \
2018-04-30 18:39:32 +08:00
c ,
2017-10-19 18:39:44 +08:00
FI__LIST
# undef F
2018-04-30 18:49:22 +08:00
FI__MAX ,
2017-10-19 18:39:44 +08:00
} PACKED ;
1999-03-09 04:30:06 +08:00
struct f_inst { /* Instruction */
struct f_inst * next ; /* Structure is 16 bytes, anyway */
2017-10-19 18:39:44 +08:00
enum f_instruction_code fi_code ;
2016-11-09 23:36:34 +08:00
u16 aux ; /* Extension to instruction code, T_*, EA_*, EAF_* */
1999-04-10 17:45:08 +08:00
union {
2017-05-23 23:22:53 +08:00
uint i ;
1999-04-10 17:45:08 +08:00
void * p ;
2016-11-09 23:36:34 +08:00
} a1 ; /* The first argument */
1999-04-10 17:45:08 +08:00
union {
2017-05-23 23:22:53 +08:00
uint i ;
1999-04-10 17:45:08 +08:00
void * p ;
2016-11-09 23:36:34 +08:00
} a2 ; /* The second argument */
2000-05-17 02:50:51 +08:00
int lineno ;
1999-01-16 00:49:17 +08:00
} ;
1999-04-10 17:45:08 +08:00
# define arg1 a1.p
# define arg2 a2.p
2012-03-19 00:32:30 +08:00
/* Not enough fields in f_inst for three args used by roa_check() */
struct f_inst_roa_check {
struct f_inst i ;
2016-01-20 22:38:37 +08:00
struct rtable_config * rtc ;
2012-03-19 00:32:30 +08:00
} ;
2016-10-01 18:50:29 +08:00
struct f_inst3 {
struct f_inst i ;
union {
int i ;
void * p ;
} a3 ;
} ;
# define INST3(x) (((struct f_inst3 *) x)->a3)
2000-05-17 06:37:53 +08:00
struct f_prefix {
2015-12-24 22:52:03 +08:00
net_addr net ;
2015-12-16 17:25:12 +08:00
u8 lo , hi ;
1999-04-07 20:11:08 +08:00
} ;
1999-03-09 04:30:06 +08:00
struct f_val {
2016-11-09 23:36:34 +08:00
int type ; /* T_* */
1999-03-09 04:30:06 +08:00
union {
2013-11-24 07:17:02 +08:00
uint i ;
2011-08-13 03:03:43 +08:00
u64 ec ;
2016-10-01 18:50:29 +08:00
lcomm lc ;
2015-12-16 17:25:12 +08:00
ip_addr ip ;
const net_addr * net ;
1999-04-07 20:11:08 +08:00
char * s ;
1999-04-13 03:58:18 +08:00
struct f_tree * t ;
2009-03-31 18:55:57 +08:00
struct f_trie * ti ;
2000-04-12 21:31:39 +08:00
struct adata * ad ;
struct f_path_mask * path_mask ;
1999-03-09 04:30:06 +08:00
} val ;
} ;
2017-10-19 18:39:44 +08:00
struct f_dynamic_attr {
int type ;
int f_type ;
int ea_code ;
} ;
struct f_static_attr {
int f_type ;
int sa_code ;
int readonly ;
} ;
1999-03-17 22:29:39 +08:00
struct filter {
char * name ;
struct f_inst * root ;
} ;
2017-10-19 18:39:44 +08:00
struct f_inst * f_new_inst ( enum f_instruction_code fi_code ) ;
struct f_inst * f_new_inst_da ( enum f_instruction_code fi_code , struct f_dynamic_attr da ) ;
struct f_inst * f_new_inst_sa ( enum f_instruction_code fi_code , struct f_static_attr sa ) ;
static inline struct f_dynamic_attr f_new_dynamic_attr ( int type , int f_type , int 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_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 } ; }
1999-04-13 03:58:18 +08:00
struct f_tree * f_new_tree ( void ) ;
2017-10-19 18:39:44 +08:00
struct f_inst * f_generate_complex ( int operation , int operation_aux , struct f_dynamic_attr da , struct f_inst * argument ) ;
2016-01-20 22:38:37 +08:00
struct f_inst * f_generate_roa_check ( struct rtable_config * table , struct f_inst * prefix , struct f_inst * asn ) ;
2012-03-19 00:32:30 +08:00
1999-04-13 03:58:18 +08:00
struct f_tree * build_tree ( struct f_tree * ) ;
struct f_tree * find_tree ( struct f_tree * t , struct f_val val ) ;
2000-02-01 01:44:22 +08:00
int same_tree ( struct f_tree * t1 , struct f_tree * t2 ) ;
2013-10-06 02:12:28 +08:00
void tree_format ( struct f_tree * t , buffer * buf ) ;
1999-03-03 03:49:28 +08:00
2015-02-21 21:05:20 +08:00
struct f_trie * f_new_trie ( linpool * lp , uint node_size ) ;
2015-12-22 00:17:21 +08:00
void * trie_add_prefix ( struct f_trie * t , const net_addr * n , uint l , uint h ) ;
2015-12-16 17:25:12 +08:00
int trie_match_net ( struct f_trie * t , const net_addr * n ) ;
2009-03-31 18:55:57 +08:00
int trie_same ( struct f_trie * t1 , struct f_trie * t2 ) ;
2013-10-06 02:12:28 +08:00
void trie_format ( struct f_trie * t , buffer * buf ) ;
2009-03-31 18:55:57 +08:00
1999-08-04 03:31:11 +08:00
struct ea_list ;
struct rte ;
2000-03-29 17:02:00 +08:00
int f_run ( struct filter * filter , struct rte * * rte , struct ea_list * * tmp_attrs , struct linpool * tmp_pool , int flags ) ;
2015-07-20 17:12:02 +08:00
struct f_val f_eval_rte ( struct f_inst * expr , struct rte * * rte , struct linpool * tmp_pool ) ;
2013-07-25 19:15:32 +08:00
struct f_val f_eval ( struct f_inst * expr , struct linpool * tmp_pool ) ;
2013-11-24 07:17:02 +08:00
uint f_eval_int ( struct f_inst * expr ) ;
2009-08-28 01:01:04 +08:00
1999-04-06 04:10:31 +08:00
char * filter_name ( struct filter * filter ) ;
2000-01-17 01:49:32 +08:00
int filter_same ( struct filter * new , struct filter * old ) ;
1999-03-17 22:29:39 +08:00
2000-02-01 01:44:22 +08:00
int i_same ( struct f_inst * f1 , struct f_inst * f2 ) ;
1999-04-13 03:58:18 +08:00
int val_compare ( struct f_val v1 , struct f_val v2 ) ;
2013-10-02 20:41:37 +08:00
int val_same ( struct f_val v1 , struct f_val v2 ) ;
1999-04-07 20:11:08 +08:00
2013-10-06 02:12:28 +08:00
void val_format ( struct f_val v , buffer * buf ) ;
2013-07-25 19:15:32 +08:00
1999-04-07 20:11:08 +08:00
# define F_NOP 0
1999-10-12 14:27:42 +08:00
# define F_NONL 1
# define F_ACCEPT 2 /* Need to preserve ordering: accepts < rejects! */
1999-12-16 20:18:19 +08:00
# define F_REJECT 3
# define F_ERROR 4
# define F_QUITBIRD 5
1999-01-16 02:13:55 +08:00
1999-04-06 04:10:31 +08:00
# define FILTER_ACCEPT NULL
# define FILTER_REJECT ((void *) 1)
2018-01-16 11:14:49 +08:00
# define FILTER_UNDEF ((void *) 2) /* Used in BGP */
1999-04-06 04:10:31 +08:00
1999-03-30 04:21:28 +08:00
/* Type numbers must be in 0..0xff range */
# define T_MASK 0xff
/* Internal types */
1999-11-18 22:01:36 +08:00
/* Do not use type of zero, that way we'll see errors easier. */
# define T_VOID 1
1999-03-30 04:21:28 +08:00
/* User visible types, which fit in int */
# define T_INT 0x10
# define T_BOOL 0x11
2000-04-26 16:03:50 +08:00
# define T_PAIR 0x12 /* Notice that pair is stored as integer: first << 16 | second */
2010-03-30 01:29:03 +08:00
# define T_QUAD 0x13
1999-11-10 20:44:07 +08:00
2000-02-25 19:15:26 +08:00
/* Put enumerational types in 0x30..0x3f range */
1999-11-10 20:44:07 +08:00
# define T_ENUM_LO 0x30
2000-02-25 19:15:26 +08:00
# define T_ENUM_HI 0x3f
1999-11-10 20:44:07 +08:00
1999-11-10 21:44:29 +08:00
# define T_ENUM_RTS 0x30
2000-04-26 15:47:47 +08:00
# define T_ENUM_BGP_ORIGIN 0x31
2000-05-30 18:42:39 +08:00
# define T_ENUM_SCOPE 0x32
# define T_ENUM_RTC 0x33
# define T_ENUM_RTD 0x34
2016-01-20 22:06:19 +08:00
# define T_ENUM_ROA 0x35
2017-03-13 20:50:32 +08:00
# define T_ENUM_NETTYPE 0x36
2017-12-08 04:54:47 +08:00
# define T_ENUM_RA_PREFERENCE 0x37
2017-03-13 20:50:32 +08:00
2000-04-26 15:47:47 +08:00
/* new enums go here */
2000-04-17 20:40:38 +08:00
# define T_ENUM_EMPTY 0x3f /* Special hack for atomic_aggr */
1999-11-10 21:44:29 +08:00
1999-11-10 20:44:07 +08:00
# define T_ENUM T_ENUM_LO ... T_ENUM_HI
1999-03-30 04:21:28 +08:00
/* Bigger ones */
# define T_IP 0x20
2015-12-16 17:25:12 +08:00
# define T_NET 0x21
1999-03-30 04:21:28 +08:00
# define T_STRING 0x22
2000-04-12 21:07:53 +08:00
# define T_PATH_MASK 0x23 /* mask for BGP path */
2000-04-12 21:31:39 +08:00
# define T_PATH 0x24 /* BGP path */
# define T_CLIST 0x25 /* Community list */
2016-10-01 18:50:29 +08:00
# define T_EC 0x26 /* Extended community value, u64 */
# define T_ECLIST 0x27 /* Extended community list */
# define T_LC 0x28 /* Large community value, lcomm */
# define T_LCLIST 0x29 /* Large community list */
2017-03-13 20:50:32 +08:00
# define T_RD 0x2a /* Route distinguisher for VPN addresses */
1999-03-30 04:21:28 +08:00
2000-02-25 19:15:26 +08:00
# define T_RETURN 0x40
1999-03-30 04:21:28 +08:00
# define T_SET 0x80
2009-03-31 18:55:57 +08:00
# define T_PREFIX_SET 0x81
1999-03-17 18:19:07 +08:00
2013-09-27 04:08:21 +08:00
2015-12-16 17:25:12 +08:00
# define SA_FROM 1
# define SA_GW 2
# define SA_NET 3
# define SA_PROTO 4
# define SA_SOURCE 5
# define SA_SCOPE 6
2017-02-20 09:26:45 +08:00
# define SA_DEST 7
# define SA_IFNAME 8
# define SA_IFINDEX 9
2013-09-27 04:08:21 +08:00
1999-04-13 03:58:18 +08:00
struct f_tree {
struct f_tree * left , * right ;
struct f_val from , to ;
void * data ;
} ;
2009-03-31 18:55:57 +08:00
struct f_trie_node
{
ip_addr addr , mask , accept ;
2016-11-09 02:27:58 +08:00
uint plen ;
2009-03-31 18:55:57 +08:00
struct f_trie_node * c [ 2 ] ;
} ;
struct f_trie
{
2010-07-27 23:17:11 +08:00
linpool * lp ;
2009-03-31 18:55:57 +08:00
int zero ;
2015-02-21 21:05:20 +08:00
uint node_size ;
struct f_trie_node root [ 0 ] ; /* Root trie node follows */
2009-03-31 18:55:57 +08:00
} ;
1999-10-12 14:27:42 +08:00
# define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
2000-03-30 16:50:30 +08:00
# define FF_FORCE_TMPATTR 1 /* Force all attributes to be temporary */
2018-01-16 23:20:01 +08:00
# define FF_SILENT 2 /* Silent filter execution */
2000-03-29 17:02:00 +08:00
2016-11-09 23:36:34 +08:00
/* Bird Tests */
struct f_bt_test_suite {
node n ; /* Node in config->tests */
struct f_inst * fn ; /* Root of function */
const char * fn_name ; /* Name of test */
const char * dsc ; /* Description */
} ;
/* Hook for call bt_assert() function in configuration */
extern void ( * bt_assert_hook ) ( int result , struct f_inst * assert ) ;
1999-01-16 00:49:17 +08:00
# endif