Allow input and output filters (only accept/reject style as we didn't define
modifying filters yet) to be attached to protocol instances.
This commit is contained in:
parent
e0f2e42f4f
commit
529c414953
5 changed files with 42 additions and 4 deletions
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
#define xyzzy = 120+10
|
#define xyzzy = 120+10
|
||||||
|
|
||||||
|
#filter sink { reject; }
|
||||||
|
#filter okay { accept; }
|
||||||
|
|
||||||
#protocol rip MyRIP_test {
|
#protocol rip MyRIP_test {
|
||||||
# preference xyzzy
|
# preference xyzzy
|
||||||
# debug all
|
# debug all
|
||||||
|
@ -25,6 +28,8 @@ protocol kernel {
|
||||||
scan time 10 # Scan kernel tables every 10 seconds
|
scan time 10 # Scan kernel tables every 10 seconds
|
||||||
route scan time 20 # But routes only every 20 seconds
|
route scan time 20 # But routes only every 20 seconds
|
||||||
# async off # Netlink: Disable asynchronous events
|
# async off # Netlink: Disable asynchronous events
|
||||||
|
# input filter sink
|
||||||
|
# output filter okay
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol static {
|
protocol static {
|
||||||
|
|
|
@ -17,7 +17,7 @@ void rt_dev_add_iface(char *);
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DEVICE)
|
CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DEVICE)
|
||||||
CF_KEYWORDS(INTERFACE)
|
CF_KEYWORDS(INTERFACE, INPUT, OUTPUT, FILTER)
|
||||||
|
|
||||||
%type <i> idval
|
%type <i> idval
|
||||||
|
|
||||||
|
@ -67,6 +67,8 @@ proto_item:
|
||||||
| DEBUG expr { this_proto->debug = $2; }
|
| DEBUG expr { this_proto->debug = $2; }
|
||||||
| DEBUG ALL { this_proto->debug = ~0; }
|
| DEBUG ALL { this_proto->debug = ~0; }
|
||||||
| DEBUG OFF { 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 */
|
/* Device protocol */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
#include "nest/iface.h"
|
#include "nest/iface.h"
|
||||||
|
#include "filter/filter.h"
|
||||||
|
|
||||||
static pool *proto_pool;
|
static pool *proto_pool;
|
||||||
|
|
||||||
|
@ -85,6 +86,8 @@ proto_new(struct proto_config *c, unsigned size)
|
||||||
p->preference = c->preference;
|
p->preference = c->preference;
|
||||||
p->disabled = c->disabled;
|
p->disabled = c->disabled;
|
||||||
p->proto = pr;
|
p->proto = pr;
|
||||||
|
p->in_filter = c->in_filter;
|
||||||
|
p->out_filter = c->out_filter;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +245,10 @@ protos_dump_all(void)
|
||||||
{
|
{
|
||||||
debug(" protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority,
|
debug(" protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority,
|
||||||
p_states[p->proto_state], c_states[p->core_state]);
|
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)
|
if (p->disabled)
|
||||||
debug("\tDISABLED\n");
|
debug("\tDISABLED\n");
|
||||||
else if (p->proto->dump)
|
else if (p->proto->dump)
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct proto_config {
|
||||||
struct protocol *proto; /* Protocol */
|
struct protocol *proto; /* Protocol */
|
||||||
char *name;
|
char *name;
|
||||||
unsigned debug, preference, disabled; /* Generic parameters */
|
unsigned debug, preference, disabled; /* Generic parameters */
|
||||||
|
struct filter *in_filter, *out_filter; /* Attached filters */
|
||||||
|
|
||||||
/* Protocol-specific data follow... */
|
/* Protocol-specific data follow... */
|
||||||
};
|
};
|
||||||
|
@ -97,7 +98,9 @@ struct proto {
|
||||||
void (*rte_insert)(struct network *, struct rte *);
|
void (*rte_insert)(struct network *, struct rte *);
|
||||||
void (*rte_remove)(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? */
|
/* Connection to routing tables? */
|
||||||
|
|
||||||
/* Hic sunt protocol-specific data */
|
/* Hic sunt protocol-specific data */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "nest/protocol.h"
|
#include "nest/protocol.h"
|
||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "lib/event.h"
|
#include "lib/event.h"
|
||||||
|
#include "filter/filter.h"
|
||||||
|
|
||||||
rtable master_table;
|
rtable master_table;
|
||||||
static slab *rte_slab;
|
static slab *rte_slab;
|
||||||
|
@ -115,6 +116,20 @@ rte_better(rte *new, rte *old)
|
||||||
return 0;
|
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
|
void
|
||||||
rte_announce(net *net, rte *new, rte *old)
|
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);
|
ASSERT(p->core_state == FS_HAPPY);
|
||||||
if (p->rt_notify)
|
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;
|
net *n = (net *) fn;
|
||||||
rte *e;
|
rte *e;
|
||||||
for(e=n->routes; e; e=e->next)
|
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;
|
FIB_WALK_END;
|
||||||
t = t->sibling;
|
t = t->sibling;
|
||||||
|
@ -172,6 +187,12 @@ rte_update(net *net, struct proto *p, rte *new)
|
||||||
rte *old = NULL;
|
rte *old = NULL;
|
||||||
rte **k, *r, *s;
|
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 */
|
if (new && !(new->attrs->aflags & RTAF_CACHED)) /* Need to copy attributes */
|
||||||
new->attrs = rta_lookup(new->attrs);
|
new->attrs = rta_lookup(new->attrs);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue