Implements C.len operator for clist and eclist types.
Thanks to Sergey Popovich for the original patch.
This commit is contained in:
parent
28a10f84cb
commit
7ccb36d330
4 changed files with 11 additions and 3 deletions
|
@ -1077,6 +1077,8 @@ incompatible with each other (that is to prevent you from shooting in the foot).
|
||||||
no literals of this type. There are three special operators on
|
no literals of this type. There are three special operators on
|
||||||
clists:
|
clists:
|
||||||
|
|
||||||
|
<cf><m/C/.len</cf> returns the length of clist <m/C/.
|
||||||
|
|
||||||
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist
|
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist
|
||||||
<m/C/ and returns the result. If item <m/P/ is already in
|
<m/C/ and returns the result. If item <m/P/ is already in
|
||||||
clist <m/C/, it does nothing. <m/P/ may also be a clist,
|
clist <m/C/, it does nothing. <m/P/ may also be a clist,
|
||||||
|
|
|
@ -1067,7 +1067,9 @@ interpret(struct f_inst *what)
|
||||||
switch(v1.type) {
|
switch(v1.type) {
|
||||||
case T_PREFIX: res.val.i = v1.val.px.len; break;
|
case T_PREFIX: res.val.i = v1.val.px.len; break;
|
||||||
case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break;
|
case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break;
|
||||||
default: runtime( "Prefix or path expected" );
|
case T_CLIST: res.val.i = int_set_get_size(v1.val.ad); break;
|
||||||
|
case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
|
||||||
|
default: runtime( "Prefix, path, clist or eclist expected" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P('c','p'): /* Convert prefix to ... */
|
case P('c','p'): /* Convert prefix to ... */
|
||||||
|
|
|
@ -142,10 +142,10 @@ eclist el2;
|
||||||
l = add( l, (3,5) );
|
l = add( l, (3,5) );
|
||||||
l2 = filter( l, [(3,*)] );
|
l2 = filter( l, [(3,*)] );
|
||||||
l = delete( l, [(3,2..4)] );
|
l = delete( l, [(3,2..4)] );
|
||||||
print "Community list (1,2) (3,1) (3,5) ", l;
|
print "Community list (1,2) (3,1) (3,5) ", l, " len: ", l.len;
|
||||||
l = add( l, (3,2) );
|
l = add( l, (3,2) );
|
||||||
l = add( l, (4,5) );
|
l = add( l, (4,5) );
|
||||||
print "Community list (1,2) (3,1) (3,2) (3,5) (4,5) ", l;
|
print "Community list (1,2) (3,1) (3,2) (3,5) (4,5) ", l, " len: ", l.len;
|
||||||
print "Should be true: ", l ~ [(*,2)], " ", l ~ [(*,5)], " ", l ~ [(*, one)];
|
print "Should be true: ", l ~ [(*,2)], " ", l ~ [(*,5)], " ", l ~ [(*, one)];
|
||||||
print "Should be false: ", l ~ [(*,3)], " ", l ~ [(*,(one+6))], " ", l ~ [(*, (one+one+one))];
|
print "Should be false: ", l ~ [(*,3)], " ", l ~ [(*,(one+6))], " ", l ~ [(*, (one+one+one))];
|
||||||
l = delete( l, [(*,(one+onef(3)))] );
|
l = delete( l, [(*,(one+onef(3)))] );
|
||||||
|
@ -168,6 +168,7 @@ eclist el2;
|
||||||
el = add(el, (ro, 11.21.31.41.mask(16), 200));
|
el = add(el, (ro, 11.21.31.41.mask(16), 200));
|
||||||
print "EC list (rt, 10, 20) (ro, 10.20.30.40, 100) (ro, 11.21.0.0, 200):";
|
print "EC list (rt, 10, 20) (ro, 10.20.30.40, 100) (ro, 11.21.0.0, 200):";
|
||||||
print el;
|
print el;
|
||||||
|
print "EC len: ", el.len;
|
||||||
el = delete(el, (rt, 10, 20));
|
el = delete(el, (rt, 10, 20));
|
||||||
el = delete(el, (rt, 10, 30));
|
el = delete(el, (rt, 10, 30));
|
||||||
el = add(el, (unknown 2, ten, 1));
|
el = add(el, (unknown 2, ten, 1));
|
||||||
|
|
|
@ -69,6 +69,9 @@ int as_path_match(struct adata *path, struct f_path_mask *mask);
|
||||||
static inline int int_set_get_size(struct adata *list)
|
static inline int int_set_get_size(struct adata *list)
|
||||||
{ return list->length / 4; }
|
{ return list->length / 4; }
|
||||||
|
|
||||||
|
static inline int ec_set_get_size(struct adata *list)
|
||||||
|
{ return list->length / 8; }
|
||||||
|
|
||||||
static inline u32 *int_set_get_data(struct adata *list)
|
static inline u32 *int_set_get_data(struct adata *list)
|
||||||
{ return (u32 *) list->data; }
|
{ return (u32 *) list->data; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue