Hi folks,
after trying forth and back to overcome some limitations in relayd along
multiple
"instances" and rdomain/rtable I decided to scrub some rust of my C/yacc
and
produced the following diffs against -current to relayd and relayctl.
Feats:
- relayd/relayctl: -s sockname; obviously and blatantly taken from
ospfd/ospfctl
- relayd: -a anchorname; overcome the problem that one stopping relayd
cleans
out everything below 'relayd/*' or not having any seperation
(includes) in first
place
- relayd.conf: add 'rtable' as a tableopt; reasoning for "only" there:
- route -T N exec will already put one into 'on rdomain N'
- 'listen' already has an 'interface' option to bound to a specific
rdomain (unless
I am mistaken here on the kernel/addressing side
- generally unsure if this has a real use case anyway
Tests done:
- running two relayd on different anchors, rdomains (via route exec) and
so on,
notable to me was the point of purging the main/final anchor in
flush_rulesets.
Caveats:
- didnt write C/yacc in some years, so esp. string-handling could need
some eyeballs
Patch-white-space-drama; if the patches have mangled WS, there are also
here:
https://github.com/double-p/smtf/tree/master/patches
Everybody coming, see you in Tokyo!
PS: iked lacks -s, ikectl doesnt... :)
--
pb
Index: relayctl.8
===================================================================
RCS file: /cvs/src/usr.sbin/relayctl/relayctl.8,v
retrieving revision 1.32
diff -u -p -r1.32 relayctl.8
--- relayctl.8 28 Nov 2015 01:22:44 -0000 1.32
+++ relayctl.8 28 Feb 2017 20:09:34 -0000
@@ -23,6 +23,7 @@
.Nd control the relay daemon
.Sh SYNOPSIS
.Nm
+.Op Fl s Ar socket
.Ar command
.Op Ar argument ...
.Sh DESCRIPTION
@@ -32,6 +33,17 @@ program controls the
.Xr relayd 8
daemon.
.Pp
+The following options are available:
+.Bl -tag -width Ds
+.It Fl s Ar socket
+Use
+.Ar socket
+instead of the default
+.Pa /var/run/relayd.sock
+to communicate with
+.Xr relayd 8 .
+.El
+.Pp
The following commands are available:
.Bl -tag -width Ds
.It Cm host disable Op Ar name | id
@@ -105,6 +117,7 @@ again.
.Sh FILES
.Bl -tag -width "/var/run/relayd.sockXX" -compact
.It Pa /var/run/relayd.sock
+Default
.Ux Ns -domain
socket used for communication with
.Xr relayd 8 .
Index: relayctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayctl/relayctl.c,v
retrieving revision 1.57
diff -u -p -r1.57 relayctl.c
--- relayctl.c 3 Sep 2016 14:44:21 -0000 1.57
+++ relayctl.c 28 Feb 2017 20:09:34 -0000
@@ -88,7 +88,8 @@ usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s command [argument ...]\n", __progname);
+ fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n",
+ __progname);
exit(1);
}
@@ -101,9 +102,25 @@ main(int argc, char *argv[])
int ctl_sock;
int done = 0;
int n, verbose = 0;
+ int ch;
+ char *sockname;
+
+ sockname = RELAYD_SOCKET;
+ while ((ch = getopt(argc, argv, "s:")) != -1) {
+ switch (ch) {
+ case 's':
+ sockname = optarg;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+ argc -= optind;
+ argv += optind;
/* parse options */
- if ((res = parse(argc - 1, argv + 1)) == NULL)
+ if ((res = parse(argc, argv)) == NULL)
exit(1);
/* connect to relayd control socket */
@@ -112,7 +129,7 @@ main(int argc, char *argv[])
bzero(&sun, sizeof(sun));
sun.sun_family = AF_UNIX;
- (void)strlcpy(sun.sun_path, RELAYD_SOCKET, sizeof(sun.sun_path));
+ (void)strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path));
reconnect:
if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
/* Keep retrying if running in monitor mode */
@@ -121,7 +138,7 @@ main(int argc, char *argv[])
usleep(100);
goto reconnect;
}
- err(1, "connect: %s", RELAYD_SOCKET);
+ err(1, "connect: %s", sockname);
}
if (pledge("stdio", NULL) == -1)
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.214
diff -u -p -r1.214 parse.y
--- parse.y 5 Jan 2017 13:53:09 -0000 1.214
+++ parse.y 1 Mar 2017 15:50:24 -0000
@@ -805,6 +805,13 @@ tableopts : CHECK tablecheck
break;
}
}
+ | RTABLE NUMBER {
+ if ($2 < 0 || $2 > RT_TABLEID_MAX) {
+ yyerror("invalid rtable id %d", $2);
+ YYERROR;
+ }
+ table->conf.rtable = $2;
+ }
;
/* should be in sync with sbin/pfctl/parse.y's hashkey */
Index: pfe_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/pfe_filter.c,v
retrieving revision 1.61
diff -u -p -r1.61 pfe_filter.c
--- pfe_filter.c 24 Jan 2017 10:49:14 -0000 1.61
+++ pfe_filter.c 1 Mar 2017 15:50:24 -0000
@@ -60,7 +60,7 @@ init_tables(struct relayd *env)
i = 0;
TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
- if (strlcpy(tables[i].pfrt_anchor, RELAYD_ANCHOR "/",
+ if (strlcpy(tables[i].pfrt_anchor, env->sc_baseanchor,
sizeof(tables[i].pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(tables[i].pfrt_anchor, rdr->conf.name,
@@ -114,7 +114,7 @@ kill_tables(struct relayd *env)
TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
memset(&io, 0, sizeof(io));
- if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
+ if (strlcpy(io.pfrio_table.pfrt_anchor, env->sc_baseanchor,
sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
@@ -160,7 +160,7 @@ sync_table(struct relayd *env, struct rd
io.pfrio_size = table->up;
io.pfrio_size2 = 0;
io.pfrio_buffer = addlist;
- if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
+ if (strlcpy(io.pfrio_table.pfrt_anchor, env->sc_baseanchor,
sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
@@ -274,7 +274,7 @@ flush_table(struct relayd *env, struct r
return;
memset(&io, 0, sizeof(io));
- if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
+ if (strlcpy(io.pfrio_table.pfrt_anchor, env->sc_baseanchor,
sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
@@ -343,7 +343,7 @@ sync_ruleset(struct relayd *env, struct
return;
bzero(anchor, sizeof(anchor));
- if (strlcpy(anchor, RELAYD_ANCHOR "/", sizeof(anchor)) >=
+ if (strlcpy(anchor, env->sc_baseanchor, sizeof(anchor)) >=
PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(anchor, rdr->conf.name, sizeof(anchor)) >=
@@ -406,10 +406,12 @@ sync_ruleset(struct relayd *env, struct
rio.rule.dst.port_op = address->port.op;
rio.rule.dst.port[0] = address->port.val[0];
rio.rule.dst.port[1] = address->port.val[1];
- rio.rule.rtableid = -1; /* stay in the main routing table */
+ rio.rule.rtableid = -1; /* default: main routing table */
rio.rule.onrdomain = env->sc_rtable;
DPRINTF("%s rtable %d",__func__,env->sc_rtable);
+ if (t->conf.rtable > 0)
+ rio.rule.rtableid = t->conf.rtable;
if (rio.rule.proto == IPPROTO_TCP)
rio.rule.timeout[PFTM_TCP_ESTABLISHED] =
(u_int32_t)MINIMUM(rdr->conf.timeout.tv_sec,
@@ -500,13 +502,14 @@ flush_rulesets(struct relayd *env)
{
struct rdr *rdr;
char anchor[PF_ANCHOR_NAME_SIZE];
+ char *slash = NULL;
if (!(env->sc_conf.flags & F_NEEDPF))
return;
kill_tables(env);
TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
- if (strlcpy(anchor, RELAYD_ANCHOR "/", sizeof(anchor)) >=
+ if (strlcpy(anchor, env->sc_baseanchor, sizeof(anchor)) >=
PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(anchor, rdr->conf.name, sizeof(anchor)) >=
@@ -514,16 +517,21 @@ flush_rulesets(struct relayd *env)
goto toolong;
if (transaction_init(env, anchor) == -1 ||
transaction_commit(env) == -1)
- log_warn("%s: transaction for %s/ failed", __func__,
- RELAYD_ANCHOR);
+ log_warn("%s: transaction for %s failed", __func__,
+ anchor);
}
- if (strlcpy(anchor, RELAYD_ANCHOR, sizeof(anchor)) >=
- PF_ANCHOR_NAME_SIZE)
+ if (strlen(anchor) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
+ /* XXX: no trailing / in anchor or we leak the main anchor at exit */
+ bzero(anchor,sizeof(anchor));
+ if (( slash = strchr(env->sc_baseanchor, '/') ) != NULL ) {
+ *slash++ = '\0';
+ (void)strlcpy(anchor, slash, sizeof(anchor));
+ }
if (transaction_init(env, anchor) == -1 ||
transaction_commit(env) == -1)
- log_warn("%s: transaction for %s failed", __func__,
- RELAYD_ANCHOR);
+ log_warn("%s: transaction for %s/ failed", __func__,
+ anchor);
log_debug("%s: flushed rules", __func__);
return;
@@ -620,7 +628,7 @@ check_table(struct relayd *env, struct r
io.pfrio_esize = sizeof(struct pfr_tstats);
io.pfrio_size = 1;
io.pfrio_buffer = &tstats;
- if (strlcpy(io.pfrio_table.pfrt_anchor, RELAYD_ANCHOR "/",
+ if (strlcpy(io.pfrio_table.pfrt_anchor, env->sc_baseanchor,
sizeof(io.pfrio_table.pfrt_anchor)) >= PF_ANCHOR_NAME_SIZE)
goto toolong;
if (strlcat(io.pfrio_table.pfrt_anchor, rdr->conf.name,
Index: relayd.8
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.8,v
retrieving revision 1.25
diff -u -p -r1.25 relayd.8
--- relayd.8 27 Jul 2015 14:50:58 -0000 1.25
+++ relayd.8 1 Mar 2017 15:50:24 -0000
@@ -23,8 +23,10 @@
.Sh SYNOPSIS
.Nm
.Op Fl dnv
+.Op Fl a Ar anchor
.Op Fl D Ar macro Ns = Ns Ar value
.Op Fl f Ar file
+.Op Fl s Ar socket
.Sh DESCRIPTION
.Nm
is a daemon to relay and dynamically redirect incoming connections to
@@ -96,6 +98,9 @@ can be used to alter or report on the st
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl a Ar anchor
+Specify an alternative anchorname.
+The default is 'relayd'.
.It Fl D Ar macro Ns = Ns Ar value
Define
.Ar macro
@@ -120,12 +125,17 @@ Configtest mode.
Only check the configuration file for validity.
.It Fl v
Produce more verbose output.
+.It Fl s Ar socket
+Specify an alternative socket.
+The default is
+.Pa /var/run/relayd.sock
.El
.Sh FILES
.Bl -tag -width "/var/run/relayd.sockXX" -compact
.It Pa /etc/relayd.conf
Default configuration file.
.It Pa /var/run/relayd.sock
+Default
.Ux Ns -domain
socket used for communication with
.Xr relayctl 8 .
Index: relayd.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.c,v
retrieving revision 1.165
diff -u -p -r1.165 relayd.c
--- relayd.c 24 Jan 2017 10:49:14 -0000 1.165
+++ relayd.c 1 Mar 2017 15:50:24 -0000
@@ -107,7 +107,7 @@ usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
+ fprintf(stderr, "usage: %s [-dnv] [-a anchor ] [-D macro=value] [-f file] [-s socket ]\n",
__progname);
exit(1);
}
@@ -121,12 +121,14 @@ main(int argc, char *argv[])
struct relayd *env;
struct privsep *ps;
const char *conffile = CONF_FILE;
+ const char *ctlsock = RELAYD_SOCKET;
+ char *baseanchor = RELAYD_ANCHOR;
enum privsep_procid proc_id = PROC_PARENT;
int proc_instance = 0;
const char *errp, *title = NULL;
int argc0 = argc;
- while ((c = getopt(argc, argv, "dD:nI:P:f:v")) != -1) {
+ while ((c = getopt(argc, argv, "a:dD:f:nI:P:s:v")) != -1) {
switch (c) {
case 'd':
debug = 2;
@@ -159,6 +161,14 @@ main(int argc, char *argv[])
if (errp)
fatalx("invalid process instance");
break;
+ case 's':
+ ctlsock = optarg;
+ break;
+ case 'a':
+ if (strlen(optarg) >= PF_ANCHOR_NAME_SIZE)
+ fatalx("anchor too long");
+ (void)asprintf(&baseanchor, "%s/", optarg);
+ break;
default:
usage();
}
@@ -180,6 +190,7 @@ main(int argc, char *argv[])
ps->ps_env = env;
TAILQ_INIT(&ps->ps_rcsocks);
env->sc_conffile = conffile;
+ env->sc_baseanchor = baseanchor;
env->sc_conf.opts = opts;
TAILQ_INIT(&env->sc_hosts);
TAILQ_INIT(&env->sc_sessions);
@@ -200,7 +211,7 @@ main(int argc, char *argv[])
errx(1, "unknown user %s", RELAYD_USER);
/* Configure the control socket */
- ps->ps_csock.cs_name = RELAYD_SOCKET;
+ ps->ps_csock.cs_name = ctlsock;
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
Index: relayd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
retrieving revision 1.175
diff -u -p -r1.175 relayd.conf.5
--- relayd.conf.5 27 Feb 2017 22:25:58 -0000 1.175
+++ relayd.conf.5 1 Mar 2017 15:50:24 -0000
@@ -386,6 +386,9 @@ It must be a multiple of the global inte
Set the timeout in milliseconds for each host that is checked using
TCP as the transport.
This will override the global timeout, which is 200 milliseconds by default.
+.It Ic rtable Ar id
+This will insert the rule with its destination within routing table with
+.Ar id .
.El
.Pp
The following options will set the scheduling algorithm to select a
Index: relayd.h
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
retrieving revision 1.239
diff -u -p -r1.239 relayd.h
--- relayd.h 2 Feb 2017 08:24:16 -0000 1.239
+++ relayd.h 1 Mar 2017 15:50:24 -0000
@@ -477,6 +477,7 @@ struct table_config {
int check;
char demote_group[IFNAMSIZ];
char ifname[IFNAMSIZ];
+ int rtable;
struct timeval timeout;
in_port_t port;
int retcode;
@@ -1054,6 +1055,7 @@ struct pfdata {
struct relayd {
struct relayd_config sc_conf;
const char *sc_conffile;
+ char *sc_baseanchor;
struct pfdata *sc_pf;
int sc_rtsock;
int sc_rtseq;