From 2d45e09f58c4ce857e10c241cf0e89b51b9ec49c Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 1 Jun 2009 12:10:10 +0200 Subject: [PATCH] Adds opaque/transparent pipe mode selection. --- proto/pipe/config.Y | 11 +++++++++-- proto/pipe/pipe.c | 25 ++++++++++++++++++------- proto/pipe/pipe.h | 5 +++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/proto/pipe/config.Y b/proto/pipe/config.Y index 52f70dce..4e6c80cd 100644 --- a/proto/pipe/config.Y +++ b/proto/pipe/config.Y @@ -10,9 +10,13 @@ CF_HDR #include "proto/pipe/pipe.h" +CF_DEFINES + +#define PIPE_CFG ((struct pipe_config *) this_proto) + CF_DECLS -CF_KEYWORDS(PIPE, PEER, TABLE) +CF_KEYWORDS(PIPE, PEER, TABLE, MODE, OPAQUE, TRANSPARENT) CF_GRAMMAR @@ -21,6 +25,7 @@ CF_ADDTO(proto, pipe_proto '}') pipe_proto_start: proto_start PIPE { this_proto = proto_config_new(&proto_pipe, sizeof(struct pipe_config)); this_proto->preference = DEF_PREF_PIPE; + PIPE_CFG->mode = PIPE_OPAQUE; } ; @@ -30,8 +35,10 @@ pipe_proto: | pipe_proto PEER TABLE SYM ';' { if ($4->class != SYM_TABLE) cf_error("Routing table name expected"); - ((struct pipe_config *) this_proto)->peer = $4->def; + PIPE_CFG->peer = $4->def; } + | pipe_proto MODE OPAQUE ';' { PIPE_CFG->mode = PIPE_OPAQUE; } + | pipe_proto MODE TRANSPARENT ';' { PIPE_CFG->mode = PIPE_TRANSPARENT; } ; CF_CODE diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 0240d16e..74e1bb3b 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -51,13 +51,23 @@ pipe_send(struct pipe_proto *p, rtable *dest, net *n, rte *new, rte *old, ea_lis if (new) { memcpy(&a, new->attrs, sizeof(rta)); + + if (p->mode == PIPE_OPAQUE) + { + a.proto = &p->p; + a.source = RTS_PIPE; + } + a.aflags = 0; a.eattrs = attrs; e = rte_get_temp(&a); e->net = nn; - /* Copy protocol specific embedded attributes. */ - memcpy(&(e->u), &(new->u), sizeof(e->u)); + if (p->mode == PIPE_TRANSPARENT) + { + /* Copy protocol specific embedded attributes. */ + memcpy(&(e->u), &(new->u), sizeof(e->u)); + } src = new->attrs->proto; } @@ -68,7 +78,7 @@ pipe_send(struct pipe_proto *p, rtable *dest, net *n, rte *new, rte *old, ea_lis } dest->pipe_busy = 1; - rte_update2(dest, nn, &p->p, src, e); + rte_update2(dest, nn, &p->p, (p->mode == PIPE_OPAQUE) ? &p->p : src, e); dest->pipe_busy = 0; } @@ -117,7 +127,7 @@ pipe_start(struct proto *P) memcpy(ph, p, sizeof(struct pipe_proto)); p->phantom = ph; ph->phantom = p; - ph->p.accept_ra_types = RA_ANY; + ph->p.accept_ra_types = (p->mode == PIPE_OPAQUE) ? RA_OPTIMAL : RA_ANY; ph->p.rt_notify = pipe_rt_notify_sec; ph->p.proto_state = PS_UP; ph->p.core_state = ph->p.core_goal = FS_HAPPY; @@ -153,7 +163,8 @@ pipe_init(struct proto_config *C) struct pipe_proto *p = (struct pipe_proto *) P; p->peer = c->peer->table; - P->accept_ra_types = RA_ANY; + p->mode = c->mode; + P->accept_ra_types = (p->mode == PIPE_OPAQUE) ? RA_OPTIMAL : RA_ANY; P->rt_notify = pipe_rt_notify_pri; P->import_control = pipe_import_control; return P; @@ -175,7 +186,7 @@ pipe_get_status(struct proto *P, byte *buf) { struct pipe_proto *p = (struct pipe_proto *) P; - bsprintf(buf, "-> %s", p->peer->name); + bsprintf(buf, "%c> %s", (p->mode == PIPE_OPAQUE) ? '-' : '=', p->peer->name); } static int @@ -184,7 +195,7 @@ pipe_reconfigure(struct proto *p, struct proto_config *new) struct pipe_config *o = (struct pipe_config *) p->cf; struct pipe_config *n = (struct pipe_config *) new; - return o->peer == n->peer; + return (o->peer == n->peer) && (o->mode == n->mode); } struct protocol proto_pipe = { diff --git a/proto/pipe/pipe.h b/proto/pipe/pipe.h index 7e9cf8ae..368ba41b 100644 --- a/proto/pipe/pipe.h +++ b/proto/pipe/pipe.h @@ -9,14 +9,19 @@ #ifndef _BIRD_PIPE_H_ #define _BIRD_PIPE_H_ +#define PIPE_OPAQUE 0 +#define PIPE_TRANSPARENT 1 + struct pipe_config { struct proto_config c; struct rtable_config *peer; /* Table we're connected to */ + int mode; /* PIPE_OPAQUE or PIPE_TRANSPARENT */ }; struct pipe_proto { struct proto p; struct rtable *peer; + int mode; /* PIPE_OPAQUE or PIPE_TRANSPARENT */ struct pipe_proto *phantom; };