]>
Commit | Line | Data |
---|---|---|
9b46748d MM |
1 | /* |
2 | * BIRD Internet Routing Daemon -- Filter instructions | |
3 | * | |
8bdb05ed | 4 | * (c) 1999 Pavel Machek <pavel@ucw.cz> |
9b46748d MM |
5 | * (c) 2018--2019 Maria Matejka <mq@jmq.cz> |
6 | * | |
7 | * Can be freely distributed and used under the terms of the GNU GPL. | |
e1ac6f1e MM |
8 | * |
9 | * Filter interpreter data structures and internal API. | |
0da06b71 | 10 | * See filter/f-inst.c for documentation. |
9b46748d MM |
11 | */ |
12 | ||
8bdb05ed MM |
13 | #ifndef _BIRD_F_INST_H_ |
14 | #define _BIRD_F_INST_H_ | |
15 | ||
4f082dfa MM |
16 | #include "nest/bird.h" |
17 | #include "conf/conf.h" | |
8bdb05ed | 18 | #include "filter/filter.h" |
4f082dfa | 19 | #include "filter/data.h" |
d06a875b | 20 | #include "lib/buffer.h" |
ff2ca10c | 21 | #include "lib/flowspec.h" |
fc354788 | 22 | #include "lib/string.h" |
8bdb05ed | 23 | |
ea4f55e3 MM |
24 | /* Flags for instructions */ |
25 | enum f_instruction_flags { | |
26bc4f99 | 26 | FIF_RECURSIVE = 1, /* FI_CALL: function is directly recursive */ |
ea4f55e3 MM |
27 | } PACKED; |
28 | ||
4f082dfa | 29 | /* Include generated filter instruction declarations */ |
87bd7cd7 | 30 | #include "filter/inst-gen.h" |
8bdb05ed | 31 | |
4f082dfa | 32 | #define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__) |
9b46748d MM |
33 | |
34 | /* Convert the instruction back to the enum name */ | |
87512e97 OZ |
35 | const char *f_instruction_name_(enum f_instruction_code fi); |
36 | static inline const char *f_instruction_name(enum f_instruction_code fi) | |
37 | { return f_instruction_name_(fi) + 3; } | |
9b46748d | 38 | |
93d6096c OZ |
39 | struct f_arg { |
40 | struct symbol *arg; | |
41 | struct f_arg *next; | |
42 | }; | |
43 | ||
8bdb05ed | 44 | /* Filter structures for execution */ |
8bdb05ed MM |
45 | /* Line of instructions to be unconditionally executed one after another */ |
46 | struct f_line { | |
47 | uint len; /* Line length */ | |
f249d0b8 | 48 | u8 args; /* Function: Args required */ |
96d757c1 | 49 | u8 vars; |
a2527ee5 | 50 | u8 results; /* Results left on stack: cmd -> 0, term -> 1 */ |
062ff656 | 51 | u8 return_type; /* Type which the function returns */ |
93d6096c | 52 | struct f_arg *arg_list; |
8bdb05ed MM |
53 | struct f_line_item items[0]; /* The items themselves */ |
54 | }; | |
9b46748d | 55 | |
8bdb05ed | 56 | /* Convert the f_inst infix tree to the f_line structures */ |
a2527ee5 OZ |
57 | struct f_line *f_linearize_concat(const struct f_inst * const inst[], uint count, uint results); |
58 | static inline struct f_line *f_linearize(const struct f_inst *root, uint results) | |
59 | { return f_linearize_concat(&root, 1, results); } | |
8bdb05ed | 60 | |
ea4f55e3 MM |
61 | void f_dump_line(const struct f_line *, uint indent); |
62 | ||
d06a875b OZ |
63 | |
64 | /* Recursive iteration over filter instructions */ | |
65 | ||
66 | struct filter_iterator { | |
67 | BUFFER_(const struct f_line *) lines; | |
68 | }; | |
69 | ||
70 | void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit); | |
71 | ||
72 | #define FILTER_ITERATE_INIT(fit, filter, pool) \ | |
73 | ({ \ | |
74 | BUFFER_INIT((fit)->lines, (pool), 32); \ | |
75 | BUFFER_PUSH((fit)->lines) = (filter)->root; \ | |
76 | }) | |
77 | ||
78 | #define FILTER_ITERATE(fit, fi) ({ \ | |
79 | const struct f_line *fl_; \ | |
80 | while (!BUFFER_EMPTY((fit)->lines)) \ | |
81 | { \ | |
82 | BUFFER_POP((fit)->lines); \ | |
83 | fl_ = (fit)->lines.data[(fit)->lines.used]; \ | |
84 | for (uint i_ = 0; i_ < fl_->len; i_++) \ | |
85 | { \ | |
86 | const struct f_line_item *fi = &fl_->items[i_]; \ | |
87 | f_add_lines(fi, (fit)); | |
88 | ||
89 | #define FILTER_ITERATE_END } } }) | |
90 | ||
91 | #define FILTER_ITERATE_CLEANUP(fit) \ | |
92 | ({ \ | |
93 | mb_free((fit)->lines.data); \ | |
94 | memset((fit), 0, sizeof(struct filter_iterator)); \ | |
95 | }) | |
96 | ||
97 | ||
63f49457 | 98 | struct filter *f_new_where(struct f_inst *); |
21faa54e MM |
99 | struct f_inst *f_for_cycle(struct symbol *var, struct f_inst *term, struct f_inst *block); |
100 | ||
78976974 MM |
101 | 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 */ |
102 | { 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 */ | |
103 | 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 */ | |
104 | { 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 */ | |
8bdb05ed MM |
105 | static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly) |
106 | { return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; } | |
8bdb05ed MM |
107 | |
108 | /* Hook for call bt_assert() function in configuration */ | |
109 | extern void (*bt_assert_hook)(int result, const struct f_line_item *assert); | |
110 | ||
111 | /* Bird Tests */ | |
112 | struct f_bt_test_suite { | |
113 | node n; /* Node in config->tests */ | |
0b39b1cb MM |
114 | const struct f_line *fn; /* Root of function */ |
115 | const struct f_line *cmp; /* Compare to this function */ | |
8bdb05ed MM |
116 | const char *fn_name; /* Name of test */ |
117 | const char *dsc; /* Description */ | |
132529ce | 118 | int result; /* Desired result */ |
9b46748d MM |
119 | }; |
120 | ||
8bdb05ed | 121 | #endif |