]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements C.len operator for clist and eclist types.
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Oct 2013 12:57:29 +0000 (14:57 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Oct 2013 12:57:29 +0000 (14:57 +0200)
Thanks to Sergey Popovich for the original patch.

doc/bird.sgml
filter/filter.c
filter/test.conf
nest/attrs.h

index f43eb4bf4d7b2edfe9bf1bb060443fbb304a5629..050acf33a9786914eff371b8e1b9cab8dca74a6e 100644 (file)
@@ -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,
index 50e3f403ae26b3f9b2edc71265cf56ed54e78694..b01933f73dd37c88d57f1e4310d2294c39920201 100644 (file)
@@ -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 ... */
index b8f706cbaf69e1eb6a08583be7c4c44bbe4b7d9c..03b09c30969b68c2cb28f5015a4b3b82fd85967a 100644 (file)
@@ -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));
index 44a23e18965927ddea09331b1d9387e65fe4dcf1..a0dae221953d9d8cd8f8eba08d7d36485c30eb3e 100644 (file)
@@ -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; }