I've been running with most of this diff for ages, just got
round to adding the pfe.c part to fix relayctl show ho / show su
output.

Any comments, oks?

Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.143
diff -u -p -r1.143 parse.y
--- parse.y     24 Feb 2010 15:44:18 -0000      1.143
+++ parse.y     30 Jun 2010 23:34:52 -0000
@@ -1213,6 +1213,11 @@ relay            : RELAY STRING  {
                                    "or table", rlay->rl_conf.name);
                                YYERROR;
                        }
+                       if (rlay->rl_backuptable == NULL) {
+                               rlay->rl_conf.backuptable =
+                                   conf->sc_empty_table.conf.id;
+                               rlay->rl_backuptable = &conf->sc_empty_table;
+                       }
                        if (rlay->rl_conf.proto == EMPTY_ID) {
                                rlay->rl_proto = &conf->sc_proto_default;
                                rlay->rl_conf.proto = conf->sc_proto_default.id;
@@ -1362,16 +1367,21 @@ forwardspec     : STRING port retry     {
                        rlay->rl_conf.dstretry = $3;
                }
                | tablespec     {
-                       if (rlay->rl_dsttable) {
-                               yyerror("table already specified");
+                       if (rlay->rl_backuptable) {
+                               yyerror("only one backup table is allowed");
                                purge_table(conf->sc_tables, $1);
                                YYERROR;
                        }
-
-                       rlay->rl_dsttable = $1;
-                       rlay->rl_dsttable->conf.flags |= F_USED;
-                       rlay->rl_conf.dsttable = $1->conf.id;
-                       rlay->rl_conf.dstport = $1->conf.port;
+                       if (rlay->rl_dsttable) {
+                               rlay->rl_backuptable = $1;
+                               rlay->rl_backuptable->conf.flags |= F_USED;
+                               rlay->rl_conf.backuptable = $1->conf.id;
+                       } else {
+                               rlay->rl_dsttable = $1;
+                               rlay->rl_dsttable->conf.flags |= F_USED;
+                               rlay->rl_conf.dsttable = $1->conf.id;
+                               rlay->rl_conf.dstport = $1->conf.port;
+                       }
                }
                ;
 
Index: pfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/pfe.c,v
retrieving revision 1.64
diff -u -p -r1.64 pfe.c
--- pfe.c       14 May 2010 11:13:36 -0000      1.64
+++ pfe.c       30 Jun 2010 23:34:52 -0000
@@ -586,6 +586,15 @@ relays:
                        TAILQ_FOREACH(host, &rlay->rl_dsttable->hosts, entry)
                                imsg_compose_event(&c->iev, IMSG_CTL_HOST,
                                    0, 0, -1, host, sizeof(*host));
+
+               if (rlay->rl_conf.backuptable == EMPTY_TABLE)
+                       continue;
+               imsg_compose_event(&c->iev, IMSG_CTL_TABLE, 0, 0, -1,
+                   rlay->rl_backuptable, sizeof(*rlay->rl_backuptable));
+               if (!(rlay->rl_backuptable->conf.flags & F_DISABLE))
+                       TAILQ_FOREACH(host, &rlay->rl_backuptable->hosts, entry)
+                               imsg_compose_event(&c->iev, IMSG_CTL_HOST,
+                                   0, 0, -1, host, sizeof(*host));
        }
 
 routers:
Index: relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.121
diff -u -p -r1.121 relay.c
--- relay.c     26 May 2010 13:56:08 -0000      1.121
+++ relay.c     30 Jun 2010 23:34:52 -0000
@@ -2123,9 +2123,11 @@ relay_from_table(struct rsession *con)
        u_int32_t                p = con->se_hashkey;
        int                      idx = 0;
 
-       if (table->conf.check && !table->up) {
+       if (table->conf.check && !table->up && !rlay->rl_backuptable->up) {
                log_debug("relay_from_table: no active hosts");
                return (-1);
+       } else if (!table->up && rlay->rl_backuptable->up) {
+               table = rlay->rl_backuptable;
        }
 
        switch (rlay->rl_conf.dstmode) {
Index: relayd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
retrieving revision 1.113
diff -u -p -r1.113 relayd.conf.5
--- relayd.conf.5       18 May 2010 15:09:34 -0000      1.113
+++ relayd.conf.5       30 Jun 2010 23:34:52 -0000
@@ -580,6 +580,9 @@ Like the previous directive, but connect
 table; see the
 .Sx TABLES
 section above for information about table options.
+This directive can be specified twice \(en the second entry will be used
+as the backup table if all hosts in the main table are down.
+At least one entry for the main table is mandatory.
 .It Xo
 .Ic forward to
 .Ic nat lookup
Index: relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.136
diff -u -p -r1.136 relayd.h
--- relayd.h    26 May 2010 13:56:08 -0000      1.136
+++ relayd.h    30 Jun 2010 23:34:52 -0000
@@ -536,6 +536,7 @@ struct relay_config {
        int                      dstmode;
        int                      dstretry;
        objid_t                  dsttable;
+       objid_t                  backuptable;
        struct sockaddr_storage  ss;
        struct sockaddr_storage  dstss;
        struct sockaddr_storage  dstaf;
@@ -556,6 +557,7 @@ struct relay {
        struct bufferevent      *rl_dstbev;
 
        struct table            *rl_dsttable;
+       struct table            *rl_backuptable;
        u_int32_t                rl_dstkey;
        struct host             *rl_dsthost[RELAY_MAXHOSTS];
        int                      rl_dstnhosts;

Reply via email to