]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
accept & reject should now work
authorPavel Machek <pavel@ucw.cz>
Wed, 17 Mar 1999 10:19:07 +0000 (10:19 +0000)
committerPavel Machek <pavel@ucw.cz>
Wed, 17 Mar 1999 10:19:07 +0000 (10:19 +0000)
filter/config.Y
filter/f-util.c
filter/filter.h

index 103acd8ba8d10e4aa03196864a60d11367441648..3577b196b2ed7b13da42004197a6a9d17b9edd55 100644 (file)
@@ -19,7 +19,8 @@ CF_HDR
 
 CF_DECLS
 
-CF_KEYWORDS(FUNCTION, FILTER, PRINTDEBUG, INT, PRINT, CONST, VAR, PUTS, DIE, IF)
+CF_KEYWORDS(FUNCTION, FILTER, PRINTDEBUG, INT, PRINT, CONST, VAR, PUTS, IF, 
+       ACCEPT, REJECT, ERROR, QUITBIRD)
 
 %type <x> term
 %type <x> block
@@ -30,11 +31,12 @@ CF_GRAMMAR
 CF_ADDTO(conf, function)
 function:
    FUNCTION SYM '(' ')' '{' cmds '}' { 
-     extern struct f_inst *last_func;
+     extern struct f_inst *autoexec_func;
      if ($2->class != SYM_VOID) cf_error("Symbol already defined" );
      $2->class = SYM_FUNCTION;
      $2->def = $6;
-     last_func = $6;
+     if (!strcasecmp($2->name, "autoexec"))
+       autoexec_func = $6;
      printf("Hmm, we've got one function here\n"); 
    }
  ;
@@ -150,9 +152,25 @@ term:
      $$->code = 'd';
      $$->arg1 = $3;
    }
- | DIE {
+ | QUITBIRD {
      $$ = f_new_inst();
      $$->code = '!';
+     (int) $$->arg1 = F_QUITBIRD;
+   }
+ | ACCEPT {
+     $$ = f_new_inst();
+     $$->code = '!';
+     (int) $$->arg1 = F_ACCEPT;
+   }
+ | REJECT {
+     $$ = f_new_inst();
+     $$->code = '!';
+     (int) $$->arg1 = F_REJECT;
+   }
+ | ERROR {
+     $$ = f_new_inst();
+     $$->code = '!';
+     (int) $$->arg1 = F_ERROR;
    }
  | PRINTDEBUG {
      $$ = f_new_inst();
index ba748041a31e5010a7c64e7a6e0c011c4d7bfb76..47c9144c41056b7e19267625caf5122fd1c04d9c 100644 (file)
@@ -10,6 +10,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/signal.h>
+#include <setjmp.h>
 
 #include "nest/bird.h"
 #include "lib/lists.h"
 #include "conf/conf.h"
 #include "filter/filter.h"
 
-struct f_inst *last_func = NULL;
+struct f_inst *autoexec_func = NULL;
 
-#define runtime die
+#define runtime(x) do { \
+    log( L_ERR, x ); \
+    res.type = T_RETURN; \
+    res.val.i = F_ERROR; \
+    return res; \
+  } while(0)
+
+#define ARG(x,y) \
+       x = interpret(what->y); \
+       if (x.type == T_RETURN) \
+               return x;
+
+#define ONEARG ARG(v1, arg1)
+#define TWOARGS ARG(v1, arg1) \
+               ARG(v2, arg2)
 
 static struct f_val
 interpret(struct f_inst *what)
@@ -37,12 +52,10 @@ interpret(struct f_inst *what)
 
   switch(what->code) {
   case ',':
-    interpret(what->arg1);
-    interpret(what->arg2);
+    TWOARGS;
     break;
   case '+':
-    v1 = interpret(what->arg1);
-    v2 = interpret(what->arg2);
+    TWOARGS;
     if (v1.type != v2.type)
       runtime( "Can not operate with values of incompatible types" );
 
@@ -53,14 +66,14 @@ interpret(struct f_inst *what)
     }
     break;
   case '=':
-    v1 = interpret(what->arg2);
+    ARG(v2, arg2);
     sym = what->arg1;
-    switch (res.type = v1.type) {
+    switch (res.type = v2.type) {
     case T_VOID: runtime( "Can not assign void values" );
     case T_INT: 
       if (sym->class != SYM_VARIABLE_INT)
        runtime( "Variable of bad type" );
-      sym->aux = v1.val.i; 
+      sym->aux = v2.val.i; 
       break;
     }
     break;
@@ -73,7 +86,7 @@ interpret(struct f_inst *what)
     res.val.i = * ((int *) what->arg1);
     break;
   case 'p':
-    v1 = interpret(what->arg1);
+    ONEARG;
     printf( "Printing: " );
     switch (v1.type) {
     case T_VOID: printf( "(void)" ); break;
@@ -83,11 +96,12 @@ interpret(struct f_inst *what)
     printf( "\n" );
     break;
   case '?':
-    v1 = interpret(what->arg1);
+    ONEARG;
     if (v1.type != T_INT)
       runtime( "If requires integer expression" );
-    if (v1.val.i)
-      res = interpret(what->arg2);
+    if (v1.val.i) {
+      ARG(res,arg2);
+    }
     break;
   case 'D':
     printf( "DEBUGGING PRINT\n" );
@@ -96,28 +110,31 @@ interpret(struct f_inst *what)
     printf( "No operation\n" );
     break;
   case 'd':
-    printf( "Puts: %s\n", what->arg1 );
+    printf( "Puts: %s\n", (char *) what->arg1 );
     break;
   case '!':
-    die( "Filter asked me to die" );
+    switch ((int) what->arg1) {
+    case F_QUITBIRD:
+      die( "Filter asked me to die" );
+    case F_ACCEPT:
+      /* Should take care about turning ACCEPT into MODIFY */
+    case F_ERROR:
+    case F_REJECT:
+      res.type = T_RETURN;
+      res.val = (int) what->arg1;
+      break;
+    default:
+      bug( "unknown return type: can not happen");
+    }
+    break;
   default:
-    die( "Unknown insruction %d(%c)", what->code, what->code & 0xff);
+    bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
   }
   if (what->next)
     return interpret(what->next);
   return res;
 }
 
-void
-filters_postconfig(void)
-{
-  if (!last_func)
-    printf( "No function defined\n" );
-  else {
-    interpret(last_func);
-  }
-} 
-
 struct f_inst *
 f_new_inst(void)
 {
@@ -132,10 +149,20 @@ int
 f_run(struct symbol *filter, struct rte *rtein, struct rte **rteout)
 {
   struct f_inst *inst;
+  struct f_val res;
   debug( "Running filter `%s'...", filter->name );
 
   inst = filter->def;
-  interpret(inst);
-  debug( "done\n" );
-  return F_ACCEPT;
+  res = interpret(inst);
+  if (res.type != T_RETURN)
+    return F_ERROR;
+  debug( "done (%d)\n", res.val.i );
+  return res.val.i;
 }
+
+void
+filters_postconfig(void)
+{
+  if (autoexec_func)
+    interpret(autoexec_func);
+} 
index e0f4723034fc5f2f5cbaf0e52cf0580e6b97774d..8ea6b94045e4f791e74a196337866799b7b287ac 100644 (file)
@@ -30,9 +30,14 @@ struct f_inst *f_new_inst(void);
 #define F_ACCEPT 1
 #define F_REJECT 2
 #define F_MODIFY 3
+#define F_ERROR 4
+#define F_QUITBIRD 5
 
 #define T_VOID 0
-#define T_INT 1
-#define T_PX 2
+#define T_RETURN 1
+#define T_INT 10
+#define T_PX 11                /* prefix */
+#define T_INTLIST 12
+
 
 #endif