]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Faster filters: documentation on what is happening there
authorMaria Matejka <mq@ucw.cz>
Wed, 6 Mar 2019 14:01:10 +0000 (15:01 +0100)
committerMaria Matejka <mq@ucw.cz>
Wed, 6 Mar 2019 14:01:39 +0000 (15:01 +0100)
filter/f-inst.c
filter/f-inst.h

index 8505534ade4a1a23fda96e0a7bf1bcc0f0d9e39d..6f031782b0620d860b358bceba54ed20a1c4b547 100644 (file)
@@ -7,6 +7,43 @@
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  *
+ *     Filter instructions. You shall define your instruction only here
+ *     and nowhere else.
+ *
+ *     Beware. This file is interpreted by M4 macros. These macros
+ *     may be more stupid than you could imagine. If something strange
+ *     happens after changing this file, compare the results before and
+ *     after your change (see the Makefile to find out where the results are)
+ *     and see what really happened.
+ *
+ *     This file is not directly a C source code -> it is a generator input
+ *     for several C sources; every instruction block gets expanded into many
+ *     different places.
+ *
+ *     What is the syntax here?
+ *     m4_dnl  INST(FI_NOP, in, out) {                 enum value, input args, output args
+ *     m4_dnl    ARG(num, type);                       argument, its id (in data fields) and type
+ *     m4_dnl    ARG_ANY(num);                         argument with no type check
+ *     m4_dnl    LINE(num, unused);                    this argument has to be converted to its own f_line
+ *     m4_dnl    ECS;                                  extended community subtype
+ *     m4_dnl    COUNT(unused);                        simply a uint
+ *     m4_dnl    SYMBOL(unused);                       symbol handed from config
+ *     m4_dnl    FRET(unused);                         filter return value
+ *     m4_dnl    STATIC_ATTR;                          static attribute definition
+ *     m4_dnl    DYNAMIC_ATTR;                         dynamic attribute definition
+ *     m4_dnl    RTC;                                  route table config
+ *     m4_dnl    TREE;                                 a tree
+ *     m4_dnl    ACCESS_RTE;                           this instruction needs route
+ *     m4_dnl    ACCESS_EATTRS;                        this instruction needs extended attributes
+ *     m4_dnl    RESULT(type, union-field, value);     putting this on value stack
+ *     m4_dnl    RESULT_OK;                            legalize what already is on the value stack
+ *     m4_dnl  }
+ *
+ *     Other code is just copied into the interpreter part.
+ *
+ *     If you want to write something really special, see FI_CALL
+ *     or FI_CONSTANT or whatever else to see how to use the FID_*
+ *     macros.
  */
 
 /* Binary operators */
index 4b42c57c0439e903303b2ebcdc155eb11f2c05e9..1e2d63a251d823a2002cb13ba2228b5a21bcbd6e 100644 (file)
@@ -5,6 +5,41 @@
  *     (c) 2018--2019 Maria Matejka <mq@jmq.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
+ *
+ *     Filter interpreter data structures and internal API.
+ *     The filter code goes through several phases:
+ *
+ *     1  Parsing
+ *     Flex- and Bison-generated parser decodes the human-readable data into
+ *     a struct f_inst tree. This is an infix tree that was interpreted by
+ *     depth-first search execution in previous versions of the interpreter.
+ *     All instructions have their constructor: f_new_inst(FI_code, ...)
+ *     translates into f_new_inst_FI_code(...) and the types are checked in
+ *     compile time.
+ *
+ *     2  Postfixify before interpreting
+ *     The infix tree is always interpreted in the same order. Therefore we
+ *     sort the instructions one after another into struct f_line. Results
+ *     and arguments of these instructions are implicitly put on a value
+ *     stack; e.g. the + operation just takes two arguments from the value
+ *     stack and puts the result on there.
+ *
+ *     3  Interpret
+ *     The given line is put on a custom execution stack. If needed (FI_CALL,
+ *     FI_SWITCH, FI_AND, FI_OR, FI_CONDITION, ...), another line is put on top
+ *     of the stack; when that line finishes, the execution continues on the
+ *     older lines on the stack where it stopped before.
+ *
+ *     4  Same
+ *     On config reload, the filters have to be compared whether channel
+ *     reload is needed or not. The comparison is done by comparing the
+ *     struct f_line's recursively.
+ *
+ *     The main purpose of this rework was to improve filter performance
+ *     by making the interpreter non-recursive.
+ *
+ *     The other outcome is concentration of instruction definitions to
+ *     one place -- filter/f-inst.c
  */
 
 #ifndef _BIRD_F_INST_H_