]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filters: permit variables of prefix types, cleanup around
authorPavel Machek <pavel@ucw.cz>
Tue, 12 Oct 1999 06:27:42 +0000 (06:27 +0000)
committerPavel Machek <pavel@ucw.cz>
Tue, 12 Oct 1999 06:27:42 +0000 (06:27 +0000)
variables. TODO list added, hopefully complete. Use new features of
filters in bird.conf

bird.conf
filter/config.Y
filter/filter.c
filter/filter.h

index 476ccf308f9a91270b5d7127d71d094438b466cd..b1220c32341ac6db275191fb2ae6abb1e8eafe46 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -13,7 +13,7 @@ function callme (int arg1; int arg2;)
        print "Function callme called arguments " arg1 " and " arg2;
 
        case arg1 {
-       2: { print "dva"; print "jeste jednou dva"; }
+       2: print "dva"; print "jeste jednou dva";
        [ 3 .. 5 ]: print "tri az pet";
        else: print "neco jineho";
        }       
@@ -22,37 +22,30 @@ function callme (int arg1; int arg2;)
 function startup () 
 int i;
 prefix px;
-
 { 
-       print "Bird filter language: selftesting...";
+       print "Testing filter language:";
        i = 4; 
        i = 1230 + i; 
-       print "Testing arithmetics: 1234 = " i;
-       if i = 4 then { print "*** FAIL: if 0"; quitbird; } else print "test 1 passed";
-       if 1234 = i then print "test 2 passed"; else { print "*** FAIL: if 1 else"; }
-       if 1 <= 1 then print "test 3 passed"; else { print "*** FAIL: test 3"; }
-       if 1234 < 1234 then { print "*** FAIL: test 4"; quitbird; } else print "test 4 passed";
-
-       print "Testing IP addresses: 1.2.3.4 = " 1.2.3.4;
-       print "Testing sets of ints = " [ 1, 2, 3 ];
-       print "Testing sets of ints = " [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ];
-       print "Testing sets of IPs = " [ 1.2.3.4, 2.3.4.5, 3.4.5.6 ];
-       print "Sets: true = " 1 ~ [ 1, 2, 3 ];
-       print "      false = " 1 ~ [ 2, 3, 4 ];
-       print "a..b: true = " 5 ~ [ 4 .. 7 ];
-       print "      false = " 5 ~ [ 2, 3, 4, 7..11 ];
-       print "IPsets: true = " 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ];
-       print "        false = " 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ];
-
-       print "Testing prefixes: 1.2.3.4/18 = " 1.2.3.4/18;
+       print "  arithmetics: 1234 = " i;
+       printn "  if statements ";
+       if i = 4 then { print "*** FAIL: if 0"; quitbird; } else printn ".";
+       if 1234 = i then printn "."; else { print "*** FAIL: if 1 else"; }
+       if 1 <= 1 then printn "."; else { print "*** FAIL: test 3"; }
+       if 1234 < 1234 then { print "*** FAIL: test 4"; quitbird; } else print "ok";
+
+       print "  data types; must be true: " 1.2.3.4 = 1.2.3.4 "," 1 ~ [1,2,3] "," 5 ~ [1..20] "," 2 ~ [ 1, 2, 3 ] "," 5 ~ [ 4 .. 7 ] "," 1.2.3.4 ~ [ 1.2.3.3..1.2.3.5 ];
+       print "  data types: must be false: " 1 ~ [ 2, 3, 4 ] "," 5 ~ [ 2, 3, 4, 7..11 ] "," 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ] "," (1,2) > (2,2) "," (1,1) > (1,1);
+
+       px = 1.2.3.4/18;
+       print "Testing prefixes: 1.2.3.4/18 = " px;
        print "Testing pairs: (1,2) = " (1,2);
 
        print "Testing functions...";
-       callme ( 1, 2, );
-       callme ( 2, 2, );
-       callme ( 3, 2, );
-       callme ( 4, 2, );
-       callme ( 7, 2, );
+       callme ( 1, 2 );
+       callme ( 2, 2 );
+       callme ( 3, 2 );
+       callme ( 4, 2 );
+       callme ( 7, 2 );
 
        print "done";
        quitbird;
index 9d0cc7474ef298afe19e39d712ce424be9e7a872..93854836a019cc799cc6c57e821242cc5f8e86cc 100644 (file)
@@ -5,16 +5,13 @@
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  *
-       FIXME: prefix variables, make prefix.ip and prefix.length work
        FIXME: define keyword
-       FIXME: case without { }'s
-       FIXME: allow px+, px- px^pair in prefix sets
+       FIXME: make px+, px- px^pair work in prefix sets
        FIXME: create ip.mask(x) function
        FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
        FIXME: create community lists
        FIXME: access to dynamic attributes
-       FIXME: do not allow function call by callme(1,2,)
-       FIXME: pairs of integers: define compare
+       FIXME: make case faster
  */
 
 CF_HDR
@@ -29,12 +26,12 @@ CF_HDR
 
 CF_DECLS
 
