Commit 529c4149 authored by Martin Mares's avatar Martin Mares
Browse files

Allow input and output filters (only accept/reject style as we didn't define

modifying filters yet) to be attached to protocol instances.
parent e0f2e42f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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 {
+3 −1
Original line number Diff line number Diff line
@@ -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 */
+7 −0
Original line number Diff line number Diff line
@@ -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)
+4 −1
Original line number Diff line number Diff line
@@ -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 */
+23 −2
Original line number Diff line number Diff line
@@ -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);