diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2013-10-02 14:57:29 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2013-10-02 14:57:29 +0200 |
commit | 7ccb36d3308ef57d340e663f0cabd24663f4f62a (patch) | |
tree | 131c95083d7e0f713241121d9c4a6116f71dcf78 | |
parent | 28a10f84cbc3635e59bff348cb1715859dfacade (diff) |
Implements C.len operator for clist and eclist types.
Thanks to Sergey Popovich for the original patch.
-rw-r--r-- | doc/bird.sgml | 2 | ||||
-rw-r--r-- | filter/filter.c | 4 | ||||
-rw-r--r-- | filter/test.conf | 5 | ||||
-rw-r--r-- | nest/attrs.h | 3 |
4 files changed, 11 insertions, 3 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index f43eb4bf..050acf33 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -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 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 <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, diff --git a/filter/filter.c b/filter/filter.c index 50e3f403..b01933f7 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -1067,7 +1067,9 @@ interpret(struct f_inst *what) switch(v1.type) { case T_PREFIX: res.val.i = v1.val.px.len; 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; case P('c','p'): /* Convert prefix to ... */ diff --git a/filter/test.conf b/filter/test.conf index b8f706cb..03b09c30 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -142,10 +142,10 @@ eclist el2; l = add( l, (3,5) ); l2 = filter( l, [(3,*)] ); 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, (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 false: ", l ~ [(*,3)], " ", l ~ [(*,(one+6))], " ", l ~ [(*, (one+one+one))]; l = delete( l, [(*,(one+onef(3)))] ); @@ -168,6 +168,7 @@ eclist el2; 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 el; + print "EC len: ", el.len; el = delete(el, (rt, 10, 20)); el = delete(el, (rt, 10, 30)); el = add(el, (unknown 2, ten, 1)); diff --git a/nest/attrs.h b/nest/attrs.h index 44a23e18..a0dae221 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -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) { 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) { return (u32 *) list->data; } |