-CF_KEYWORDS(FUNCTION, PRINT, CONST,
+CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
        ACCEPT, REJECT, ERROR, QUITBIRD,
        INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
        IF, THEN, ELSE, CASE,
        TRUE, FALSE,
-       RTA, FROM, GW, NET,
+       RTA, FROM, GW, NET, MASK,
        LEN,
        IMPOSSIBLE,
        FILTER
@@ -42,9 +39,9 @@ CF_KEYWORDS(FUNCTION, PRINT, CONST,
 
 %type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list switch_body
 %type <f> filter filter_body
-%type <i> type break_command
+%type <i> type break_command pair
 %type <e> set_item set_items
-%type <v> set_atom
+%type <v> set_atom prefix prefix_s ipa
 %type <s> decls function_params 
 
 CF_GRAMMAR
@@ -80,6 +77,12 @@ decls: /* EMPTY */ { $$ = NULL; }
      cf_define_symbol($2, SYM_VARIABLE | $1, NULL);
      printf( "New variable %s type %x\n", $2->name, $1 );
      $2->aux = $4;
+     {
+       struct f_val * val; 
+       val = cfg_alloc(sizeof(struct f_val)); 
+       val->type = $1; 
+       $2->aux2 = val;
+     }
      $$=$2;
    }
  ;
@@ -146,10 +149,36 @@ block:
    }
  ;
 
+/*
+ * Simple types, their bison value is int
+ */
+pair:
+   '(' NUM ',' NUM ')' { $$ = $2 << 16 | $4; }
+ ;
+
+/*
+ * Complex types, their bison value is struct f_val
+ */
+prefix_s:
+   IPA '/' NUM { $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3; printf( "ook, we have prefix here\n" ); }
+ ;
+
+prefix:
+   prefix_s { $$ = $1; }
+ | prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
+ | prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
+/* | prefix_s '{' NUM ',' NUM '}' How should this be done? */
+ ;
+
+ipa:
+   IPA  { $$.type = T_IP; $$.val.ip = $1; }
+ ;
+
 set_atom:
-   NUM { $$.type = T_INT; $$.val.i = $1; }
- | IPA { $$.type = T_IP; $$.val.ip = $1; }
+   NUM  { $$.type = T_INT; $$.val.i = $1; }
+ | pair { $$.type = T_PAIR; $$.val.i = $1; }
+ | ipa  { $$ = $1; }
+ | prefix { $$ = $1; }
  ; 
 
 set_item:
@@ -162,15 +191,16 @@ set_items:
  | set_items ',' set_item { $$ = $3; $$->left = $1; }
  ;
 
+
 constant:
    CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $3; }
  | NUM    { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT;  $$->a2.i = $1; }
  | TRUE   { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 1;  }
  | FALSE  { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_BOOL; $$->a2.i = 0;  }
  | TEXT   { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_STRING; $$->a2.p = $1; }
- | '(' NUM ',' NUM ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_PAIR;  $$->a2.i = $2 << 16 | $4; }
- | IPA   { struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; val->type = T_IP; val->val.ip = $1; }
- | IPA '/' NUM { struct f_val * val; val = cfg_alloc(sizeof(struct f_val)); $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; val->type = T_PREFIX; val->val.px.ip = $1; val->val.px.len = $3; printf( "ook, we have prefix here\n" ); }
+ | pair   { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_PAIR;  $$->a2.i = $1; }
+ | ipa    { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
+ | prefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
  | '[' set_items ']' { printf( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_SET; $$->a2.p = build_tree($2); printf( "ook\n" ); }
  ;
 
@@ -188,9 +218,11 @@ term:
      $$ = f_new_inst();
      switch ($1->class) {
        case SYM_VARIABLE | T_INT:
-        $$->code = 'i';
-         $$->a1.i = T_INT;
-        $$->a2.p = &($1->aux);
+       case SYM_VARIABLE | T_PAIR:
+       case SYM_VARIABLE | T_PREFIX:
+       case SYM_VARIABLE | T_IP:
+        $$->code = 'C';
+        $$->a1.p = $1->aux2;
         break;
        default:
         cf_error("Can not use this class of symbol as variable." );
@@ -204,6 +236,7 @@ term:
 
  | term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_IP; }
  | term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_INT; }
+ | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = 'iM'; $$->a1.p = $1; $$->a2.p = $5; }
  ;
 
 break_command:
@@ -212,6 +245,7 @@ break_command:
  | REJECT { $$ = F_REJECT }
  | ERROR { $$ = F_ERROR }
  | PRINT { $$ = F_NOP }
+ | PRINTN { $$ = F_NONL }
  ;
 
 ifthen:
@@ -236,7 +270,13 @@ print_list: /* EMPTY */ { $$ = NULL; }
    }
  ;
 
-var_list: /* EMPTY */ { $$ = NULL; }
+var_list: term { 
+     $$ = f_new_inst();
+     $$->code = 's';
+     $$->a1.p = NULL;
+     $$->a2.p = $1;
+     $$->next = NULL;
+   }
  | term ',' var_list {
      $$ = f_new_inst();
      $$->code = 's';
@@ -246,15 +286,16 @@ var_list: /* EMPTY */ { $$ = NULL; }
    }
  ;
 
