1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Extends pair set syntax, matching and deleting against clist.

Expressions like (123,*) can be used in pair set literals, clists can be
matched against pair sets (community ~ pairset) and pair sets can be
used to specify items to delete from clists (community.delete(pairset)).
This commit is contained in:
Ondrej Zajicek
2010-05-22 22:47:24 +02:00
parent 6d04ef8987
commit ba5c0057ed
4 changed files with 103 additions and 10 deletions

View File

@@ -243,7 +243,13 @@ set_atom:
;
set_item:
set_atom {
'(' NUM ',' '*' ')' {
$$ = f_new_tree();
$$->from.type = $$->to.type = T_PAIR;
$$->from.val.i = make_pair($2, 0);
$$->to.val.i = make_pair($2, 0xffff);
}
| set_atom {
$$ = f_new_tree();
$$->from = $1;
$$->to = $1;

View File

@@ -230,6 +230,76 @@ val_simple_in_range(struct f_val v1, struct f_val v2)
return CMP_ERROR;
}
static int
clist_set_type(struct f_tree *set, struct f_val *v)
{
switch (set->from.type) {
case T_PAIR:
v->type = T_PAIR;
return 1;
case T_QUAD:
#ifndef IPV6
case T_IP:
#endif
v->type = T_QUAD;
return 1;
break;
default:
v->type = T_VOID;
return 0;
}
}
static int
clist_match_set(struct adata *clist, struct f_tree *set)
{
if (!clist)
return 0;
struct f_val v;
if (!clist_set_type(set, &v))
return CMP_ERROR;
u32 *l = (u32 *) clist->data;
u32 *end = l + clist->length/4;
while (l < end) {
v.val.i = *l++;
if (find_tree(set, v))
return 1;
}
return 0;
}
static struct adata *
clist_del_matching(struct linpool *pool, struct adata *clist, struct f_tree *set)
{
if (!clist)
return NULL;
struct f_val v;
clist_set_type(set, &v);
u32 tmp[clist->length/4];
u32 *l = (u32 *) clist->data;
u32 *k = tmp;
u32 *end = l + clist->length/4;
while (l < end) {
v.val.i = *l++;
if (!find_tree(set, v))
*k++ = v.val.i;
}
int nl = (k - tmp) * 4;
if (nl == clist->length)
return clist;
struct adata *res = lp_alloc(pool, sizeof(struct adata) + nl);
res->length = nl;
memcpy(res->data, tmp, nl);
return res;
}
/**
* val_in_range - implement |~| operator
* @v1: element
@@ -251,6 +321,9 @@ val_in_range(struct f_val v1, struct f_val v2)
if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET))
return trie_match_prefix(v2.val.ti, &v1.val.px);
if ((v1.type == T_CLIST) && (v2.type == T_SET))
return clist_match_set(v1.val.ad, v2.val.t);
if (v2.type == T_SET)
switch (v1.type) {
case T_ENUM:
@@ -845,6 +918,7 @@ interpret(struct f_inst *what)
if (v1.type != T_CLIST)
runtime("Can't add/delete to non-clist");
struct f_val dummy;
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
i = v2.val.i;
#ifndef IPV6
@@ -852,6 +926,8 @@ interpret(struct f_inst *what)
else if (v2.type == T_IP)
i = ipa_to_u32(v2.val.px.ip);
#endif
else if ((v2.type == T_SET) && (what->aux == 'd') && clist_set_type(v2.val.t, &dummy))
what->aux = 'D';
else
runtime("Can't add/delete non-pair");
@@ -859,6 +935,7 @@ interpret(struct f_inst *what)
switch (what->aux) {
case 'a': res.val.ad = int_set_add(f_pool, v1.val.ad, i); break;
case 'd': res.val.ad = int_set_del(f_pool, v1.val.ad, i); break;
case 'D': res.val.ad = clist_del_matching(f_pool, v1.val.ad, v2.val.t); break;
default: bug("unknown Ca operation");
}
break;

View File

@@ -79,10 +79,11 @@ clist l;
l = add( l, (1,2) );
l = add( l, (2,3) );
print "Community list (1,2) (2,3) ", l;
print "Should be true: ", (2,3) ~ l;
l = delete( l, (2,3) );
print "Should be true: ", (2,3) ~ l, " ", l ~ [(1,*)], " ", l ~ [(2,3)];
l = add( l, (2,5) );
l = delete( l, [(2,*)] );
print "Community list (1,2) ", l;
print "Should be false: ", (2,3) ~ l;
print "Should be false: ", (2,3) ~ l, " ", l ~ [(2,*)];
}
function bla()
@@ -196,8 +197,9 @@ string s;
", true: ", RTS_STATIC ~ [RTS_STATIC, RTS_DEVICE],
", false: ", RTS_BGP ~ [RTS_STATIC, RTS_DEVICE];
ps = [(1,2), (3,4)..(3,8)];
print "Testing pair set (TTF):", pp ~ ps, " ", (3,5) ~ ps, " ", (3,9) ~ ps;
ps = [(1,2), (3,4)..(4,8), (5,*)];
print "Testing pair set, true: ", pp ~ ps, " ", (3,5) ~ ps, " ", (4,1) ~ ps, " ", (5,4) ~ ps, " ", (5,65535) ~ ps;
print "Testing pair set, false: ", (3,3) ~ ps, " ", (4,9) ~ ps, " ", (4,65535) ~ ps, " ", (6,0) ~ ps ;
qq = 1.2.3.4;
print "Testinq quad: 1.2.3.4 = ", qq,