Hi double-p!

On Wed, Mar 01, 2017 at 08:00:30PM +0100, Philipp Buehler wrote:
> 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.
> 

Nice.

> Feats:
> - relayd/relayctl: -s sockname; obviously and blatantly taken from
> ospfd/ospfctl

Regarding the -s:
There is inconsistency across our daemons.

I think it all started with bgpd, where we once had -s and -r options
in the daemon, but replaced them with a config option "socket path
NAME".  This was supposed to be the model for other daemons as well,
but they either didn't adopt it or implemented the "old" -s option (it
remains in the *ctl, of course).  AFAIK, I only have it in snmpd and
this would be a reference for relayd (except the agentx part in it).
Recently I saw somebody adding a -s to a newer daemon (I forgot which
one), but I forgot to cry out.

---snip---
Author: claudio <clau...@openbsd.org>
Date:   Sun Jun 27 19:53:34 2010 +0000

    Instead of specifying the control sockets on the command line have them
    in bgpd.conf. This allows to add/modify restricted control sockets on 
runtime.
    Feature request by a few people how often forgot to add -r path when 
restarting
    bgpd (including myself).
    NOTE: this removes the -s and -r arguments from bgpd so pay attention when
    updateing.
    jajaja sthen@, OK henning@
---snap---

> - relayd: -a anchorname; overcome the problem that one stopping relayd
> cleans
>  out everything below 'relayd/*'  or not having any seperation (includes) in
> first
>  place

OK, setting the anchorname is fine. I have to look at the "cleaning" part.

> - 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
> 

I do think that this has a use case and inter-rdomain is a feature
that was requested before (some people run it in bigger rdomain
setups).

Make sure that the rtable table option doesn't only alter the rules'
rtable, it should also be used for the health checks (check_*.c)
accordingly or you end up testing hosts in the wrong rdomain.

> 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
> 

The parse.y part is small and looks fine.

But you should brush up your style(9) / KNF (at least in the anchor
part below) ;)

> 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!
> 

Bummer, I'm not there, it would be nice to meet you again.

Everyone: double-p was the first person who invited me into OpenBSD! \o/

> PS: iked lacks -s, ikectl doesnt... :)

Yes, I probably intended to put it in iked.conf as well ...

Reyk

> -- 
> 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;

This line doesn't seem to make much sense.
- anchor might be uninitialized here (of sc_rdrs is empty)
- the previous value is not used in the following transaction

> +     /* 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));
> +     }

Do you mean "trailing" or "leading" anchor?
What about the following:

        if (strlcpy(anchor, env->sc_baseanchor, sizeof(anchor)) >=
            PF_ANCHOR_NAME_SIZE)
                goto toolong;
        anchor[strcspn(anchor, "/*")] = '\0';

relayd/ -> relayd

>       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.

Specify an alternative
.Ar anchor .

(pfctl also just uses "Ar anchor")

> +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

See comment on top

>  .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;

either allocate or assign the string, you're mixing it
(baseanchor = RELAYD_ANCHOR vs asprintf(&baseanchor ...)

Maybe a simple baseanchor = optarg would be enough (see my chunk
above, we don't have to modify baseanchor anymore)

>       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;


-- 

Reply via email to