+/* 2 shift/reduce conflicts here. Curable by replacing cmds with block which breaks syntax */
 switch_body: /* EMPTY */ { $$ = NULL; }
- | term ':' block switch_body {
+ | term ':' cmds switch_body {
      $$ = f_new_inst();
      $$->code = 'of';
      $$->a1.p = $1;
      $$->a2.p = $3;
      $$->next = $4;
    }
- | ELSE ':' block {
+ | ELSE ':' cmds {
      $$ = f_new_inst();
      $$->code = 'el';
      $$->a1.p = NULL;
index d317fcc0fe6d8d07753bab64ea821c740fe3dd96..f6b2d4beeeb10371daaa08d6f8a12c7187c69f1c 100644 (file)
@@ -58,6 +58,7 @@ val_compare(struct f_val v1, struct f_val v2)
     return CMP_ERROR;
   switch (v1.type) {
   case T_INT: 
+  case T_PAIR:
     if (v1.val.i == v2.val.i) return 0;
     if (v1.val.i < v2.val.i) return -1;
     return 1;
@@ -209,31 +210,32 @@ interpret(struct f_inst *what)
       runtime( "~ applied on unknown type pair" );
     break;
 
-  /* Set to consant, a1 = type, a2 = value */
+  /* Set to indirect value, a1 = variable, a2 = value */
   case 's':
     ARG(v2, a2.p);
     sym = what->a1.p;
     switch (res.type = v2.type) {
     case T_VOID: runtime( "Can not assign void values" );
     case T_INT: 
-      if (sym->class != (SYM_VARIABLE | T_INT))
+    case T_IP: 
+    case T_PREFIX: 
+    case T_PAIR: 
+      if (sym->class != (SYM_VARIABLE | v2.type))
        runtime( "Variable of bad type" );
-      sym->aux = v2.val.i
+      * (struct f_val *) sym->aux2 = v2
       break;
+    default:
+      bug( "Set to invalid type\n" );
     }
     break;
 
-  case 'c':
+  case 'c':    /* integer (or simple type) constant */
     res.type = what->a1.i;
-    res.val.i = (int) what->a2.p;
+    res.val.i = what->a2.i;
     break;
   case 'C':
     res = * ((struct f_val *) what->a1.p);
     break;
-  case 'i':
-    res.type = what->a1.i;
-    res.val.i = * ((int *) what->a2.p);
-    break;
   case 'p':
     ONEARG;
     val_print(v1);
@@ -253,7 +255,8 @@ interpret(struct f_inst *what)
     break;
   case 'p,':
     ONEARG;
-    printf( "\n" );
+    if (what->a2.i != F_NONL)
+      printf( "\n" );
 
     switch (what->a2.i) {
     case F_QUITBIRD:
@@ -265,6 +268,7 @@ interpret(struct f_inst *what)
       res.type = T_RETURN;
       res.val.i = what->a1.i;
       break;
+    case F_NONL:
     case F_NOP:
       break;
     default:
@@ -309,6 +313,10 @@ interpret(struct f_inst *what)
     ONEARG;
     interpret_switch(what->a2.p, v1);
     break;
+  case 'iM': /* IP.MASK(val) */
+    TWOARGS_C;
+    bug( "Should implement ip.mask\n" );
+    break;
   default:
     bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
   }
index f32a98eb1392254dd6f7a52d4991c2a5a78d69dd..ac7162ec82580b8d4e8be43c005d6df75125c0dc 100644 (file)
@@ -31,6 +31,11 @@ struct f_inst {              /* Instruction */
 struct prefix {
   ip_addr ip;
   int len;
+#define LEN_MASK 0xff
+#define LEN_PLUS  0x10000 
+#define LEN_MINUS 0x20000
+#define LEN_RANGE 0x40000
+  /* If range then prefix must be in range (len >> 8 & 0xff, len & 0xff) */
 };
 
 struct f_val {
@@ -66,11 +71,12 @@ int val_compare(struct f_val v1, struct f_val v2);
 void val_print(struct f_val v);
 
 #define F_NOP 0
-#define F_ACCEPT 1     /* Need to preserve ordering: accepts < rejects! */
-#define F_MODIFY 2     /* FIXME: Introduce modification flags instead? */
-#define F_REJECT 3
-#define F_ERROR 4
-#define F_QUITBIRD 5
+#define F_NONL 1
+#define F_ACCEPT 2     /* Need to preserve ordering: accepts < rejects! */
+#define F_MODIFY 3     /* FIXME: Introduce modification flags instead? */
+#define F_REJECT 4
+#define F_ERROR 5
+#define F_QUITBIRD 6
 
 #define FILTER_ACCEPT NULL
 #define FILTER_REJECT ((void *) 1)
@@ -101,4 +107,6 @@ struct f_tree {
   void *data;
 };
 
+#define NEW_F_VAL struct f_val * val; val = cfg_alloc(sizeof(struct f_val));
+
 #endif