diff options
-rw-r--r-- | usr.sbin/relayd/check_icmp.c | 5 | ||||
-rw-r--r-- | usr.sbin/relayd/control.c | 6 | ||||
-rw-r--r-- | usr.sbin/relayd/hce.c | 17 | ||||
-rw-r--r-- | usr.sbin/relayd/parse.y | 43 | ||||
-rw-r--r-- | usr.sbin/relayd/pfe.c | 54 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 17 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 9 |
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 *); |