summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2013-10-05 20:12:28 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2013-10-05 20:12:28 +0200
commit0e175f9f0fd872e95225355dbdeca49cd35ec0fd (patch)
treee54284ea9541f3de0600acab2c8d76681f4f0ddc /filter
parent6a8d3f1c1ffbd964e4d11b452c73e1ea70310af3 (diff)
Fixes some BFD bugs and makes logging thread-safe.
Diffstat (limited to 'filter')
-rw-r--r--filter/filter.c129
-rw-r--r--filter/filter.h6
-rw-r--r--filter/test.conf2
-rw-r--r--filter/tree.c34
-rw-r--r--filter/trie.c38
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, "]");
}