diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2021-11-19 18:04:32 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2021-11-19 18:04:32 +0100 |
commit | 062e69bf520e5788913bdd564076ad9892b24a87 (patch) | |
tree | d8a4f3496220ea818b3b8ad1fbb931647adebe46 /filter/data.h | |
parent | 71c18d9f53ec0ea5eb512fdb6510d0c3350f96b4 (diff) |
Trie: Implement trie walking code
Trie walking allows enumeration of prefixes in a trie in the usual
lexicographic order. Optionally, trie enumeration can be restricted
to a chosen subnet (and its descendants).
Diffstat (limited to 'filter/data.h')
-rw-r--r-- | filter/data.h | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/filter/data.h b/filter/data.h index 21967deb..4a0ee865 100644 --- a/filter/data.h +++ b/filter/data.h @@ -140,7 +140,8 @@ struct f_tree { void *data; }; -#define TRIE_STEP 4 +#define TRIE_STEP 4 +#define TRIE_STACK_LENGTH 33 struct f_trie_node4 { @@ -175,6 +176,16 @@ struct f_trie struct f_trie_node root; /* Root trie node */ }; +struct f_trie_walk_state +{ + u8 ipv4; + u8 accept_length; /* Current inter-node prefix position */ + u8 start_pos; /* Initial prefix position in stack[0] */ + u8 local_pos; /* Current intra-node prefix position */ + u8 stack_pos; /* Current node in stack below */ + const struct f_trie_node *stack[TRIE_STACK_LENGTH]; +}; + struct f_tree *f_new_tree(void); struct f_tree *build_tree(struct f_tree *); const struct f_tree *find_tree(const struct f_tree *t, const struct f_val *val); @@ -185,9 +196,19 @@ void tree_walk(const struct f_tree *t, void (*hook)(const struct f_tree *, void struct f_trie *f_new_trie(linpool *lp, uint data_size); void *trie_add_prefix(struct f_trie *t, const net_addr *n, uint l, uint h); int trie_match_net(const struct f_trie *t, const net_addr *n); +void trie_walk_init(struct f_trie_walk_state *s, const struct f_trie *t, const net_addr *from); +int trie_walk_next(struct f_trie_walk_state *s, net_addr *net); int trie_same(const struct f_trie *t1, const struct f_trie *t2); void trie_format(const struct f_trie *t, buffer *buf); +#define TRIE_WALK(trie, net, from) ({ \ + net_addr net; \ + struct f_trie_walk_state tws_; \ + trie_walk_init(&tws_, trie, from); \ + while (trie_walk_next(&tws_, &net)) + +#define TRIE_WALK_END }) + #define F_CMP_ERROR 999 const char *f_type_name(enum f_type t); |