]>
Commit | Line | Data |
---|---|---|
b9d70dc8 | 1 | /* |
e0f2e42f | 2 | * BIRD Internet Routing Daemon -- Filters |
b9d70dc8 | 3 | * |
e0f2e42f | 4 | * (c) 1999 Pavel Machek <pavel@ucw.cz> |
b9d70dc8 PM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_FILT_H_ | |
10 | #define _BIRD_FILT_H_ | |
11 | ||
12 | #include "lib/resource.h" | |
23b1539b | 13 | #include "lib/ip.h" |
4847a894 | 14 | #include "nest/route.h" |
159fa4ce | 15 | #include "nest/attrs.h" |
b9d70dc8 | 16 | |
ca2ee91a MM |
17 | struct f_prefix { |
18 | net_addr net; | |
19 | u8 lo, hi; | |
20 | }; | |
21 | ||
22 | struct f_val { | |
23 | int type; /* T_* */ | |
24 | union { | |
25 | uint i; | |
26 | u64 ec; | |
27 | lcomm lc; | |
28 | ip_addr ip; | |
29 | const net_addr *net; | |
30 | char *s; | |
31 | struct f_tree *t; | |
32 | struct f_trie *ti; | |
33 | struct adata *ad; | |
34 | struct f_path_mask *path_mask; | |
35 | } val; | |
36 | }; | |
37 | ||
38 | struct f_dynamic_attr { | |
39 | int type; | |
40 | int f_type; | |
41 | int ea_code; | |
42 | }; | |
43 | ||
44 | struct f_static_attr { | |
45 | int f_type; | |
46 | int sa_code; | |
47 | int readonly; | |
48 | }; | |
49 | ||
5a14df39 MJM |
50 | /* Filter instruction types */ |
51 | ||
52 | #define FI__TWOCHAR(a,b) ((a<<8) | b) | |
53 | #define FI__LIST \ | |
967b88d9 | 54 | F(FI_NOP, 0, '0') \ |
5a14df39 MJM |
55 | F(FI_ADD, 0, '+') \ |
56 | F(FI_SUBTRACT, 0, '-') \ | |
57 | F(FI_MULTIPLY, 0, '*') \ | |
58 | F(FI_DIVIDE, 0, '/') \ | |
59 | F(FI_AND, 0, '&') \ | |
60 | F(FI_OR, 0, '|') \ | |
61 | F(FI_PAIR_CONSTRUCT, 'm', 'p') \ | |
62 | F(FI_EC_CONSTRUCT, 'm', 'c') \ | |
63 | F(FI_LC_CONSTRUCT, 'm', 'l') \ | |
e8bc64e3 | 64 | F(FI_PATHMASK_CONSTRUCT, 'm', 'P') \ |
5a14df39 MJM |
65 | F(FI_NEQ, '!', '=') \ |
66 | F(FI_EQ, '=', '=') \ | |
67 | F(FI_LT, 0, '<') \ | |
68 | F(FI_LTE, '<', '=') \ | |
69 | F(FI_NOT, 0, '!') \ | |
70 | F(FI_MATCH, 0, '~') \ | |
71 | F(FI_NOT_MATCH, '!', '~') \ | |
72 | F(FI_DEFINED, 'd', 'e') \ | |
d1ba927b JMM |
73 | F(FI_TYPE, 0, 'T') \ |
74 | F(FI_IS_V4, 'I', 'i') \ | |
5a14df39 MJM |
75 | F(FI_SET, 0, 's') \ |
76 | F(FI_CONSTANT, 0, 'c') \ | |
77 | F(FI_VARIABLE, 0, 'V') \ | |
78 | F(FI_CONSTANT_INDIRECT, 0, 'C') \ | |
79 | F(FI_PRINT, 0, 'p') \ | |
80 | F(FI_CONDITION, 0, '?') \ | |
5a14df39 MJM |
81 | F(FI_PRINT_AND_DIE, 'p', ',') \ |
82 | F(FI_RTA_GET, 0, 'a') \ | |
83 | F(FI_RTA_SET, 'a', 'S') \ | |
84 | F(FI_EA_GET, 'e', 'a') \ | |
85 | F(FI_EA_SET, 'e', 'S') \ | |
86 | F(FI_PREF_GET, 0, 'P') \ | |
87 | F(FI_PREF_SET, 'P', 'S') \ | |
88 | F(FI_LENGTH, 0, 'L') \ | |
d1ba927b JMM |
89 | F(FI_ROA_MAXLEN, 'R', 'M') \ |
90 | F(FI_ROA_ASN, 'R', 'A') \ | |
b24b7811 | 91 | F(FI_SADR_SRC, 'n', 's') \ |
5a14df39 | 92 | F(FI_IP, 'c', 'p') \ |
d1ba927b | 93 | F(FI_ROUTE_DISTINGUISHER, 'R', 'D') \ |
5a14df39 MJM |
94 | F(FI_AS_PATH_FIRST, 'a', 'f') \ |
95 | F(FI_AS_PATH_LAST, 'a', 'l') \ | |
96 | F(FI_AS_PATH_LAST_NAG, 'a', 'L') \ | |
97 | F(FI_RETURN, 0, 'r') \ | |
98 | F(FI_CALL, 'c', 'a') \ | |
99 | F(FI_CLEAR_LOCAL_VARS, 'c', 'V') \ | |
100 | F(FI_SWITCH, 'S', 'W') \ | |
101 | F(FI_IP_MASK, 'i', 'M') \ | |
102 | F(FI_EMPTY, 0, 'E') \ | |
103 | F(FI_PATH_PREPEND, 'A', 'p') \ | |
104 | F(FI_CLIST_ADD_DEL, 'C', 'a') \ | |
d1ba927b JMM |
105 | F(FI_ROA_CHECK, 'R', 'C') \ |
106 | F(FI_FORMAT, 0, 'F') \ | |
107 | F(FI_ASSERT, 'a', 's') | |
5a14df39 MJM |
108 | |
109 | enum f_instruction_code { | |
110 | #define F(c,a,b) \ | |
31d6939c | 111 | c, |
5a14df39 MJM |
112 | FI__LIST |
113 | #undef F | |
cff9e937 | 114 | FI__MAX, |
5a14df39 MJM |
115 | } PACKED; |
116 | ||
0ec6b5ec JMM |
117 | const char *f_instruction_name(enum f_instruction_code fi); |
118 | ||
b7005824 PM |
119 | struct f_inst { /* Instruction */ |
120 | struct f_inst *next; /* Structure is 16 bytes, anyway */ | |
5a14df39 | 121 | enum f_instruction_code fi_code; |
9b0a0ba9 | 122 | u16 aux; /* Extension to instruction code, T_*, EA_*, EAF_* */ |
2db3b288 | 123 | union { |
ca2ee91a MM |
124 | union { |
125 | uint i; | |
126 | void *p; | |
84360407 | 127 | struct rtable_config *rtc; |
ca2ee91a MM |
128 | } a[3]; /* The three arguments */ |
129 | struct f_val val; /* The value if FI_CONSTANT */ | |
130 | }; | |
a96a979d | 131 | int lineno; |
b9d70dc8 PM |
132 | }; |
133 | ||
7f0ac737 MM |
134 | #define arg1 a[0].p |
135 | #define arg2 a[1].p | |
136 | #define arg3 a[2].p | |
2db3b288 | 137 | |
e0f2e42f MM |
138 | struct filter { |
139 | char *name; | |
140 | struct f_inst *root; | |
141 | }; | |
142 | ||
5a14df39 MJM |
143 | struct f_inst *f_new_inst(enum f_instruction_code fi_code); |
144 | struct f_inst *f_new_inst_da(enum f_instruction_code fi_code, struct f_dynamic_attr da); | |
145 | struct f_inst *f_new_inst_sa(enum f_instruction_code fi_code, struct f_static_attr sa); | |
146 | 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 */ | |
147 | { 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 */ | |
148 | static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly) | |
149 | { return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; } | |
38506f71 | 150 | struct f_tree *f_new_tree(void); |
5a14df39 | 151 | struct f_inst *f_generate_complex(int operation, int operation_aux, struct f_dynamic_attr da, struct f_inst *argument); |
0264ccf6 | 152 | struct f_inst *f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct f_inst *asn); |
af582c48 | 153 | |
38506f71 PM |
154 | |
155 | struct f_tree *build_tree(struct f_tree *); | |
156 | struct f_tree *find_tree(struct f_tree *t, struct f_val val); | |
9a4037d4 | 157 | int same_tree(struct f_tree *t1, struct f_tree *t2); |
0e175f9f | 158 | void tree_format(struct f_tree *t, buffer *buf); |
84c7e194 | 159 | |
51762a45 | 160 | struct f_trie *f_new_trie(linpool *lp, uint node_size); |
0bf95f99 | 161 | void *trie_add_prefix(struct f_trie *t, const net_addr *n, uint l, uint h); |
5e173e9f | 162 | int trie_match_net(struct f_trie *t, const net_addr *n); |
b1a597e0 | 163 | int trie_same(struct f_trie *t1, struct f_trie *t2); |
0e175f9f | 164 | void trie_format(struct f_trie *t, buffer *buf); |
b1a597e0 | 165 | |
9a706f32 MM |
166 | struct ea_list; |
167 | struct rte; | |
168 | ||
7afa1438 JMM |
169 | enum filter_return { |
170 | F_NOP = 0, | |
171 | F_NONL, | |
172 | F_RETURN, | |
173 | F_ACCEPT, /* Need to preserve ordering: accepts < rejects! */ | |
174 | F_REJECT, | |
175 | F_ERROR, | |
176 | F_QUITBIRD, | |
177 | }; | |
178 | ||
179 | enum filter_return f_run(struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags); | |
180 | enum filter_return f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool); | |
181 | enum filter_return f_eval(struct f_inst *expr, struct linpool *tmp_pool, struct f_val *pres); | |
52e030e1 | 182 | uint f_eval_int(struct f_inst *expr); |
05198c12 | 183 | |
63a381db | 184 | char *filter_name(struct filter *filter); |
30a6108c | 185 | int filter_same(struct filter *new, struct filter *old); |
e0f2e42f | 186 | |
9a4037d4 PM |
187 | int i_same(struct f_inst *f1, struct f_inst *f2); |
188 | ||
38506f71 | 189 | int val_compare(struct f_val v1, struct f_val v2); |
28a10f84 | 190 | int val_same(struct f_val v1, struct f_val v2); |
23b1539b | 191 | |
0e175f9f OZ |
192 | void val_format(struct f_val v, buffer *buf); |
193 | ||
63a381db MM |
194 | #define FILTER_ACCEPT NULL |
195 | #define FILTER_REJECT ((void *) 1) | |
3831b619 | 196 | #define FILTER_UNDEF ((void *) 2) /* Used in BGP */ |
63a381db | 197 | |
ba921648 PM |
198 | /* Type numbers must be in 0..0xff range */ |
199 | #define T_MASK 0xff | |
200 | ||
201 | /* Internal types */ | |
c7b43f33 PM |
202 | /* Do not use type of zero, that way we'll see errors easier. */ |
203 | #define T_VOID 1 | |
ba921648 PM |
204 | |
205 | /* User visible types, which fit in int */ | |
206 | #define T_INT 0x10 | |
207 | #define T_BOOL 0x11 | |
7a86a8b0 | 208 | #define T_PAIR 0x12 /* Notice that pair is stored as integer: first << 16 | second */ |
126683fe | 209 | #define T_QUAD 0x13 |
f4536657 | 210 | |
2d496d20 | 211 | /* Put enumerational types in 0x30..0x3f range */ |
f4536657 | 212 | #define T_ENUM_LO 0x30 |
2d496d20 | 213 | #define T_ENUM_HI 0x3f |
f4536657 | 214 | |
cb8034f4 | 215 | #define T_ENUM_RTS 0x30 |
471bd6c3 | 216 | #define T_ENUM_BGP_ORIGIN 0x31 |
26c09e1d PM |
217 | #define T_ENUM_SCOPE 0x32 |
218 | #define T_ENUM_RTC 0x33 | |
219 | #define T_ENUM_RTD 0x34 | |
cb1bd816 | 220 | #define T_ENUM_ROA 0x35 |
8c9986d3 | 221 | #define T_ENUM_NETTYPE 0x36 |
830ba75e | 222 | #define T_ENUM_RA_PREFERENCE 0x37 |
8c9986d3 | 223 | |
471bd6c3 | 224 | /* new enums go here */ |
3bbc4ad6 | 225 | #define T_ENUM_EMPTY 0x3f /* Special hack for atomic_aggr */ |
cb8034f4 | 226 | |
f4536657 | 227 | #define T_ENUM T_ENUM_LO ... T_ENUM_HI |
ba921648 PM |
228 | |
229 | /* Bigger ones */ | |
230 | #define T_IP 0x20 | |
5e173e9f | 231 | #define T_NET 0x21 |
ba921648 | 232 | #define T_STRING 0x22 |
dcab7890 | 233 | #define T_PATH_MASK 0x23 /* mask for BGP path */ |
10a53608 PM |
234 | #define T_PATH 0x24 /* BGP path */ |
235 | #define T_CLIST 0x25 /* Community list */ | |
66dbdbd9 OZ |
236 | #define T_EC 0x26 /* Extended community value, u64 */ |
237 | #define T_ECLIST 0x27 /* Extended community list */ | |
238 | #define T_LC 0x28 /* Large community value, lcomm */ | |
239 | #define T_LCLIST 0x29 /* Large community list */ | |
8c9986d3 | 240 | #define T_RD 0x2a /* Route distinguisher for VPN addresses */ |
ba921648 PM |
241 | |
242 | #define T_SET 0x80 | |
b1a597e0 | 243 | #define T_PREFIX_SET 0x81 |
d36d838d | 244 | |
a5fc5958 | 245 | |
5e173e9f JMM |
246 | #define SA_FROM 1 |
247 | #define SA_GW 2 | |
248 | #define SA_NET 3 | |
249 | #define SA_PROTO 4 | |
250 | #define SA_SOURCE 5 | |
251 | #define SA_SCOPE 6 | |
62e64905 OZ |
252 | #define SA_DEST 7 |
253 | #define SA_IFNAME 8 | |
254 | #define SA_IFINDEX 9 | |
a5fc5958 OZ |
255 | |
256 | ||
38506f71 PM |
257 | struct f_tree { |
258 | struct f_tree *left, *right; | |
259 | struct f_val from, to; | |
260 | void *data; | |
261 | }; | |
262 | ||
b1a597e0 OZ |
263 | struct f_trie_node |
264 | { | |
265 | ip_addr addr, mask, accept; | |
8860e991 | 266 | uint plen; |
b1a597e0 OZ |
267 | struct f_trie_node *c[2]; |
268 | }; | |
269 | ||
270 | struct f_trie | |
271 | { | |
7f0d245a | 272 | linpool *lp; |
b1a597e0 | 273 | int zero; |
51762a45 OZ |
274 | uint node_size; |
275 | struct f_trie_node root[0]; /* Root trie node follows */ | |
b1a597e0 OZ |
276 | }; |
277 | ||
d3dd620b PM |
278 | #define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); |
279 | ||
b9405791 | 280 | #define FF_SILENT 2 /* Silent filter execution */ |
0a06a9b8 | 281 | |
265419a3 MM |
282 | /* Custom route attributes */ |
283 | struct custom_attribute { | |
284 | resource r; | |
285 | struct f_dynamic_attr *fda; | |
286 | const char *name; | |
287 | }; | |
288 | ||
289 | struct custom_attribute *ca_lookup(pool *p, const char *name, int ea_type); | |
290 | ||
9b0a0ba9 OZ |
291 | /* Bird Tests */ |
292 | struct f_bt_test_suite { | |
293 | node n; /* Node in config->tests */ | |
294 | struct f_inst *fn; /* Root of function */ | |
295 | const char *fn_name; /* Name of test */ | |
296 | const char *dsc; /* Description */ | |
297 | }; | |
298 | ||
299 | /* Hook for call bt_assert() function in configuration */ | |
300 | extern void (*bt_assert_hook)(int result, struct f_inst *assert); | |
301 | ||
b9d70dc8 | 302 | #endif |