summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/relayd/check_icmp.c5
-rw-r--r--usr.sbin/relayd/control.c6
-rw-r--r--usr.sbin/relayd/hce.c17
-rw-r--r--usr.sbin/relayd/parse.y43
-rw-r--r--usr.sbin/relayd/pfe.c54
-rw-r--r--usr.sbin/relayd/relayd.conf.517
-rw-r--r--usr.sbin/relayd/relayd.h9
7 files changed, 114 insertions, 37 deletions
diff --git a/usr.sbin/relayd/check_icmp.c b/usr.sbin/relayd/check_icmp.c
index f16e9bd3d61..c022077f936 100644
--- a/usr.sbin/relayd/check_icmp.c
+++ b/usr.sbin/relayd/check_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: check_icmp.c,v 1.23 2008/01/31 09:33:39 reyk Exp $ */
+/* $OpenBSD: check_icmp.c,v 1.24 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -197,7 +197,8 @@ send_icmp(int s, short event, void *arg)
table->conf.flags & F_DISABLE)
continue;
TAILQ_FOREACH(host, &table->hosts, entry) {
- if (host->flags & (F_DISABLE | F_CHECK_SENT))
+ if (host->flags & (F_DISABLE | F_CHECK_SENT) ||
+ host->conf.parentid)
continue;
if (((struct sockaddr *)&host->conf.ss)->sa_family !=
cie->af)
diff --git a/usr.sbin/relayd/control.c b/usr.sbin/relayd/control.c
index d0c7258fe7d..67be0a1a7be 100644
--- a/usr.sbin/relayd/control.c
+++ b/usr.sbin/relayd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.25 2008/01/31 09:33:39 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.26 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -293,7 +293,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
fatalx("invalid imsg header len");
memcpy(&id, imsg.data, sizeof(id));
- if (disable_host(c, &id))
+ if (disable_host(c, &id, NULL))
imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1,
NULL, 0);
else {
@@ -307,7 +307,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
fatalx("invalid imsg header len");
memcpy(&id, imsg.data, sizeof(id));
- if (enable_host(c, &id))
+ if (enable_host(c, &id, NULL))
imsg_compose(&c->ibuf, IMSG_CTL_FAIL, 0, 0, -1,
NULL, 0);
else {
diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c
index f0cd92cfb47..262f7f646c9 100644
--- a/usr.sbin/relayd/hce.c
+++ b/usr.sbin/relayd/hce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hce.c,v 1.41 2008/03/12 10:50:44 pyr Exp $ */
+/* $OpenBSD: hce.c,v 1.42 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -240,7 +240,7 @@ hce_launch_checks(int fd, short event, void *arg)
fatalx("hce_launch_checks: unknown check type");
TAILQ_FOREACH(host, &table->hosts, entry) {
- if (host->flags & F_DISABLE)
+ if (host->flags & F_DISABLE || host->conf.parentid)
continue;
switch (table->conf.check) {
case CHECK_ICMP:
@@ -276,6 +276,10 @@ hce_notify_done(struct host *host, const char *msg)
struct timeval tv_now, tv_dur;
u_long duration;
u_int logopt;
+ struct host *h;
+ int hostup;
+
+ hostup = host->up;
if (host->up == HOST_DOWN && host->retry_cnt) {
log_debug("hce_notify_done: host %s retry %d",
@@ -327,6 +331,15 @@ hce_notify_done(struct host *host, const char *msg)
snmp_hosttrap(table, host);
host->last_up = host->up;
+
+ if (TAILQ_EMPTY(&host->children))
+ return;
+
+ /* Notify for all other hosts that inherit the state from this one */
+ TAILQ_FOREACH(h, &host->children, child) {
+ h->up = hostup;
+ hce_notify_done(h, msg);
+ }
}
void
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index 3c7cb2b61a7..9a881ed0f2a 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.119 2008/07/17 16:41:06 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.120 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
@@ -130,11 +130,11 @@ typedef struct {
%token ON PATH PORT PREFORK PROTO QUERYSTR REAL REDIRECT RELAY REMOVE TRAP
%token REQUEST RESPONSE RETRY RETURN ROUNDROBIN SACK SCRIPT SEND SESSION
%token SOCKET SSL STICKYADDR STYLE TABLE TAG TCP TIMEOUT TO UPDATES URL
-%token VIRTUAL WITH ERROR ROUTE TRANSPARENT
+%token VIRTUAL WITH ERROR ROUTE TRANSPARENT PARENT
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.string> interface hostname table
-%type <v.number> port http_type loglevel sslcache optssl mark
+%type <v.number> port http_type loglevel sslcache optssl mark parent
%type <v.number> proto_type dstmode retry log flag direction forwardmode
%type <v.host> host
%type <v.tv> timeout
@@ -1238,7 +1238,7 @@ interface : /*empty*/ { $$ = NULL; }
| INTERFACE STRING { $$ = $2; }
;
-host : STRING retry {
+host : STRING retry parent {
struct address *a;
struct addresslist al;
@@ -1266,6 +1266,8 @@ host : STRING retry {
free($1);
$$->conf.id = 0; /* will be set later */
$$->conf.retry = $2;
+ $$->conf.parentid = $3;
+ TAILQ_INIT(&$$->children);
}
;
@@ -1278,6 +1280,15 @@ retry : /* nothing */ { $$ = 0; }
}
;
+parent : /* nothing */ { $$ = 0; }
+ | PARENT NUMBER {
+ if (($$ = $2) < 0) {
+ yyerror("invalid parent value: %d\n", $2);
+ YYERROR;
+ }
+ }
+ ;
+
timeout : NUMBER
{
if ($1 < 0) {
@@ -1378,6 +1389,7 @@ lookup(char *s)
{ "nodelay", NODELAY },
{ "nothing", NOTHING },
{ "on", ON },
+ { "parent", PARENT },
{ "path", PATH },
{ "port", PORT },
{ "prefork", PREFORK },
@@ -1729,7 +1741,7 @@ parse_config(const char *filename, int opts)
{
struct sym *sym, *next;
struct table *nexttb;
- struct host *h;
+ struct host *h, *ph;
if ((conf = calloc(1, sizeof(*conf))) == NULL ||
(conf->sc_tables = calloc(1, sizeof(*conf->sc_tables))) == NULL ||
@@ -1833,6 +1845,26 @@ parse_config(const char *filename, int opts)
free(table);
continue;
}
+
+ TAILQ_FOREACH(h, &table->hosts, entry) {
+ if (h->conf.parentid) {
+ ph = host_find(conf, h->conf.parentid);
+
+ /* Validate the parent id */
+ if (h->conf.id == h->conf.parentid ||
+ ph == NULL || ph->conf.parentid)
+ ph = NULL;
+
+ if (ph == NULL) {
+ log_warnx("host parent id %d invalid",
+ h->conf.parentid);
+ errors++;
+ } else
+ TAILQ_INSERT_TAIL(&ph->children,
+ h, child);
+ }
+ }
+
if (!(table->conf.flags & F_USED)) {
log_warnx("unused table: %s", table->conf.name);
errors++;
@@ -2135,6 +2167,7 @@ table_inherit(struct table *tb)
}
h->conf.tableid = tb->conf.id;
h->tablename = tb->conf.name;
+ TAILQ_INIT(&h->children);
TAILQ_INSERT_TAIL(&tb->hosts, h, entry);
}
diff --git a/usr.sbin/relayd/pfe.c b/usr.sbin/relayd/pfe.c
index f905f4f85d9..f06432a6b6b 100644
--- a/usr.sbin/relayd/pfe.c
+++ b/usr.sbin/relayd/pfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe.c,v 1.48 2008/01/31 09:56:28 reyk Exp $ */
+/* $OpenBSD: pfe.c,v 1.49 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -749,18 +749,20 @@ enable_table(struct ctl_conn *c, struct ctl_id *id)
}
int
-disable_host(struct ctl_conn *c, struct ctl_id *id)
+disable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
{
- struct host *host;
+ struct host *h;
struct table *table;
int n;
- if (id->id == EMPTY_ID)
- host = host_findbyname(env, id->name);
- else
- host = host_find(env, id->id);
- if (host == NULL)
- return (-1);
+ if (host == NULL) {
+ if (id->id == EMPTY_ID)
+ host = host_findbyname(env, id->name);
+ else
+ host = host_find(env, id->id);
+ if (host == NULL || host->conf.parentid)
+ return (-1);
+ }
id->id = host->conf.id;
if (host->flags & F_DISABLE)
@@ -788,22 +790,30 @@ disable_host(struct ctl_conn *c, struct ctl_id *id)
IMSG_HOST_DISABLE, 0, 0, -1,
&host->conf.id, sizeof(host->conf.id));
log_debug("disable_host: disabled host %d", host->conf.id);
- pfe_sync();
+
+ /* Disable all children */
+ TAILQ_FOREACH(h, &host->children, child)
+ disable_host(c, id, h);
+
+ if (!host->conf.parentid)
+ pfe_sync();
return (0);
}
int
-enable_host(struct ctl_conn *c, struct ctl_id *id)
+enable_host(struct ctl_conn *c, struct ctl_id *id, struct host *host)
{
- struct host *host;
+ struct host *h;
int n;
- if (id->id == EMPTY_ID)
- host = host_findbyname(env, id->name);
- else
- host = host_find(env, id->id);
- if (host == NULL)
- return (-1);
+ if (host == NULL) {
+ if (id->id == EMPTY_ID)
+ host = host_findbyname(env, id->name);
+ else
+ host = host_find(env, id->id);
+ if (host == NULL || host->conf.parentid)
+ return (-1);
+ }
id->id = host->conf.id;
if (!(host->flags & F_DISABLE))
@@ -822,7 +832,13 @@ enable_host(struct ctl_conn *c, struct ctl_id *id)
IMSG_HOST_ENABLE, 0, 0, -1,
&host->conf.id, sizeof(host->conf.id));
log_debug("enable_host: enabled host %d", host->conf.id);
- pfe_sync();
+
+ /* Enable all children */
+ TAILQ_FOREACH(h, &host->children, child)
+ enable_host(c, id, h);
+
+ if (!host->conf.parentid)
+ pfe_sync();
return (0);
}
diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5
index 16c609b0f69..2611a531000 100644
--- a/usr.sbin/relayd/relayd.conf.5
+++ b/usr.sbin/relayd/relayd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: relayd.conf.5,v 1.88 2008/06/11 18:21:20 reyk Exp $
+.\" $OpenBSD: relayd.conf.5,v 1.89 2008/07/19 10:52:32 reyk Exp $
.\"
.\" Copyright (c) 2006, 2007 Reyk Floeter <reyk@openbsd.org>
.\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 11 2008 $
+.Dd $Mdocdate: July 19 2008 $
.Dt RELAYD.CONF 5
.Os
.Sh NAME
@@ -183,7 +183,7 @@ The table can be later enabled through
.El
Each table must contain at least one host;
multiple hosts are separated by newline, comma, or whitespace.
-Host entries may be defined with the following attribute:
+Host entries may be defined with the following attributes:
.Bl -tag -width retry
.It Ic retry Ar number
The optional retry option adds a tolerance for failed host checks;
@@ -192,6 +192,17 @@ the check will be retried for
more times before setting the host state to down.
If this table is used by a relay, it will also specify the number of
retries for outgoing connection attempts.
+.It Ic parent Ar number
+The optional parent option allows to inherit the state from a parent
+host with the specified identifier.
+The check will be skipped for this host and copied from the parent host.
+This can be used to prevent multiple checks on hosts with multiple IP
+addresses for the same service.
+The host identifiers are sequentially assigned to the configured hosts
+starting with 1; it can be figured out with the
+.Xr relayctl 8
+.Ic show summary
+commands.
.El
.Pp
For example:
diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h
index 1979e4285fa..763a4f58709 100644
--- a/usr.sbin/relayd/relayd.h
+++ b/usr.sbin/relayd/relayd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: relayd.h,v 1.106 2008/07/09 17:16:51 reyk Exp $ */
+/* $OpenBSD: relayd.h,v 1.107 2008/07/19 10:52:32 reyk Exp $ */
/*
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -345,6 +345,7 @@ enum forwardmode {
struct host_config {
objid_t id;
+ objid_t parentid;
objid_t tableid;
int retry;
char name[MAXHOSTNAMELEN];
@@ -353,6 +354,8 @@ struct host_config {
struct host {
TAILQ_ENTRY(host) entry;
+ TAILQ_ENTRY(host) child;
+ TAILQ_HEAD(,host) children;
struct host_config conf;
u_int32_t flags;
char *tablename;
@@ -766,10 +769,10 @@ void show(struct ctl_conn *);
void show_sessions(struct ctl_conn *);
int enable_rdr(struct ctl_conn *, struct ctl_id *);
int enable_table(struct ctl_conn *, struct ctl_id *);
-int enable_host(struct ctl_conn *, struct ctl_id *);
+int enable_host(struct ctl_conn *, struct ctl_id *, struct host *);
int disable_rdr(struct ctl_conn *, struct ctl_id *);
int disable_table(struct ctl_conn *, struct ctl_id *);
-int disable_host(struct ctl_conn *, struct ctl_id *);
+int disable_host(struct ctl_conn *, struct ctl_id *, struct host *);
/* pfe_filter.c */
void init_filter(struct relayd *);