0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-19 01:28:44 +00:00
bird/filter/f-inst.h
Maria Matejka bc17fee1bf Filter: Bitfield eattrs reading / writing moved to filter code
Before this change, fetch-update-write and bitmasking was hardcoded in
attribute access code cased by the attribute type. Several filter
instructions are used to do it instead.

As this is certainly going to be a little bit slower than before, the
switch block in attribute access code should be completely removed in
near future, helping with both performance and code cleanliness.

The user interface should have stayed intact.
2022-05-04 15:37:41 +02:00

113 lines
4.1 KiB
C

/*
* BIRD Internet Routing Daemon -- Filter instructions
*
* (c) 1999 Pavel Machek <pavel@ucw.cz>
* (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.
* See filter/f-inst.c for documentation.
*/
#ifndef _BIRD_F_INST_H_
#define _BIRD_F_INST_H_
#include "nest/bird.h"
#include "conf/conf.h"
#include "filter/filter.h"
#include "filter/data.h"
#include "lib/buffer.h"
#include "lib/flowspec.h"
/* Flags for instructions */
enum f_instruction_flags {
FIF_PRINTED = 1, /* FI_PRINT_AND_DIE: message put in buffer */
} PACKED;
/* Include generated filter instruction declarations */
#include "filter/inst-gen.h"
#define f_new_inst(...) MACRO_CONCAT_AFTER(f_new_inst_, MACRO_FIRST(__VA_ARGS__))(__VA_ARGS__)
/* Convert the instruction back to the enum name */
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; }
/* Filter structures for execution */
/* Line of instructions to be unconditionally executed one after another */
struct f_line {
uint len; /* Line length */
u8 args; /* Function: Args required */
u8 vars;
struct f_line_item items[0]; /* The items themselves */
};
/* Convert the f_inst infix tree to the f_line structures */
struct f_line *f_linearize_concat(const struct f_inst * const inst[], uint count);
static inline struct f_line *f_linearize(const struct f_inst *root)
{ return f_linearize_concat(&root, 1); }
void f_dump_line(const struct f_line *, uint indent);
/* 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)); \
})
struct filter *f_new_where(struct f_inst *);
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, 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_INT, .bit = bit, .f_type = T_INT, .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 }; }
struct f_inst *f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument);
struct f_inst *f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct f_inst *asn);
/* 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 */
const struct f_line *fn; /* Root of function */
const struct f_line *cmp; /* Compare to this function */
const char *fn_name; /* Name of test */
const char *dsc; /* Description */
int result; /* Desired result */
};
#endif