]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Adds opaque/transparent pipe mode selection.
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 1 Jun 2009 10:10:10 +0000 (12:10 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 1 Jun 2009 10:10:10 +0000 (12:10 +0200)
proto/pipe/config.Y
proto/pipe/pipe.c
proto/pipe/pipe.h

index 52f70dcebc5fde87acb98118534cee015d4c8aeb..4e6c80cd4e77a62fd89573033e9c4cd531121600 100644 (file)
@@ -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
index 0240d16eae3bb07830f29858102f5d9a5a593f27..74e1bb3b0a0a5c8a1523a213ddcd6bf8ebd7d2bf 100644 (file)
@@ -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 = {
index 7e9cf8aedf12bf29d205a5a9ed3d185e2cdcc80a..368ba41ba63b814ec2d1f63b5948e568f464f1dd 100644 (file)
@@ -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;
 };