]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filters now do not allow function (int arg; int arg2; ).
authorPavel Machek <pavel@ucw.cz>
Wed, 3 Nov 1999 22:23:01 +0000 (22:23 +0000)
committerPavel Machek <pavel@ucw.cz>
Wed, 3 Nov 1999 22:23:01 +0000 (22:23 +0000)
bird.conf
filter/config.Y
filter/filter.c
filter/filter.h

index 3b8f6a7beb8019adc53f5a7e703b037431cde395..09290def67b9a81bf6f9745db05f9edf902328f4 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -8,7 +8,9 @@ router id 62.168.0.1;
 
 define xyzzy = 120+10;
 
-function callme (int arg1; int arg2;)
+function callme ( int arg1; int arg2 )
+int local1;
+int local2;
 {
        print "Function callme called arguments " arg1 " and " arg2;
 
@@ -33,8 +35,8 @@ prefix px;
        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);
+       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 ] "," 1.2.3.4 ~ 1.2.3.4/8 "," 1.2.3.4/8 ~ 1.2.3.4/8 "," 1.2.3.4/8 ~ 1.2.3.4/8+ "," 1.2.3.4/16 ~ 1.2.3.4/8{ 15 , 16 };
+       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) "," 1.2.3.4/8 ~ 1.2.3.4/8- "," 1.2.3.4/17 ~ 1.2.3.4/8{ 15 , 16 };
 
        px = 1.2.3.4/18;
        print "Testing prefixes: 1.2.3.4/18 = " px;
@@ -60,6 +62,8 @@ int j;
 { 
        print "Heya, filtering route to " rta.net.ip " prefixlen " rta.net.len;
        print "This route was from " rta.from;
+       j = 7;
+       j = 17;
        accept;
 }
 
index d5a9dca960cc180ab0a55c634c37431bacd81d4a..d9f72fb50b3226eff78caf129ad6a9fc8408559c 100644 (file)
@@ -6,11 +6,11 @@
  *     Can be freely distributed and used under the terms of the GNU GPL.
  *
        FIXME: define keyword
-       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: local namespace for functions
  */
 
 CF_HDR
@@ -30,18 +30,18 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
        INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
        IF, THEN, ELSE, CASE,
        TRUE, FALSE,
-       RTA, FROM, GW, NET, MASK,
+       RTA, FROM, GW, NET, MASK, RIP_METRIC, RIP_TAG,
        LEN,
        IMPOSSIBLE,
        FILTER
        )
 
-%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list
+%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list var_listn
 %type <f> filter filter_body
 %type <i> type break_command pair
 %type <e> set_item set_items switch_body
 %type <v> set_atom prefix prefix_s ipa
-%type <s> decls function_params 
+%type <s> decls declsn one_decl function_params 
 
 CF_GRAMMAR
 
@@ -71,11 +71,11 @@ type:
        }
  ;
 
-decls: /* EMPTY */ { $$ = NULL; }
| type SYM ';' decls {
+one_decl:
  type SYM {
      cf_define_symbol($2, SYM_VARIABLE | $1, NULL);
      printf( "New variable %s type %x\n", $2->name, $1 );
-     $2->aux = $4;
+     $2->aux = NULL;
      {
        struct f_val * val; 
        val = cfg_alloc(sizeof(struct f_val)); 
@@ -86,6 +86,24 @@ decls: /* EMPTY */ { $$ = NULL; }
    }
  ;
 
+/* Decls with ';' at the end */
+decls: /* EMPTY */ { $$ = NULL; }
+ | one_decl ';' decls {
+     $$ = $1;
+     $$->aux = $3;
+   }
+ ;
+
+/* Declarations that have no ';' at the end.
+   Ouch, this is responsible for 13 or so shift/reduce conflicts. */
+declsn: one_decl { $$ = $1; }
+ | declsn ';' one_decl {
+     $$ = $3;
+     $$->aux = $1;
+   }
+ ;
+
+
 filter_body:
    function_body {
      struct filter *f = cfg_alloc(sizeof(struct filter));
@@ -104,7 +122,8 @@ filter:
  ;
 
 function_params:
-   '(' decls ')' { printf( "Have function parameters\n" ); $$=$2; }
+   '(' declsn ')' { printf( "Have function parameters\n" ); $$=$2; }
+ | '(' ')' { $$=NULL; }
  ;
 
 function_body:
@@ -166,11 +185,11 @@ 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? */
+ | prefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
  ;
 
 ipa:
-   IPA  { $$.type = T_IP; $$.val.ip = $1; }
+   IPA  { $$.type = T_IP; $$.val.px.ip = $1; }
  ;
 
 set_atom:
@@ -213,7 +232,8 @@ constant:
  | TEXT   { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_STRING; $$->a2.p = $1; }
  | 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; }
+          /* Replace with prefix_s to get rid of shift/reduce conflicts. */
+ | prefix  {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" ); }
  ;
 
@@ -245,7 +265,9 @@ term:
  | RTA '.' FROM { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, from); }
 
  | RTA '.' GW { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); }
- | RTA '.' NET  { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
+ | RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
+
+ | RTA '.' RIP_METRIC { $$ = f_new_inst(); $$->code = 'ea'; $$->a1.i = T_INT; $$->a2.i = EA_RIP_METRIC; }
 
  | 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; }
@@ -283,14 +305,14 @@ print_list: /* EMPTY */ { $$ = NULL; }
    }
  ;
 
-var_list: term { 
+var_listn: term { 
      $$ = f_new_inst();
      $$->code = 's';
      $$->a1.p = NULL;
      $$->a2.p = $1;
      $$->next = NULL;
    }
- | term ',' var_list {
+ | term ',' var_listn {
      $$ = f_new_inst();
      $$->code = 's';
      $$->a1.p = NULL;
@@ -299,6 +321,10 @@ var_list: term {
    }
  ;
 
+var_list: /* EMPTY */ { $$ = NULL; }
+ | var_listn { $$ = $1; }
+ ;
+
 cmd:
    ifthen { 
      $$ = $1;
index dc8235ed0a6b5dfb552d3ba420bdd2cd65585f1a..e913bf601e53496957810c75edfbeb8cae096e23 100644 (file)
@@ -5,8 +5,6 @@
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  *
- *     FIXME: local namespace for functions
- *
  *     Notice that pair is stored as integer: first << 16 | second
  */
 
@@ -70,16 +68,55 @@ val_compare(struct f_val v1, struct f_val v2)
     if (v1.val.i < v2.val.i) return -1;
     return 1;
   case T_IP:
-    return ipa_compare(v1.val.ip, v2.val.ip);
+  case T_PREFIX:
+    return ipa_compare(v1.val.px.ip, v2.val.px.ip);
   default: { printf( "Error comparing\n" ); return CMP_ERROR; }
   }
 }
 
+int 
+val_simple_in_range(struct f_val v1, struct f_val v2)
+{
+  if ((v1.type == T_IP) && (v2.type == T_PREFIX))
+    return !(ipa_compare(ipa_and(v2.val.px.ip, ipa_mkmask(v2.val.px.len)), ipa_and(v1.val.px.ip, ipa_mkmask(v2.val.px.len))));
+
+  if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX)) {
+    ip_addr mask;
+    if (v1.val.px.len & (LEN_PLUS | LEN_MINUS | LEN_RANGE))
+      return CMP_ERROR;
+    mask = ipa_mkmask( v2.val.px.len & LEN_MASK );
+    if (ipa_compare(ipa_and(v2.val.px.ip, mask), ipa_and(v1.val.px.ip, mask)))
+      return 0;
+    /* FIXME: read rpsl or better ask mj: is it really like this? */
+    if ((v2.val.px.len & LEN_MINUS) && (v1.val.px.len <= (v2.val.px.len & LEN_MASK)))
+      return 0;
+    if ((v2.val.px.len & LEN_PLUS) && (v1.val.px.len < (v2.val.px.len & LEN_MASK)))
+      return 0;
+    if ((v2.val.px.len & LEN_RANGE) && ((v1.val.px.len < (0xff & (v2.val.px.len >> 16)))
+                                       || (v1.val.px.len > (0xff & (v2.val.px.len >> 8)))))
+      return 0;
+    return 1;    
+  }
+  return CMP_ERROR;
+}
+
 int
 val_in_range(struct f_val v1, struct f_val v2)
 {
-  if (((v1.type == T_INT) || (v1.type == T_IP)) && (v2.type == T_SET))
-    return !! find_tree(v2.val.t, v1);
+  int res;
+
+  res = val_simple_in_range(v1, v2);
+
+  if (res != CMP_ERROR)
+    return res;
+
+  if (((v1.type == T_INT) || (v1.type == T_IP)) && (v2.type == T_SET)) {
+    struct f_tree *n;
+    n = find_tree(v2.val.t, v1);
+    if (!n)
+      return 0;
+    return !! (val_simple_in_range(v1, n->from));      /* We turn CMP_ERROR into compared ok, and that's fine */
+  }
   return CMP_ERROR;
 }
 
@@ -108,7 +145,7 @@ val_print(struct f_val v)
   case T_BOOL: PRINTF( v.val.i ? "TRUE" : "FALSE" ); break;
   case T_INT: PRINTF( "%d ", v.val.i ); break;
   case T_STRING: PRINTF( "%s", v.val.s ); break;
-  case T_IP: PRINTF( "%I", v.val.ip ); break;
+  case T_IP: PRINTF( "%I", v.val.px.ip ); break;
   case T_PREFIX: PRINTF( "%I/%d", v.val.px.ip, v.val.px.len ); break;
   case T_PAIR: PRINTF( "(%d,%d)", v.val.i >> 16, v.val.i & 0xffff ); break;
   case T_SET: tree_print( v.val.t ); PRINTF( "\n" ); break;
@@ -254,7 +291,7 @@ interpret(struct f_inst *what)
       res.type = what->a1.i;
       switch(res.type) {
       case T_IP:
-       res.val.ip = * (ip_addr *) ((char *) rta + what->a2.i);
+       res.val.px.ip = * (ip_addr *) ((char *) rta + what->a2.i);
        break;
       case T_PREFIX:   /* Warning: this works only for prefix of network */
        {
@@ -267,6 +304,9 @@ interpret(struct f_inst *what)
       }
     }
     break;
+  case 'ea':   /* Access to extended attributes [hmm, but we need it read/write, do we?] */
+    bug( "Implement me" );
+    break;
   case 'cp':   /* Convert prefix to ... */
     ONEARG;
     if (v1.type != T_PREFIX)
@@ -274,7 +314,7 @@ interpret(struct f_inst *what)
     res.type = what->a2.i;
     switch(res.type) {
     case T_INT:        res.val.i = v1.val.px.len; break;
-    case T_IP: res.val.ip = v1.val.px.ip; break;
+    case T_IP: res.val.px.ip = v1.val.px.ip; break;
     default: bug( "Unknown prefix to conversion\n" );
     }
     break;
index ac7162ec82580b8d4e8be43c005d6df75125c0dc..4cdf8f6b35778f528a3f853708ae6416bab7c77e 100644 (file)
@@ -32,17 +32,17 @@ 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) */
+#define LEN_PLUS  0x1000000
+#define LEN_MINUS 0x2000000
+#define LEN_RANGE 0x4000000
+  /* If range then prefix must be in range (len >> 16 & 0xff, len >> 8 & 0xff) */
 };
 
 struct f_val {
   int type;
   union {
     int i;
-    ip_addr ip;
+    /*    ip_addr ip; Folded into prefix */    
     struct prefix px;
     char *s;
     struct f_tree *t;