summaryrefslogtreecommitdiff
path: root/proto/pipe
diff options
context:
space:
mode:
Diffstat (limited to 'proto/pipe')
-rw-r--r--proto/pipe/Makefile3
-rw-r--r--proto/pipe/config.Y6
-rw-r--r--proto/pipe/pipe.c39
-rw-r--r--proto/pipe/pipe.h1
4 files changed, 33 insertions, 16 deletions
diff --git a/proto/pipe/Makefile b/proto/pipe/Makefile
index 5093da98..ba66027f 100644
--- a/proto/pipe/Makefile
+++ b/proto/pipe/Makefile
@@ -2,5 +2,6 @@ src := pipe.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
+$(call proto-build,pipe_build)
-tests_objs := $(tests_objs) $(src-o-files) \ No newline at end of file
+tests_objs := $(tests_objs) $(src-o-files)
diff --git a/proto/pipe/config.Y b/proto/pipe/config.Y
index c869de9f..0990168e 100644
--- a/proto/pipe/config.Y
+++ b/proto/pipe/config.Y
@@ -41,6 +41,12 @@ pipe_proto:
pipe_proto_start '{'
| pipe_proto proto_item ';'
| pipe_proto channel_item_ ';'
+ | pipe_proto IMPORT IN net_any imexport ';' {
+ if (this_channel->net_type && ($4->type != this_channel->net_type))
+ cf_error("Incompatible export prefilter type");
+ PIPE_CFG->in_subprefix = $4;
+ this_channel->in_filter = $5;
+ }
| pipe_proto PEER TABLE rtable ';' { PIPE_CFG->peer = $4; }
| pipe_proto MAX GENERATION expr ';' {
if (($4 < 1) || ($4 > 254)) cf_error("Max generation must be in range 1..254, got %u", $4);
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index bbcd8f0d..8af6de81 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -35,7 +35,7 @@
#include "nest/bird.h"
#include "nest/iface.h"
#include "nest/protocol.h"
-#include "nest/route.h"
+#include "nest/rt.h"
#include "nest/cli.h"
#include "conf/conf.h"
#include "filter/filter.h"
@@ -58,18 +58,14 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, const net_addr *n, rte *
if (new)
{
- rta *a = alloca(rta_size(new->attrs));
- memcpy(a, new->attrs, rta_size(new->attrs));
-
- a->cached = 0;
- a->hostentry = NULL;
-
rte e0 = {
- .attrs = a,
+ .attrs = new->attrs,
.src = new->src,
.generation = new->generation + 1,
};
+ ea_unset_attr(&e0.attrs, 0, &ea_gen_hostentry);
+
rte_update(dst, n, &e0, new->src);
}
else
@@ -77,12 +73,12 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, const net_addr *n, rte *
}
static int
-pipe_preexport(struct channel *c, rte *e)
+pipe_preexport(struct channel *C, rte *e)
{
- struct pipe_proto *p = (void *) c->proto;
+ struct pipe_proto *p = (void *) C->proto;
/* Avoid direct loopbacks */
- if (e->sender == c->in_req.hook)
+ if (e->sender == C->in_req.hook)
return -1;
/* Indirection check */
@@ -90,8 +86,8 @@ pipe_preexport(struct channel *c, rte *e)
if (e->generation >= max_generation)
{
log_rl(&p->rl_gen, L_ERR "Route overpiped (%u hops of %u configured in %s) in table %s: %N %s/%u:%u",
- e->generation, max_generation, c->proto->name,
- c->table->name, e->net, e->src->proto->name, e->src->private_id, e->src->global_id);
+ e->generation, max_generation, C->proto->name,
+ C->table->name, e->net, e->src->proto->name, e->src->private_id, e->src->global_id);
return -1;
}
@@ -127,10 +123,16 @@ pipe_postconfig(struct proto_config *CF)
if (cc->table->addr_type != cf->peer->addr_type)
cf_error("Primary table and peer table must have the same type");
+ if (cc->out_subprefix && (cc->table->addr_type != cc->out_subprefix->type))
+ cf_error("Export subprefix must match table type");
+
+ if (cf->in_subprefix && (cc->table->addr_type != cf->in_subprefix->type))
+ cf_error("Import subprefix must match table type");
+
if (cc->rx_limit.action)
cf_error("Pipe protocol does not support receive limits");
- if (cc->in_keep_filtered)
+ if (cc->in_keep)
cf_error("Pipe protocol prohibits keeping filtered routes");
cc->debug = cf->c.debug;
@@ -146,6 +148,7 @@ pipe_configure_channels(struct pipe_proto *p, struct pipe_config *cf)
.channel = cc->channel,
.table = cc->table,
.out_filter = cc->out_filter,
+ .out_subprefix = cc->out_subprefix,
.in_limit = cc->in_limit,
.ra_mode = RA_ANY,
.debug = cc->debug,
@@ -157,6 +160,7 @@ pipe_configure_channels(struct pipe_proto *p, struct pipe_config *cf)
.channel = cc->channel,
.table = cf->peer,
.out_filter = cc->in_filter,
+ .out_subprefix = cf->in_subprefix,
.in_limit = cc->out_limit,
.ra_mode = RA_ANY,
.debug = cc->debug,
@@ -299,7 +303,6 @@ pipe_update_debug(struct proto *P)
struct protocol proto_pipe = {
.name = "Pipe",
.template = "pipe%d",
- .class = PROTOCOL_PIPE,
.proto_size = sizeof(struct pipe_proto),
.config_size = sizeof(struct pipe_config),
.postconfig = pipe_postconfig,
@@ -309,3 +312,9 @@ struct protocol proto_pipe = {
.get_status = pipe_get_status,
.show_proto_info = pipe_show_proto_info
};
+
+void
+pipe_build(void)
+{
+ proto_build(&proto_pipe);
+}
diff --git a/proto/pipe/pipe.h b/proto/pipe/pipe.h
index 60c857eb..a6534e1c 100644
--- a/proto/pipe/pipe.h
+++ b/proto/pipe/pipe.h
@@ -12,6 +12,7 @@
struct pipe_config {
struct proto_config c;
struct rtable_config *peer; /* Table we're connected to */
+ const net_addr *in_subprefix;
u8 max_generation;
};