Int sets moved to core. It is now possible to have variable of type clist.
This commit is contained in:
parent
e3558ab14e
commit
9c400ec9dd
5 changed files with 73 additions and 0 deletions
|
@ -390,6 +390,7 @@ term:
|
||||||
case SYM_VARIABLE | T_IP:
|
case SYM_VARIABLE | T_IP:
|
||||||
case SYM_VARIABLE | T_PATH_MASK:
|
case SYM_VARIABLE | T_PATH_MASK:
|
||||||
case SYM_VARIABLE | T_PATH:
|
case SYM_VARIABLE | T_PATH:
|
||||||
|
case SYM_VARIABLE | T_CLIST:
|
||||||
$$->code = 'C';
|
$$->code = 'C';
|
||||||
$$->a1.p = $1->aux2;
|
$$->a1.p = $1->aux2;
|
||||||
break;
|
break;
|
||||||
|
@ -423,7 +424,11 @@ term:
|
||||||
| term '.' RESET { }
|
| term '.' RESET { }
|
||||||
|
|
||||||
| '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
|
| '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
|
||||||
|
| '-' EMPTY '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_CLIST; }
|
||||||
| PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
|
| PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
|
||||||
|
/* | ADD '(' term, ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; }
|
||||||
|
| DELETE '(' term, ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; } */
|
||||||
|
|
||||||
|
|
||||||
/* | term '.' LEN { $$->code = P('P','l'); } */
|
/* | term '.' LEN { $$->code = P('P','l'); } */
|
||||||
|
|
||||||
|
|
|
@ -483,6 +483,21 @@ interpret(struct f_inst *what)
|
||||||
res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i);
|
res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case P('C','a'): /* Community list add or delete */
|
||||||
|
TWOARGS;
|
||||||
|
if (v1.type != T_CLIST)
|
||||||
|
runtime("Can't add/delete to non-clist");
|
||||||
|
if (v2.type != T_PAIR)
|
||||||
|
runtime("Can't add/delete non-pair");
|
||||||
|
|
||||||
|
res.type = T_CLIST;
|
||||||
|
switch (what->aux) {
|
||||||
|
case 'a': res.val.ad = int_set_add(f_pool, v1.val.ad, v2.val.i); break;
|
||||||
|
case 'd': res.val.ad = int_set_del(f_pool, v1.val.ad, v2.val.i); break;
|
||||||
|
default: bug("unknown Ca operation");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
|
bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
|
||||||
}
|
}
|
||||||
|
@ -566,6 +581,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
|
||||||
case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
|
case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
|
||||||
case P('i','M'): TWOARGS; break;
|
case P('i','M'): TWOARGS; break;
|
||||||
case P('A','p'): TWOARGS; break;
|
case P('A','p'): TWOARGS; break;
|
||||||
|
case P('C','a'): TWOARGS; break;
|
||||||
default:
|
default:
|
||||||
bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
|
bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ function fifteen()
|
||||||
function paths()
|
function paths()
|
||||||
bgpmask p;
|
bgpmask p;
|
||||||
bgppath p2;
|
bgppath p2;
|
||||||
|
clist l;
|
||||||
{
|
{
|
||||||
p = / 4 3 2 1 /;
|
p = / 4 3 2 1 /;
|
||||||
print "Testing path masks: ", p;
|
print "Testing path masks: ", p;
|
||||||
|
@ -46,6 +47,10 @@ bgppath p2;
|
||||||
print "Should be false: ", p2 ~ p;
|
print "Should be false: ", p2 ~ p;
|
||||||
print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /;
|
print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /;
|
||||||
print "5 = ", p2.len;
|
print "5 = ", p2.len;
|
||||||
|
|
||||||
|
l = - empty -;
|
||||||
|
l = add( l, (1,2) );
|
||||||
|
print "Community list ", l;
|
||||||
}
|
}
|
||||||
|
|
||||||
function startup()
|
function startup()
|
||||||
|
|
43
nest/a-set.c
43
nest/a-set.c
|
@ -38,3 +38,46 @@ int_set_format(struct adata *set, byte *buf, unsigned int size)
|
||||||
}
|
}
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct adata *
|
||||||
|
int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
||||||
|
{
|
||||||
|
struct adata *res = lp_alloc(pool, list->length + sizeof(struct adata) + 4);
|
||||||
|
res->length = list->length+4;
|
||||||
|
* (u32 *) res->data = val;
|
||||||
|
memcpy((char *) res->data + 4, list->data, list->length);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
int_set_contains(struct adata *list, u32 val)
|
||||||
|
{
|
||||||
|
u32 *l = &(list->data);
|
||||||
|
int i;
|
||||||
|
for (i=0; i<list->length/4; i++)
|
||||||
|
if (*l++ == val)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct adata *
|
||||||
|
int_set_del(struct linpool *pool, struct adata *list, u32 val)
|
||||||
|
{
|
||||||
|
struct adata *res;
|
||||||
|
u32 *l, *k;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!int_set_contains(list, val))
|
||||||
|
return list;
|
||||||
|
|
||||||
|
res = lp_alloc(pool, list->length + sizeof(struct adata) - 4);
|
||||||
|
res->length = list->length-4;
|
||||||
|
|
||||||
|
l = &(list->data);
|
||||||
|
k = &(res->data);
|
||||||
|
for (i=0; i<list->length/4; i++)
|
||||||
|
if (l[i] != val)
|
||||||
|
*k++ = l[i];
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -29,5 +29,9 @@ int as_path_match(struct adata *path, struct f_path_mask *mask);
|
||||||
/* a-set.c */
|
/* a-set.c */
|
||||||
|
|
||||||
void int_set_format(struct adata *set, byte *buf, unsigned int size);
|
void int_set_format(struct adata *set, byte *buf, unsigned int size);
|
||||||
|
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
|
||||||
|
int int_set_contains(struct adata *list, u32 val);
|
||||||
|
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue