]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Allow input and output filters (only accept/reject style as we didn't define
authorMartin Mares <mj@ucw.cz>
Wed, 17 Mar 1999 14:31:26 +0000 (14:31 +0000)
committerMartin Mares <mj@ucw.cz>
Wed, 17 Mar 1999 14:31:26 +0000 (14:31 +0000)
modifying filters yet) to be attached to protocol instances.

doc/bird.conf.example
nest/config.Y
nest/proto.c
nest/protocol.h
nest/rt-table.c

index 9f5907d4988e8779461787057c7e15d5084eff2a..1d8203dc82df03e0d0e812339e66c4e5d8fb369a 100644 (file)
@@ -8,6 +8,9 @@
 
 #define xyzzy = 120+10
 
+#filter sink { reject; }
+#filter okay { accept; }
+
 #protocol rip MyRIP_test {
 #      preference xyzzy
 #      debug all
@@ -25,6 +28,8 @@ protocol kernel {
        scan time 10            # Scan kernel tables every 10 seconds
        route scan time 20      # But routes only every 20 seconds
 #      async off               # Netlink: Disable asynchronous events
+#      input filter sink
+#      output filter okay
 }
 
 protocol static {
index a19cce63944ef24ea5735e17dbd52e2f6150c595..83001328f53bdd9514fd5cb3b64cbda8733f2d76 100644 (file)
@@ -17,7 +17,7 @@ void rt_dev_add_iface(char *);
 CF_DECLS
 
 CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DEVICE)
-CF_KEYWORDS(INTERFACE)
+CF_KEYWORDS(INTERFACE, INPUT, OUTPUT, FILTER)
 
 %type <i> idval
 
@@ -67,6 +67,8 @@ proto_item:
  | DEBUG expr { this_proto->debug = $2; }
  | DEBUG ALL { this_proto->debug = ~0; }
  | DEBUG OFF { this_proto->debug = 0; }
+ | INPUT FILTER filter { this_proto->in_filter = $3; }
+ | OUTPUT FILTER filter { this_proto->out_filter = $3; }
  ;
 
 /* Device protocol */
index 4df625ff486a28772f3774679acc7583c751b4f0..431c47dbdbeffcde8a8244a3bbb00fe533667ea0 100644 (file)
@@ -18,6 +18,7 @@
 #include "conf/conf.h"
 #include "nest/route.h"
 #include "nest/iface.h"
+#include "filter/filter.h"
 
 static pool *proto_pool;
 
@@ -85,6 +86,8 @@ proto_new(struct proto_config *c, unsigned size)
   p->preference = c->preference;
   p->disabled = c->disabled;
   p->proto = pr;
+  p->in_filter = c->in_filter;
+  p->out_filter = c->out_filter;
   return p;
 }
 
@@ -242,6 +245,10 @@ protos_dump_all(void)
     {
       debug("  protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority,
            p_states[p->proto_state], c_states[p->core_state]);
+      if (p->in_filter)
+       debug("\tInput filter: %s\n", p->in_filter->name);
+      if (p->out_filter)
+       debug("\tOutput filter: %s\n", p->out_filter->name);
       if (p->disabled)
        debug("\tDISABLED\n");
       else if (p->proto->dump)
index a168b41215ecbdb10d38859d70b36583046b200d..1e641a5f746cd5d5723401f59f768ee1b700724e 100644 (file)
@@ -70,6 +70,7 @@ struct proto_config {
   struct protocol *proto;              /* Protocol */
   char *name;
   unsigned debug, preference, disabled;        /* Generic parameters */
+  struct filter *in_filter, *out_filter; /* Attached filters */
 
   /* Protocol-specific data follow... */
 };
@@ -97,7 +98,9 @@ struct proto {
   void (*rte_insert)(struct network *, struct rte *);
   void (*rte_remove)(struct network *, struct rte *);
 
-  /* Input/output filters */
+  struct filter *in_filter;            /* Input filter */
+  struct filter *out_filter;           /* Output filter */
+
   /* Connection to routing tables? */
 
   /* Hic sunt protocol-specific data */
index 4da6807acc32a50fdb87f5d90b2a3d3763d62349..756141ce690398330e38d4e1ba64b1b2fc693507 100644 (file)
@@ -15,6 +15,7 @@
 #include "nest/protocol.h"
 #include "lib/resource.h"
 #include "lib/event.h"
+#include "filter/filter.h"
 
 rtable master_table;
 static slab *rte_slab;
@@ -115,6 +116,20 @@ rte_better(rte *new, rte *old)
   return 0;
 }
 
+static inline void
+do_rte_announce(struct proto *p, net *net, rte *new, rte *old)
+{
+  if (p->out_filter)
+    {
+      if (old && f_run(p->out_filter, old, NULL) != F_ACCEPT)
+       old = NULL;
+      if (new && f_run(p->out_filter, new, NULL) != F_ACCEPT)
+       new = NULL;
+    }
+  if (new || old)
+    p->rt_notify(p, net, new, old);
+}
+
 void
 rte_announce(net *net, rte *new, rte *old)
 {
@@ -124,7 +139,7 @@ rte_announce(net *net, rte *new, rte *old)
     {
       ASSERT(p->core_state == FS_HAPPY);
       if (p->rt_notify)
-       p->rt_notify(p, net, new, old);
+       do_rte_announce(p, net, new, old);
     }
 }
 
@@ -143,7 +158,7 @@ rt_feed_baby(struct proto *p)
          net *n = (net *) fn;
          rte *e;
          for(e=n->routes; e; e=e->next)
-           p->rt_notify(p, n, e, NULL);
+           do_rte_announce(p, n, e, NULL);
        }
       FIB_WALK_END;
       t = t->sibling;
@@ -172,6 +187,12 @@ rte_update(net *net, struct proto *p, rte *new)
   rte *old = NULL;
   rte **k, *r, *s;
 
+  if (new && p->in_filter && f_run(p->in_filter, new, NULL) != F_ACCEPT)
+    {
+      rte_free(new);
+      return;
+    }
+
   if (new && !(new->attrs->aflags & RTAF_CACHED)) /* Need to copy attributes */
     new->attrs = rta_lookup(new->attrs);