diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2013-10-05 20:12:28 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2013-10-05 20:12:28 +0200 |
commit | 0e175f9f0fd872e95225355dbdeca49cd35ec0fd (patch) | |
tree | e54284ea9541f3de0600acab2c8d76681f4f0ddc /filter | |
parent | 6a8d3f1c1ffbd964e4d11b452c73e1ea70310af3 (diff) |
Fixes some BFD bugs and makes logging thread-safe.
Diffstat (limited to 'filter')
-rw-r--r-- | filter/filter.c | 129 | ||||
-rw-r--r-- | filter/filter.h | 6 | ||||
-rw-r--r-- | filter/test.conf | 2 | ||||
-rw-r--r-- | filter/tree.c | 34 | ||||
-rw-r--r-- | filter/trie.c | 38 |
5 files changed, 107 insertions, 102 deletions
diff --git a/filter/filter.c b/filter/filter.c index 25587e0f..ff4000e8 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -75,41 +75,35 @@ pm_path_compare(struct f_path_mask *m1, struct f_path_mask *m2) u32 f_eval_asn(struct f_inst *expr); static void -pm_format(struct f_path_mask *p, byte *buf, unsigned int size) +pm_format(struct f_path_mask *p, buffer *buf) { - byte *end = buf + size - 16; + buffer_puts(buf, "[= "); while (p) + { + switch(p->kind) { - if (buf > end) - { - strcpy(buf, " ..."); - return; - } - - switch(p->kind) - { - case PM_ASN: - buf += bsprintf(buf, " %u", p->val); - break; - - case PM_QUESTION: - buf += bsprintf(buf, " ?"); - break; + case PM_ASN: + buffer_print(buf, "%u ", p->val); + break; - case PM_ASTERISK: - buf += bsprintf(buf, " *"); - break; + case PM_QUESTION: + buffer_puts(buf, "? "); + break; - case PM_ASN_EXPR: - buf += bsprintf(buf, " %u", f_eval_asn((struct f_inst *) p->val)); - break; - } + case PM_ASTERISK: + buffer_puts(buf, "* "); + break; - p = p->next; + case PM_ASN_EXPR: + buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val)); + break; } - *buf = 0; + p = p->next; + } + + buffer_puts(buf, "=]"); } static inline int int_cmp(int i1, int i2) @@ -119,7 +113,7 @@ static inline int int_cmp(int i1, int i2) else return 1; } -static inline int uint_cmp(unsigned int i1, unsigned int i2) +static inline int uint_cmp(uint i1, uint i2) { if (i1 == i2) return 0; if (i1 < i2) return -1; @@ -440,60 +434,32 @@ val_in_range(struct f_val v1, struct f_val v2) return CMP_ERROR; } -static void -tree_node_print(struct f_tree *t, char **sep) -{ - if (t == NULL) - return; - - tree_node_print(t->left, sep); - - logn(*sep); - val_print(t->from); - if (val_compare(t->from, t->to) != 0) - { - logn( ".." ); - val_print(t->to); - } - *sep = ", "; - - tree_node_print(t->right, sep); -} - -static void -tree_print(struct f_tree *t) -{ - char *sep = ""; - logn( "[" ); - tree_node_print(t, &sep); - logn( "] " ); -} - /* - * val_print - format filter value + * val_format - format filter value */ void -val_print(struct f_val v) +val_format(struct f_val v, buffer *buf) { char buf2[1024]; - switch (v.type) { - case T_VOID: logn("(void)"); return; - case T_BOOL: logn(v.val.i ? "TRUE" : "FALSE"); return; - case T_INT: logn("%d", v.val.i); return; - case T_STRING: logn("%s", v.val.s); return; - case T_IP: logn("%I", v.val.px.ip); return; - case T_PREFIX: logn("%I/%d", v.val.px.ip, v.val.px.len); return; - case T_PAIR: logn("(%d,%d)", v.val.i >> 16, v.val.i & 0xffff); return; - case T_QUAD: logn("%R", v.val.i); return; - case T_EC: ec_format(buf2, v.val.ec); logn("%s", buf2); return; - case T_PREFIX_SET: trie_print(v.val.ti); return; - case T_SET: tree_print(v.val.t); return; - case T_ENUM: logn("(enum %x)%d", v.type, v.val.i); return; - case T_PATH: as_path_format(v.val.ad, buf2, 1000); logn("(path %s)", buf2); return; - case T_CLIST: int_set_format(v.val.ad, 1, -1, buf2, 1000); logn("(clist %s)", buf2); return; - case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); logn("(eclist %s)", buf2); return; - case T_PATH_MASK: pm_format(v.val.path_mask, buf2, 1000); logn("(pathmask%s)", buf2); return; - default: logn( "[unknown type %x]", v.type ); return; + switch (v.type) + { + case T_VOID: buffer_puts(buf, "(void)"); return; + case T_BOOL: buffer_puts(buf, v.val.i ? "TRUE" : "FALSE"); return; + case T_INT: buffer_print(buf, "%d", v.val.i); return; + case T_STRING: buffer_print(buf, "%s", v.val.s); return; + case T_IP: buffer_print(buf, "%I", v.val.px.ip); return; + case T_PREFIX: buffer_print(buf, "%I/%d", v.val.px.ip, v.val.px.len); return; + case T_PAIR: buffer_print(buf, "(%d,%d)", v.val.i >> 16, v.val.i & 0xffff); return; + case T_QUAD: buffer_print(buf, "%R", v.val.i); return; + case T_EC: ec_format(buf2, v.val.ec); buffer_print(buf, "%s", buf2); return; + case T_PREFIX_SET: trie_format(v.val.ti, buf); return; + case T_SET: tree_format(v.val.t, buf); return; + case T_ENUM: buffer_print(buf, "(enum %x)%d", v.type, v.val.i); return; + case T_PATH: as_path_format(v.val.ad, buf2, 1000); buffer_print(buf, "(path %s)", buf2); return; + case T_CLIST: int_set_format(v.val.ad, 1, -1, buf2, 1000); buffer_print(buf, "(clist %s)", buf2); return; + case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); buffer_print(buf, "(eclist %s)", buf2); return; + case T_PATH_MASK: pm_format(v.val.path_mask, buf); return; + default: buffer_print(buf, "[unknown type %x]", v.type); return; } } @@ -501,6 +467,7 @@ static struct rte **f_rte; static struct rta *f_old_rta; static struct ea_list **f_tmp_attrs; static struct linpool *f_pool; +static struct buffer f_buf; static int f_flags; static inline void f_rte_cow(void) @@ -782,7 +749,7 @@ interpret(struct f_inst *what) break; case 'p': ONEARG; - val_print(v1); + val_format(v1, &f_buf); break; case '?': /* ? has really strange error value, so we can implement if ... else nicely :-) */ ONEARG; @@ -800,7 +767,7 @@ interpret(struct f_inst *what) case P('p',','): ONEARG; if (what->a2.i == F_NOP || (what->a2.i != F_NONL && what->a1.p)) - log_commit(*L_INFO); + log_commit(*L_INFO, &f_buf); switch (what->a2.i) { case F_QUITBIRD: @@ -1502,7 +1469,8 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc f_pool = tmp_pool; f_flags = flags; - log_reset(); + LOG_BUFFER_INIT(f_buf); + struct f_val res = interpret(filter->root); if (f_old_rta) { @@ -1541,7 +1509,8 @@ f_eval(struct f_inst *expr, struct linpool *tmp_pool) f_rte = NULL; f_pool = tmp_pool; - log_reset(); + LOG_BUFFER_INIT(f_buf); + return interpret(expr); } diff --git a/filter/filter.h b/filter/filter.h index 1d5150e7..0cef9f36 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -78,12 +78,13 @@ struct f_inst *f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, s struct f_tree *build_tree(struct f_tree *); struct f_tree *find_tree(struct f_tree *t, struct f_val val); int same_tree(struct f_tree *t1, struct f_tree *t2); +void tree_format(struct f_tree *t, buffer *buf); struct f_trie *f_new_trie(linpool *lp); void trie_add_prefix(struct f_trie *t, ip_addr px, int plen, int l, int h); int trie_match_prefix(struct f_trie *t, ip_addr px, int plen); int trie_same(struct f_trie *t1, struct f_trie *t2); -void trie_print(struct f_trie *t); +void trie_format(struct f_trie *t, buffer *buf); void fprefix_get_bounds(struct f_prefix *px, int *l, int *h); @@ -118,7 +119,8 @@ int i_same(struct f_inst *f1, struct f_inst *f2); int val_compare(struct f_val v1, struct f_val v2); int tree_compare(const void *p1, const void *p2); -void val_print(struct f_val v); +void val_format(struct f_val v, buffer *buf); + #define F_NOP 0 #define F_NONL 1 diff --git a/filter/test.conf b/filter/test.conf index 048983b5..3d35ed05 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -106,7 +106,7 @@ eclist el2; print "5 = ", p2.len; print "Delete 3: ", delete(p2, 3); print "Filter 1-3: ", filter(p2, [1..3]); - + pm1 = [= 1 2 * 3 4 5 =]; p2 = prepend( + empty +, 5 ); p2 = prepend( p2, 4 ); diff --git a/filter/tree.c b/filter/tree.c index f6ab75b4..5e1d606a 100644 --- a/filter/tree.c +++ b/filter/tree.c @@ -132,3 +132,37 @@ same_tree(struct f_tree *t1, struct f_tree *t2) return 0; return 1; } + + +static void +tree_node_format(struct f_tree *t, buffer *buf) +{ + if (t == NULL) + return; + + tree_node_format(t->left, buf); + + val_format(t->from, buf); + if (val_compare(t->from, t->to) != 0) + { + buffer_puts(buf, ".."); + val_format(t->to, buf); + } + buffer_puts(buf, ", "); + + tree_node_format(t->right, buf); +} + +void +tree_format(struct f_tree *t, buffer *buf) +{ + buffer_puts(buf, "["); + + tree_node_format(t, buf); + + /* Undo last separator */ + if (buf->pos[-1] != '[') + buf->pos -= 2; + + buffer_puts(buf, "]"); +} diff --git a/filter/trie.c b/filter/trie.c index 581332c6..52b1ed47 100644 --- a/filter/trie.c +++ b/filter/trie.c @@ -265,37 +265,37 @@ trie_same(struct f_trie *t1, struct f_trie *t2) } static void -trie_node_print(struct f_trie_node *t, char **sep) +trie_node_format(struct f_trie_node *t, buffer *buf) { if (t == NULL) return; if (ipa_nonzero(t->accept)) - { - logn("%s%I/%d{%I}", *sep, t->addr, t->plen, t->accept); - *sep = ", "; - } + buffer_print(buf, "%I/%d{%I}, ", t->addr, t->plen, t->accept); - trie_node_print(t->c[0], sep); - trie_node_print(t->c[1], sep); + trie_node_format(t->c[0], buf); + trie_node_format(t->c[1], buf); } /** - * trie_print - * @t: trie to be printed + * trie_format + * @t: trie to be formatted + * @buf: destination buffer * - * Prints the trie to the log buffer. + * Prints the trie to the supplied buffer. */ void -trie_print(struct f_trie *t) +trie_format(struct f_trie *t, buffer *buf) { - char *sep = ""; - logn("["); + buffer_puts(buf, "["); + if (t->zero) - { - logn("0.0.0.0/0"); - sep = ", "; - } - trie_node_print(&t->root, &sep); - logn("]"); + buffer_print(buf, "0.0.0.0/0, "); + trie_node_format(&t->root, buf); + + /* Undo last separator */ + if (buf->pos[-1] != '[') + buf->pos -= 2; + + buffer_puts(buf, "]"); } |