Retire switchd and switchctl. While interesting they never managed to
authorclaudio <claudio@openbsd.org>
Thu, 11 Nov 2021 09:59:19 +0000 (09:59 +0000)
committerclaudio <claudio@openbsd.org>
Thu, 11 Nov 2021 09:59:19 +0000 (09:59 +0000)
really get into a usable state. The OpenFlow API is mostly superseeded
by P4 and so this is a bit of a dead end.
OK akoshibe@ yasuoka@ deraadt@ kn@ patrick@ sthen@

31 files changed:
usr.sbin/switchctl/Makefile [deleted file]
usr.sbin/switchctl/ofpclient.c [deleted file]
usr.sbin/switchctl/parser.c [deleted file]
usr.sbin/switchctl/parser.h [deleted file]
usr.sbin/switchctl/switchctl.8 [deleted file]
usr.sbin/switchctl/switchctl.c [deleted file]
usr.sbin/switchd/Makefile [deleted file]
usr.sbin/switchd/control.c [deleted file]
usr.sbin/switchd/genmap.sh [deleted file]
usr.sbin/switchd/imsg_util.c [deleted file]
usr.sbin/switchd/log.c [deleted file]
usr.sbin/switchd/ofcconn.c [deleted file]
usr.sbin/switchd/ofp.c [deleted file]
usr.sbin/switchd/ofp10.c [deleted file]
usr.sbin/switchd/ofp10.h [deleted file]
usr.sbin/switchd/ofp13.c [deleted file]
usr.sbin/switchd/ofp_common.c [deleted file]
usr.sbin/switchd/ofp_map.h [deleted file]
usr.sbin/switchd/ofrelay.c [deleted file]
usr.sbin/switchd/packet.c [deleted file]
usr.sbin/switchd/parse.y [deleted file]
usr.sbin/switchd/proc.c [deleted file]
usr.sbin/switchd/proc.h [deleted file]
usr.sbin/switchd/switch.c [deleted file]
usr.sbin/switchd/switchd.8 [deleted file]
usr.sbin/switchd/switchd.c [deleted file]
usr.sbin/switchd/switchd.conf.5 [deleted file]
usr.sbin/switchd/switchd.h [deleted file]
usr.sbin/switchd/timer.c [deleted file]
usr.sbin/switchd/types.h [deleted file]
usr.sbin/switchd/util.c [deleted file]

diff --git a/usr.sbin/switchctl/Makefile b/usr.sbin/switchctl/Makefile
deleted file mode 100644 (file)
index d6007e9..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# $OpenBSD: Makefile,v 1.5 2017/07/06 12:15:23 espie Exp $
-
-SWITCHD=       ${.CURDIR}/../switchd
-
-.PATH:         ${SWITCHD}
-
-PROG=          switchctl
-MAN=           switchctl.8
-SRCS=          log.c ofpclient.c parser.c util.c imsg_util.c switchctl.c
-SRCS+=         ofp10.c ofp13.c ofp_common.c packet.c
-
-LDADD=         -lutil
-DPADD=         ${LIBUTIL}
-
-CFLAGS+=       -Wall -I${.CURDIR} -I${SWITCHD}
-CFLAGS+=       -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+=       -Wmissing-declarations
-CFLAGS+=       -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+=       -Wsign-compare
-
-GENERATED=     ofp_map.c ofp10_map.c
-SRCS+=         ${GENERATED}
-CLEANFILES+=   ${GENERATED}
-
-ofp_map.c: genmap.sh ${SWITCHD}/ofp_map.h ${SWITCHD}/../../sys/net/ofp.h
-       /bin/sh ${SWITCHD}/genmap.sh -i ${SWITCHD}/../../sys/net/ofp.h -t ofp \
-           -m ${SWITCHD}/ofp_map.h -h '<net/ofp.h>' > $@
-       @touch $@
-
-ofp10_map.c: genmap.sh ${SWITCHD}/ofp_map.h ${SWITCHD}/ofp10.h
-       /bin/sh ${SWITCHD}/genmap.sh -i ${SWITCHD}/ofp10.h -t ofp10 \
-           -m ${SWITCHD}/ofp_map.h -h '"ofp10.h"' > $@
-       @touch $@
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/switchctl/ofpclient.c b/usr.sbin/switchctl/ofpclient.c
deleted file mode 100644 (file)
index b349a0b..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*     $OpenBSD: ofpclient.c,v 1.7 2018/10/21 21:10:24 akoshibe Exp $  */
-
-/*
- * Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/tree.h>
-#include <sys/un.h>
-
-#include <net/if.h>
-#include <net/ofp.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <string.h>
-#include <ctype.h>
-#include <poll.h>
-#include <err.h>
-#include <pwd.h>
-#include <vis.h>
-
-#include "switchd.h"
-#include "parser.h"
-
-void    ofpclient_read(struct switch_connection *, int);
-int     flowmod(struct switchd *, struct switch_connection *,
-           struct parse_result *);
-int     flowmod_test(struct switchd *, struct switch_connection *);
-
-void
-ofpclient(struct parse_result *res, struct passwd *pw)
-{
-       struct switch_connection con;
-       struct switchd           sc;
-       int                      s, timeout;
-       struct sockaddr_un      *un;
-
-       memset(&sc, 0, sizeof(sc));
-       sc.sc_tap = -1;
-
-       /* If no uri has been specified, try to connect to localhost */
-       if (res->uri.swa_addr.ss_family == AF_UNSPEC) { 
-               res->uri.swa_type = SWITCH_CONN_TCP;
-               if (parsehostport("127.0.0.1",
-                   (struct sockaddr *)&res->uri.swa_addr,
-                   sizeof(res->uri.swa_addr)) != 0)
-                       fatal("could not parse address");
-       }
-
-       memset(&con, 0, sizeof(con));
-       memcpy(&con.con_peer, &res->uri.swa_addr, sizeof(res->uri.swa_addr));
-       con.con_sc = &sc;
-
-       /*
-        * Connect and send the request
-        */
-       switch (res->uri.swa_type) {
-       case SWITCH_CONN_TCP:
-               if ((s = socket(res->uri.swa_addr.ss_family, SOCK_STREAM,
-                   IPPROTO_TCP)) == -1)
-                       fatal("socket");
-
-               /* Use the default port if no port has been specified */
-               if (socket_getport(&con.con_peer) == 0)
-                       (void)socket_setport(&con.con_peer, SWITCHD_CTLR_PORT);
-
-               if (connect(s, (struct sockaddr *)&con.con_peer,
-                   con.con_peer.ss_len) == -1)
-                       fatal("connect");
-
-               con.con_fd = s;
-               break;
-       case SWITCH_CONN_LOCAL:
-               un = (struct sockaddr_un *)&res->uri.swa_addr;
-
-               if (strncmp(un->sun_path, "/dev/switch",
-                   strlen("/dev/switch")) != 0)
-                       fatalx("device path not supported");
-
-               if ((s = open(un->sun_path, O_RDWR | O_NONBLOCK)) == -1)
-                       fatalx("failed to open %s", un->sun_path);
-               con.con_fd = s;
-               break;
-       default:
-               fatalx("connect type not supported");
-       }
-
-       /* Drop privileges */
-       if (pledge("stdio", NULL) == -1)
-               err(1, "pledge");
-
-       /* Set a default read timeout */
-       timeout = 3 * 1000;
-
-       log_setverbose(res->verbose);
-
-       ofp_send_hello(&sc, &con, OFP_V_1_3);
-       ofpclient_read(&con, timeout);
-
-       log_setverbose(res->quiet ? res->verbose : 2);
-
-       switch (res->action) {
-       case DUMP_DESC:
-               ofp13_desc(&sc, &con);
-               break;
-       case DUMP_FEATURES:
-               ofp_send_featuresrequest(&sc, &con);
-               break;
-       case DUMP_FLOWS:
-               ofp13_flow_stats(&sc, &con, OFP_PORT_ANY, OFP_GROUP_ID_ANY,
-                   res->table);
-               break;
-       case DUMP_TABLES:
-               ofp13_table_features(&sc, &con, res->table);
-               break;
-       case FLOW_ADD:
-       case FLOW_DELETE:
-       case FLOW_MODIFY:
-               timeout = 0;
-               flowmod(&sc, &con, res);
-               break;
-       default:
-               fatalx("unsupported action");
-       }
-
-       /* XXX */
-       ofpclient_read(&con, timeout);
-}
-
-int
-flowmod(struct switchd *sc, struct switch_connection *con,
-    struct parse_result *res)
-{
-       struct ofp_header       *oh;
-       struct ofp_flow_mod     *fm;
-
-       if (oflowmod_iclose(&res->fctx) == -1)
-               goto err;
-       if (oflowmod_close(&res->fctx) == -1)
-               goto err;
-
-       fm = res->fctx.ctx_fm;
-       fm->fm_table_id = res->table;
-       oh = &fm->fm_oh;
-
-       if (ofp_validate(sc, &con->con_local, &con->con_peer,
-           oh, res->fbuf, oh->oh_version) != 0)
-               goto err;
-
-       ofrelay_write(con, res->fbuf);
-
-       return (0);
-
- err:
-       (void)oflowmod_err(&res->fctx, __func__, __LINE__);
-       log_warnx("invalid flow");
-       return (-1);
-}
-
-void
-ofpclient_read(struct switch_connection *con, int timeout)
-{
-       uint8_t                 rbuf[0xffff];
-       ssize_t                 rlen;
-       struct ofp_header       *oh;
-       struct ibuf             *ibuf;
-       struct pollfd            pfd[1];
-       int                      nfds;
-
-       /* Wait for response */
-       pfd[0].fd = con->con_fd;
-       pfd[0].events = POLLIN;
-       nfds = poll(pfd, 1, timeout);
-       if (nfds == -1 || (pfd[0].revents & (POLLERR|POLLHUP|POLLNVAL)))
-               fatal("poll error");
-       if (nfds == 0) {
-               if (timeout)
-                       fatal("time out");
-               return;
-       }
-
-       if ((rlen = read(con->con_fd, rbuf, sizeof(rbuf))) == -1)
-               fatal("read");
-       if (rlen == 0)
-               fatal("connection closed");
-
-       if ((ibuf = ibuf_new(rbuf, rlen)) == NULL)
-               fatal("ibuf_new");
-
-       if ((oh = ibuf_seek(ibuf, 0, sizeof(*oh))) == NULL)
-               fatal("short header");
-
-       if (ofp_validate(con->con_sc,
-           &con->con_peer, &con->con_local, oh, ibuf, oh->oh_version) != 0)
-               fatal("ofp_validate");
-
-       if (con->con_state == OFP_STATE_CLOSED) {
-               con->con_version = oh->oh_version;
-               ofp_recv_hello(con->con_sc, con, oh, ibuf);
-               con->con_state = OFP_STATE_ESTABLISHED;
-       }
-
-       ibuf_free(ibuf);
-}
-
-/*
- * stubs for ofp*.c
- */
-
-void
-ofrelay_write(struct switch_connection *con, struct ibuf *buf)
-{
-       struct msgbuf           msgbuf;
-
-       msgbuf_init(&msgbuf);
-       msgbuf.fd = con->con_fd;
-
-       ibuf_close(&msgbuf, buf);
-       ibuf_write(&msgbuf);
-}
-
-struct switch_control *
-switch_add(struct switch_connection *con)
-{
-       static struct switch_control sw;
-       con->con_switch = &sw;
-       return (&sw);
-}
-
-struct macaddr *
-switch_learn(struct switchd *sc, struct switch_control *sw,
-    uint8_t *ea, uint32_t port)
-{
-       return (NULL);
-}
-
-struct macaddr *
-switch_cached(struct switch_control *sw, uint8_t *ea)
-{
-       return (NULL);
-}
-
-int
-ofp_nextstate(struct switchd *sc, struct switch_connection *con,
-    enum ofp_state state)
-{
-       int             rv = 0;
-
-       switch (con->con_state) {
-       case OFP_STATE_CLOSED:
-               if (state != OFP_STATE_HELLO_WAIT)
-                       return (-1);
-               break;
-
-       case OFP_STATE_HELLO_WAIT:
-               if (state != OFP_STATE_FEATURE_WAIT)
-                       return (-1);
-
-               rv = ofp_send_featuresrequest(sc, con);
-               break;
-
-       case OFP_STATE_FEATURE_WAIT:
-               if (state != OFP_STATE_ESTABLISHED)
-                       return (-1);
-               break;
-
-       case OFP_STATE_ESTABLISHED:
-               if (state != OFP_STATE_CLOSED)
-                       return (-1);
-               break;
-
-       default:
-               return (-1);
-       }
-
-       /* Set the next state. */
-       con->con_state = state;
-
-       return (rv);
-}
diff --git a/usr.sbin/switchctl/parser.c b/usr.sbin/switchctl/parser.c
deleted file mode 100644 (file)
index 01657a9..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*     $OpenBSD: parser.c,v 1.10 2018/10/21 21:10:24 akoshibe Exp $    */
-
-/*
- * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <event.h>
-#include <netdb.h>
-
-#include "switchd.h"
-#include "ofp_map.h"
-#include "parser.h"
-
-enum token_type {
-       NOTOKEN,
-       ENDTOKEN,
-       KEYWORD,
-       PATH,
-       ADDRESS,
-       URI,
-       TABLE,
-       FLOWADD,
-       FLOWDELETE,
-       FLOWMODIFY,
-       FLOWAPPLY,
-       FLOWWRITE,
-       FLOWMATCH,
-       MATCHINPORT,
-       ACTIONOUTPUT,
-};
-
-struct token {
-       enum token_type          type;
-       const char              *keyword;
-       int                      value;
-       const struct token      *next;
-};
-
-static const struct token t_main[];
-static const struct token t_reset[];
-static const struct token t_log[];
-static const struct token t_load[];
-static const struct token t_show[];
-static const struct token t_switch[];
-#if 0
-static const struct token t_switchreq[];
-#endif
-static const struct token t_table[];
-static const struct token t_dump[];
-static const struct token t_flow[];
-static const struct token t_flowmod[];
-static const struct token t_flowmatch[];
-static const struct token t_matchinport[];
-static const struct token t_flowaction[];
-static const struct token t_actionoutput[];
-static const struct token t_connect[];
-static const struct token t_disconnect[];
-static const struct token t_forward_to[];
-static const struct token t_uri[];
-
-static const struct token t_main[] = {
-       { KEYWORD,      "connect",      CONNECT,        t_connect },
-       { KEYWORD,      "disconnect",   DISCONNECT,     t_disconnect },
-       { KEYWORD,      "dump",         NONE,           t_dump },
-       { KEYWORD,      "flow",         NONE,           t_flow },
-       { KEYWORD,      "load",         LOAD,           t_load },
-       { KEYWORD,      "log",          NONE,           t_log },
-       { KEYWORD,      "monitor",      MONITOR,        NULL },
-       { KEYWORD,      "reload",       RELOAD,         NULL },
-       { KEYWORD,      "reset",        NONE,           t_reset },
-       { KEYWORD,      "show",         NONE,           t_show },
-       { KEYWORD,      "switch",       NONE,           t_switch },
-       { KEYWORD,      "table",        NONE,           t_table },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_log[] = {
-       { KEYWORD,      "verbose",      LOG_VERBOSE,    NULL },
-       { KEYWORD,      "brief",        LOG_BRIEF,      NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_reset[] = {
-       { KEYWORD,      "all",          RESETALL,       NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_load[] = {
-       { PATH,         "",             NONE,           NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token  t_table[] = {
-       { TABLE,        "",             NONE,           t_main },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token  t_switch[] = {
-       { URI,          "",             NONE,           t_main },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-#if 0
-static const struct token  t_switchreq[] = {
-       { KEYWORD,      "dump",         NONE,           t_dump },
-       { KEYWORD,      "flow",         NONE,           t_flow },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-#endif
-
-static const struct token t_dump[] = {
-       { KEYWORD,      "desc",         DUMP_DESC,      NULL },
-       { KEYWORD,      "features",     DUMP_FEATURES,  NULL },
-       { KEYWORD,      "flows",        DUMP_FLOWS,     NULL },
-       { KEYWORD,      "tables",       DUMP_TABLES,    NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_flow[] = {
-       { FLOWADD,      "add",          FLOW_ADD,       t_flowmod },
-       { FLOWDELETE,   "delete",       FLOW_DELETE,    t_flowmod },
-       { FLOWMODIFY,   "modify",       FLOW_MODIFY,    t_flowmod },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_flowmod[] = {
-       { NOTOKEN,      "",             NONE,           NULL },
-       { FLOWAPPLY,    "apply",        NONE,           t_flowaction },
-       { FLOWWRITE,    "write",        NONE,           t_flowaction },
-       { FLOWMATCH,    "match",        NONE,           t_flowmatch },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_flowmatch[] = {
-       { NOTOKEN,      "",             NONE,           t_flowmod },
-       { KEYWORD,      "inport",       NONE,           t_matchinport },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_matchinport[] = {
-       { MATCHINPORT,  "",             NONE,           t_flowmatch },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_flowaction[] = {
-       { NOTOKEN,      "",             NONE,           t_flowmod },
-       { KEYWORD,      "output",       NONE,           t_actionoutput },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_actionoutput[] = {
-       { ACTIONOUTPUT, "",             NONE,           t_flowaction },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_show[] = {
-       { KEYWORD,      "summary",      SHOW_SUM,       NULL },
-       { KEYWORD,      "switches",     SHOW_SWITCHES,  NULL },
-       { KEYWORD,      "macs",         SHOW_MACS,      NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token t_connect[] = {
-       { ADDRESS,      "",             NONE,           t_forward_to },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-static const struct token t_disconnect[] = {
-       { ADDRESS,      "",             NONE,           NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-static const struct token t_forward_to[] = {
-       { NOTOKEN,      "",             NONE,           NULL },
-       { KEYWORD,      "forward-to",   NONE,           t_uri },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static const struct token  t_uri[] = {
-       { URI,          "",             NONE,           NULL },
-       { ENDTOKEN,     "",             NONE,           NULL }
-};
-
-static struct parse_result      res;
-
-const struct token     *match_token(char *, const struct token [], int);
-void                    show_valid_args(const struct token [], int);
-int                     parse_addr(const char *,
-                           struct sockaddr_storage *);
-
-struct parse_result *
-parse(int argc, char *argv[])
-{
-       const struct token      *table = t_main;
-       const struct token      *match;
-
-       bzero(&res, sizeof(res));
-
-       res.table = OFP_TABLE_ID_ALL;
-
-       while (argc >= 0) {
-               if ((match = match_token(argv[0], table, 0)) == NULL) {
-                       fprintf(stderr, "valid commands/args:\n");
-                       show_valid_args(table, 0);
-                       return (NULL);
-               }
-
-               argc--;
-               argv++;
-
-               if (match->type == NOTOKEN || match->next == NULL)
-                       break;
-
-               table = match->next;
-       }
-
-       if (argc > 0) {
-               fprintf(stderr, "superfluous argument: %s\n", argv[0]);
-               return (NULL);
-       }
-
-       return (&res);
-}
-
-int
-parse_addr(const char *word, struct sockaddr_storage *ss)
-{
-       struct addrinfo          hints, *ai;
-       struct sockaddr_un      *un;
-
-       memset(ss, 0, sizeof(*ss));
-
-       /* device */
-       if (*word == '/') {
-               un = (struct sockaddr_un *)ss;
-               if (strlcpy(un->sun_path, word, sizeof(un->sun_path)) >=
-                   sizeof(un->sun_path)) {
-                       warnx("invalid path");
-                       return (-1);
-               }
-               un->sun_family = AF_LOCAL;
-               un->sun_len = sizeof(*un);
-               return (0);
-       }
-
-       /* address */
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_socktype = SOCK_DGRAM; /* dummy */
-       hints.ai_family = PF_UNSPEC;
-       hints.ai_flags = AI_NUMERICHOST;
-       if (getaddrinfo(word, "0", &hints, &ai) == 0) {
-               memcpy(ss, ai->ai_addr, ai->ai_addrlen);
-               ss->ss_len = ai->ai_addrlen;
-               freeaddrinfo(ai);
-               return (0);
-       }
-
-       /* FQDN */
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_socktype = SOCK_DGRAM; /* dummy */
-       hints.ai_family = PF_UNSPEC;
-       hints.ai_flags = AI_ADDRCONFIG;
-       if (getaddrinfo(word, "0", &hints, &ai) == 0) {
-               /* Pick first name only */
-               memcpy(ss, ai->ai_addr, ai->ai_addrlen);
-               ss->ss_len = ai->ai_addrlen;
-               freeaddrinfo(ai);
-               return (0);
-       }
-
-       return (-1);
-}
-
-
-const struct token *
-match_token(char *word, const struct token table[], int level)
-{
-       unsigned int             i, j, match = 0;
-       int64_t                  val;
-       struct constmap         *cm;
-       const char              *errstr = NULL;
-       const struct token      *t = NULL;
-       size_t                   len;
-
-       for (i = 0; table[i].type != ENDTOKEN; i++) {
-               switch (table[i].type) {
-               case NOTOKEN:
-                       if (word == NULL || strlen(word) == 0) {
-                               match++;
-                               t = &table[i];
-                       }
-                       break;
-               case KEYWORD:
-               case FLOWADD:
-               case FLOWDELETE:
-               case FLOWMODIFY:
-               case FLOWMATCH:
-               case FLOWAPPLY:
-               case FLOWWRITE:
-                       if (word != NULL && strncmp(word, table[i].keyword,
-                           strlen(word)) == 0) {
-                               match++;
-                               t = &table[i];
-                               if (t->value)
-                                       res.action = t->value;
-                               switch (table[i].type) {
-                               case FLOWADD:
-                               case FLOWDELETE:
-                               case FLOWMODIFY:
-                                       if ((res.fbuf =
-                                           oflowmod_open(&res.fctx,
-                                           NULL, NULL, 0)) == NULL)
-                                               goto flowerr;
-
-                                       /* Update header */
-                                       if (table[i].type == FLOWDELETE)
-                                               res.fctx.ctx_fm->fm_command =
-                                                   OFP_FLOWCMD_DELETE;
-                                       else if (table[i].type == FLOWMODIFY)
-                                               res.fctx.ctx_fm->fm_command =
-                                                   OFP_FLOWCMD_MODIFY;
-                                       break;
-                               case FLOWAPPLY:
-                                       val = OFP_INSTRUCTION_T_APPLY_ACTIONS;
-                                       if (oflowmod_instruction(&res.fctx,
-                                           val) == -1)
-                                               goto flowerr;
-                                       break;
-                               case FLOWWRITE:
-                                       val = OFP_INSTRUCTION_T_WRITE_ACTIONS;
-                                       if (oflowmod_instruction(&res.fctx,
-                                           val) == -1)
-                                               goto flowerr;
-                                       break;
-                               case FLOWMATCH:
-                                       if (oflowmod_mopen(&res.fctx) == -1)
-                                               goto flowerr;
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case MATCHINPORT:
-               case ACTIONOUTPUT:
-                       if (!match && word != NULL && strlen(word) > 0) {
-                               match++;
-                               t = &table[i];
-
-                               val = -1;
-
-                               /* Is the port a keyword? */
-                               cm = ofp_port_map;
-                               for (j = 0; cm[j].cm_name != NULL; j++) {
-                                       if (strcasecmp(cm[j].cm_name,
-                                           word) == 0) {
-                                               val = cm[j].cm_type;
-                                               break;
-                                       }
-                               }
-
-                               /* Is the port a number? */
-                               if (val == -1) {
-                                       val = strtonum(word, 1,
-                                           UINT32_MAX, &errstr);
-                                       if (errstr != NULL)
-                                               val = -1;
-                               }
-
-                               if (val == -1) {
-                                       fprintf(stderr,
-                                           "could not parse port:"
-                                           " %s\n", word);
-                                       return (NULL);
-                               }
-
-                               switch (table[i].type) {
-                               case MATCHINPORT:
-                                       if (oxm_inport(res.fbuf, val) == -1)
-                                               goto flowerr;
-                                       break;
-                               case ACTIONOUTPUT:
-                                       if (action_output(res.fbuf, val,
-                                           OFP_CONTROLLER_MAXLEN_MAX) == -1)
-                                               goto flowerr;
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case PATH:
-                       if (!match && word != NULL && strlen(word) > 0) {
-                               res.path = strdup(word);
-                               match++;
-                               t = &table[i];
-                       }
-                       break;
-               case ADDRESS:
-                       if (!match && word != NULL && strlen(word) > 0) {
-                               parse_addr(word, &res.addr);
-                               match++;
-                               t = &table[i];
-                       }
-                       break;
-               case TABLE:
-                       if (word == NULL)
-                               break;
-                       res.table = strtonum(word, 0,
-                           OFP_TABLE_ID_MAX, &errstr);
-                       if (errstr)
-                               res.table = OFP_TABLE_ID_ALL;
-                       t = &table[i];
-                       match++;
-                       break;
-               case URI:
-                       if (!match && word != NULL && strlen(word) > 0) {
-                               len = 4;
-                               if (strncmp(word, "tcp:", len) == 0)
-                                       res.uri.swa_type = SWITCH_CONN_TCP;
-                               else if (strncmp(word, "tls:", len) == 0)
-                                       res.uri.swa_type = SWITCH_CONN_TLS;
-                               else if (strncmp(word, "/dev", len) == 0) {
-                                       res.uri.swa_type = SWITCH_CONN_LOCAL;
-                                       parse_addr(word, &res.uri.swa_addr);
-                                       match++;
-                                       t = &table[i];
-                                       break;
-                               } else {
-                                       /* set the default */
-                                       res.uri.swa_type = SWITCH_CONN_TCP;
-                                       len = 0;
-                               }
-                               if (parsehostport(word + len,
-                                   (struct sockaddr *)&res.uri.swa_addr,
-                                   sizeof(res.uri.swa_addr)) != 0) {
-                                       fprintf(stderr,
-                                           "could not parse address: %s\n",
-                                           word);
-                                       return (NULL);
-                               }
-                               match++;
-                               t = &table[i];
-                       }
-                       break;
-               case ENDTOKEN:
-                       break;
-               }
-       }
-
-       if (match != 1) {
-               if (word == NULL)
-                       fprintf(stderr, "missing argument:\n");
-               else if (match > 1)
-                       fprintf(stderr, "ambiguous argument: %s\n", word);
-               else if (match < 1) {
-                       if (level == 0 &&
-                           table[0].type == NOTOKEN && table[0].next)
-                               return (match_token(word, table[0].next, 1));
-                       else
-                               fprintf(stderr, "unknown argument: %s\n", word);
-               }
-               return (NULL);
-       }
-
-       return (t);
-
- flowerr:
-       (void)oflowmod_err(&res.fctx, __func__, __LINE__);
-       fprintf(stderr, "flow invalid\n");
-       return (NULL);
-}
-
-void
-show_valid_args(const struct token table[], int level)
-{
-       int     i;
-
-       for (i = 0; table[i].type != ENDTOKEN; i++) {
-               switch (table[i].type) {
-               case NOTOKEN:
-                       if (level == 0)
-                               fprintf(stderr, "  <cr>\n");
-                       break;
-               case KEYWORD:
-               case FLOWADD:
-               case FLOWDELETE:
-               case FLOWMODIFY:
-               case FLOWMATCH:
-               case FLOWAPPLY:
-               case FLOWWRITE:
-                       fprintf(stderr, "  %s\n", table[i].keyword);
-                       break;
-               case MATCHINPORT:
-               case ACTIONOUTPUT:
-                       fprintf(stderr, "  <port>\n");
-                       break;
-               case PATH:
-                       fprintf(stderr, "  <path>\n");
-                       break;
-               case ADDRESS:
-                       fprintf(stderr, "  <address>\n");
-                       break;
-               case TABLE:
-                       fprintf(stderr, "  <table>\n");
-                       break;
-               case URI:
-                       fprintf(stderr, "  <uri>\n");
-                       break;
-               case ENDTOKEN:
-                       break;
-               }
-       }
-
-       if (level == 0 && table[0].type == NOTOKEN && table[0].next)
-               return (show_valid_args(table[0].next, 1));
-}
diff --git a/usr.sbin/switchctl/parser.h b/usr.sbin/switchctl/parser.h
deleted file mode 100644 (file)
index 83fb489..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*     $OpenBSD: parser.h,v 1.4 2016/11/24 09:23:11 reyk Exp $ */
-
-/*
- * Copyright (c) 2007-2015 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _SWITCHCTL_PARSER_H
-#define _SWITCHCTL_PARSER_H
-
-enum actions {
-       NONE,
-       FLOW_ADD,
-       FLOW_DELETE,
-       FLOW_MODIFY,
-       DUMP_DESC,
-       DUMP_FEATURES,
-       DUMP_FLOWS,
-       DUMP_TABLES,
-       SHOW_SUM,
-       SHOW_SWITCHES,
-       SHOW_MACS,
-       LOAD,
-       RELOAD,
-       MONITOR,
-       LOG_VERBOSE,
-       LOG_BRIEF,
-       RESETALL,
-       CONNECT,
-       DISCONNECT
-};
-
-struct parse_result {
-       enum actions             action;
-       struct imsgbuf          *ibuf;
-       char                    *path;
-       struct switch_address    uri;
-       struct sockaddr_storage  addr;
-       struct oflowmod_ctx      fctx;
-       struct ibuf             *fbuf;
-       int                      table;
-       int                      quiet;
-       int                      verbose;
-};
-
-#define HOST_IPADDR    1
-#define HOST_FQDN      2
-
-struct parse_result    *parse(int, char *[]);
-void                    ofpclient(struct parse_result *, struct passwd *);
-
-#endif /* _SWITCHCTL_PARSER_H */
diff --git a/usr.sbin/switchctl/switchctl.8 b/usr.sbin/switchctl/switchctl.8
deleted file mode 100644 (file)
index 9874e7a..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-.\" $OpenBSD: switchctl.8,v 1.6 2018/10/21 21:10:24 akoshibe Exp $
-.\"
-.\" Copyright (c) 2007-2015 Reyk Floeter <reyk@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: October 21 2018 $
-.Dt SWITCHCTL 8
-.Os
-.Sh NAME
-.Nm switchctl
-.Nd control the SDN flow controller
-.Sh SYNOPSIS
-.Nm
-.Op Fl q
-.Op Fl s Ar socket
-.Ar command
-.Op Ar arg ...
-.Sh DESCRIPTION
-The
-.Nm
-program controls the
-.Xr switchd 8
-daemon.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl q
-Don't ask for confirmation of any default options.
-.It Fl s Ar socket
-Use
-.Ar socket
-instead of the default
-.Pa /var/run/switchd.sock
-to communicate with
-.Xr switchd 8 .
-.El
-.Pp
-The following commands are available to control
-.Xr switchd 8 :
-.Bl -tag -width Ds
-.It Cm connect Ar address Op Cm forward-to Ar address
-Connect to a new switch by
-.Ar address ,
-for example
-.Ar 10.1.1.1 ,
-or a
-.Xr switch 4
-control device, for example
-.Pa /dev/switch0 .
-.Nm switchd
-will forward all OpenFlow requests of the switch to a remote controller
-if the optional
-.Cm forward-to
-.Ar address
-is specified.
-.It Cm disconnect Ar address
-Close the client connection to a remote switch or a
-.Xr switch 4
-control device.
-.It Cm dump Ar address request
-Request information from a remote switch or a
-.Xr switch 4
-control device.
-.Nm
-will send an OpenFlow request to the remote switch that is specified by
-.Ar address .
-The
-.Ar request
-can be one of the following:
-.Pp
-.Bl -tag -width features -offset indent -compact
-.It Cm desc
-Request the switch description.
-.It Cm features
-Request the switch features.
-.It Cm flows
-Request the tables and flows.
-.It Cm tables
-Request the tables.
-.El
-.It Cm load Ar filename address
-Reload the configuration from the specified file.
-.It Cm log brief
-Disable verbose logging.
-.It Cm log verbose
-Enable verbose logging.
-.It Cm monitor
-Monitor internal messages of the
-.Xr switchd 8
-subsystems.
-.It Cm reload
-Reload the configuration from the default configuration file.
-.It Cm reset all
-Reset the running state.
-.It Cm show macs
-Display all known mac addresses.
-.It Cm show summary
-Display a list of all switches and mac addresses.
-.It Cm show switches
-Display all known switches.
-.El
-.Sh FILES
-.Bl -tag -width "/var/run/switchd.sockXX" -compact
-.It /etc/switchd.conf
-Active configuration.
-.It /var/run/switchd.sock
-default
-.Ux Ns -domain
-socket used for communication with
-.Xr switchd 8
-.El
-.Sh SEE ALSO
-.Xr bridge 4 ,
-.Xr switchd.conf 5 ,
-.Xr switchd 8
-.Sh HISTORY
-The
-.Nm
-program first appeared in
-.Ox 6.1 .
-.Sh AUTHORS
-The
-.Nm
-program was written by
-.An Reyk Floeter Aq Mt reyk@openbsd.org .
diff --git a/usr.sbin/switchctl/switchctl.c b/usr.sbin/switchctl/switchctl.c
deleted file mode 100644 (file)
index d101778..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*     $OpenBSD: switchctl.c,v 1.9 2018/10/24 18:06:21 akoshibe Exp $  */
-
-/*
- * Copyright (c) 2007-2015 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
- * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/queue.h>
-#include <sys/un.h>
-#include <sys/tree.h>
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <event.h>
-#include <pwd.h>
-
-#include "switchd.h"
-#include "parser.h"
-
-__dead void     usage(void);
-
-struct imsgname {
-       int type;
-       char *name;
-       void (*func)(struct imsg *);
-};
-
-int             show_summary_msg(struct imsg *, int);
-
-struct imsgname *monitor_lookup(uint8_t);
-void            monitor_id(struct imsg *);
-int             monitor(struct imsg *);
-
-int             ca_opt(struct parse_result *);
-
-struct imsgname imsgs[] = {
-       { IMSG_CTL_OK,                  "ok",                   NULL },
-       { IMSG_CTL_FAIL,                "fail",                 NULL },
-       { IMSG_CTL_VERBOSE,             "verbose",              NULL },
-       { IMSG_CTL_RELOAD,              "reload",               NULL },
-       { IMSG_CTL_RESET,               "reset",                NULL },
-       { 0,                            NULL,                   NULL }
-
-};
-struct imsgname imsgunknown = {
-       -1,                             "<unknown>",            NULL
-};
-
-struct imsgbuf *ibuf;
-
-__dead void
-usage(void)
-{
-       extern char *__progname;
-
-       fprintf(stderr, "usage: %s [-q] [-s socket] command [arg ...]\n",
-           __progname);
-       exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
-       struct sockaddr_un       sun;
-       struct parse_result     *res;
-       struct imsg              imsg;
-       struct switch_client     swc;
-       struct switch_address   *to;
-       struct passwd           *pw;
-       int                      ctl_sock;
-       int                      done = 1;
-       int                      n;
-       int                      ch;
-       int                      v = 0;
-       int                      quiet = 0;
-       int                      verbose = 0;
-       const char              *sock = SWITCHD_SOCKET;
-
-       while ((ch = getopt(argc, argv, "qs:v")) != -1) {
-               switch (ch) {
-               case 'q':
-                       quiet = 1;
-                       break;
-               case 's':
-                       sock = optarg;
-                       break;
-               case 'v':
-                       verbose = 2;
-                       break;
-               default:
-                       usage();
-                       /* NOTREACHED */
-               }
-       }
-       argc -= optind;
-       argv += optind;
-
-       if ((pw = getpwnam(SWITCHD_USER)) == NULL)
-               fatal("switchctl: getpwnam");
-
-       /*
-        * pledge in switchctl:
-        * stdio - for malloc and basic I/O including events.
-        * rpath - for reading from the /dev/switch device.
-        * wpath - for accessing the /dev/switch device.
-        * inet - for handling tcp connections with OpenFlow peers.
-        * unix - for opening the control socket.
-        * dns - for parsehostport() in the device spec.
-        */
-       if (pledge("stdio rpath wpath inet unix dns", NULL) == -1)
-               err(1, "pledge");
-
-       log_init(quiet ? 0 : 2, LOG_USER);
-
-       /* parse options */
-       if ((res = parse(argc, argv)) == NULL)
-               exit(1);
-
-       res->quiet = quiet;
-       res->verbose = verbose;
-
-       if (res->quiet && res->verbose)
-               fatal("conflicting -v and -q options");
-
-       switch (res->action) {
-       case NONE:
-               usage();
-               break;
-       case DUMP_DESC:
-       case DUMP_FEATURES:
-       case DUMP_FLOWS:
-       case DUMP_TABLES:
-       case FLOW_ADD:
-       case FLOW_DELETE:
-       case FLOW_MODIFY:
-               ofpclient(res, pw);
-               break;
-       default:
-               goto connect;
-       }
-
-       return (0);
-
- connect:
-       /* connect to sdnflowd control socket */
-       if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
-               err(1, "socket");
-
-       bzero(&sun, sizeof(sun));
-       sun.sun_family = AF_UNIX;
-       strlcpy(sun.sun_path, sock, sizeof(sun.sun_path));
- reconnect:
-       if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
-               /* Keep retrying if running in monitor mode */
-               if (res->action == MONITOR &&
-                   (errno == ENOENT || errno == ECONNREFUSED)) {
-                       usleep(100);
-                       goto reconnect;
-               }
-               err(1, "connect: %s", sock);
-       }
-
-       if (pledge("stdio", NULL) == -1)
-               err(1, "pledge");
-
-       if (res->ibuf != NULL)
-               ibuf = res->ibuf;
-       else
-               if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
-                       err(1, "malloc");
-       imsg_init(ibuf, ctl_sock);
-
-       /* process user request */
-       switch (res->action) {
-       case RESETALL:
-               v = RESET_ALL;
-               break;
-       case LOG_VERBOSE:
-               v = 2;
-               break;
-       case LOG_BRIEF:
-       default:
-               v = 0;
-               break;
-       }
-
-       switch (res->action) {
-       case NONE:
-               usage();
-               /* NOTREACHED */
-               break;
-       case SHOW_SUM:
-       case SHOW_SWITCHES:
-       case SHOW_MACS:
-               imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
-               printf("%-4s\t%-4s\t%-8s\t%-24s\t%s\n",
-                   "Switch", "Port", "Type", "Name", "Info");
-               done = 0;
-               break;
-       case CONNECT:
-       case DISCONNECT:
-               memset(&swc, 0, sizeof(swc));
-               if (res->addr.ss_family == AF_UNSPEC)
-                       errx(1, "invalid address");
-
-               memcpy(&swc.swc_addr.swa_addr, &res->addr, sizeof(res->addr));
-               if (res->action == DISCONNECT) {
-                       imsg_compose(ibuf, IMSG_CTL_DISCONNECT, 0, 0, -1,
-                           &swc, sizeof(swc));
-                       break;
-               }
-
-               to = &swc.swc_target;
-               memcpy(to, &res->uri, sizeof(*to));
-
-               imsg_compose(ibuf, IMSG_CTL_CONNECT, 0, 0, -1,
-                   &swc, sizeof(swc));
-               break;
-       case RESETALL:
-               imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1, &v, sizeof(v));
-               printf("reset request sent.\n");
-               break;
-       case LOAD:
-               imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1,
-                   res->path, strlen(res->path));
-               break;
-       case RELOAD:
-               imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
-               break;
-       case MONITOR:
-               imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0);
-               done = 0;
-               break;
-       case LOG_VERBOSE:
-       case LOG_BRIEF:
-               imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &v, sizeof(v));
-               printf("logging request sent.\n");
-               break;
-       default:
-               break;
-       }
-
-       while (ibuf->w.queued)
-               if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
-                       err(1, "write error");
-
-       while (!done) {
-               if ((n = imsg_read(ibuf)) == -1)
-                       errx(1, "imsg_read error");
-               if (n == 0)
-                       errx(1, "pipe closed");
-
-               while (!done) {
-                       if ((n = imsg_get(ibuf, &imsg)) == -1)
-                               errx(1, "imsg_get error");
-                       if (n == 0)
-                               break;
-                       switch (res->action) {
-                       case SHOW_SUM:
-                       case SHOW_SWITCHES:
-                       case SHOW_MACS:
-                               done = show_summary_msg(&imsg, res->action);
-                               break;
-                       case MONITOR:
-                               done = monitor(&imsg);
-                               break;
-                       default:
-                               break;
-                       }
-                       imsg_free(&imsg);
-               }
-       }
-       close(ctl_sock);
-       free(ibuf);
-
-       return (0);
-}
-
-int
-show_summary_msg(struct imsg *imsg, int type)
-{
-       struct switch_control   *sw;
-       struct macaddr          *mac;
-       struct timeval           tv;
-       static unsigned int      sw_id = 0;
-
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SWITCH:
-               IMSG_SIZE_CHECK(imsg, sw);
-               sw = imsg->data;
-               sw_id = sw->sw_id;
-
-               if (!(type == SHOW_SUM || type == SHOW_SWITCHES))
-                       break;
-               printf("%-4u\t%-4s\t%-8s\t%-24s\n",
-                   sw->sw_id, "", "switch",
-                   print_host(&sw->sw_addr, NULL, 0));
-               break;
-       case IMSG_CTL_MAC:
-               IMSG_SIZE_CHECK(imsg, mac);
-               mac = imsg->data;
-
-               if (!(type == SHOW_SUM || type == SHOW_MACS))
-                       break;
-
-               getmonotime(&tv);
-               printf("%-4u\t%-4u\t%-8s\t%-24s\tage %llds\n",
-                   sw_id, mac->mac_port, "mac",
-                   print_ether(mac->mac_addr),
-                   (long long)tv.tv_sec - mac->mac_age);
-               break;
-       case IMSG_CTL_END:
-               return (1);
-       default:
-               errx(1, "wrong message in summary: %u", imsg->hdr.type);
-               break;
-       }
-       return (0);
-}
-
-struct imsgname *
-monitor_lookup(uint8_t type)
-{
-       int i;
-
-       for (i = 0; imsgs[i].name != NULL; i++)
-               if (imsgs[i].type == type)
-                       return (&imsgs[i]);
-       return (&imsgunknown);
-}
-
-int
-monitor(struct imsg *imsg)
-{
-       time_t                   now;
-       int                      done = 0;
-       struct imsgname         *imn;
-
-       now = time(NULL);
-
-       imn = monitor_lookup(imsg->hdr.type);
-       printf("%s: imsg type %u len %u peerid %u pid %d\n", imn->name,
-           imsg->hdr.type, imsg->hdr.len, imsg->hdr.peerid, imsg->hdr.pid);
-       printf("\ttimestamp: %lld, %s", (long long)now, ctime(&now));
-       if (imn->type == -1)
-               done = 1;
-       if (imn->func != NULL)
-               (*imn->func)(imsg);
-
-       return (done);
-}
diff --git a/usr.sbin/switchd/Makefile b/usr.sbin/switchd/Makefile
deleted file mode 100644 (file)
index 7312b73..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# $OpenBSD: Makefile,v 1.8 2017/07/06 12:15:23 espie Exp $
-
-PROG=          switchd
-MAN=           switchd.8 switchd.conf.5
-
-SRCS=          imsg_util.c log.c packet.c proc.c switch.c timer.c util.c
-SRCS+=         switchd.c control.c ofp.c ofp10.c ofp13.c ofp_common.c ofrelay.c
-SRCS+=         ${.OBJDIR}/ofp_map.c ${.OBJDIR}/ofp10_map.c
-SRCS+=         parse.y ofcconn.c
-
-LDADD=         -levent -lutil
-DPADD=         ${LIBEVENT} ${LIBUTIL}
-
-CFLAGS+=       -Wall -I${.CURDIR} -I${.CURDIR}/../switchd
-CFLAGS+=       -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+=       -Wmissing-declarations
-CFLAGS+=       -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+=       -Wsign-compare
-
-GENERATED=     ofp_map.c ofp10_map.c
-CLEANFILES+=   ${GENERATED}
-YFLAGS=
-
-ofp_map.c: genmap.sh ${.CURDIR}/ofp_map.h ${.CURDIR}/../../sys/net/ofp.h
-       /bin/sh ${.CURDIR}/genmap.sh -i ${.CURDIR}/../../sys/net/ofp.h -t ofp \
-           -m ${.CURDIR}/ofp_map.h -h '<net/ofp.h>' > $@
-       @touch $@
-
-ofp10_map.c: genmap.sh ${.CURDIR}/ofp_map.h ${.CURDIR}/ofp10.h
-       /bin/sh ${.CURDIR}/genmap.sh -i ${.CURDIR}/ofp10.h -t ofp10 \
-           -m ${.CURDIR}/ofp_map.h -h '"ofp10.h"' > $@
-       @touch $@
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/switchd/control.c b/usr.sbin/switchd/control.c
deleted file mode 100644 (file)
index 50ceb10..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/*     $OpenBSD: control.c,v 1.10 2021/04/20 21:11:56 dv Exp $ */
-
-/*
- * Copyright (c) 2010-2016 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/tree.h>
-
-#include <net/if.h>
-
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <imsg.h>
-
-#include "proc.h"
-#include "switchd.h"
-
-#define        CONTROL_BACKLOG 5
-
-struct ctl_connlist ctl_conns = TAILQ_HEAD_INITIALIZER(ctl_conns);
-
-void
-        control_accept(int, short, void *);
-struct ctl_conn
-       *control_connbyfd(int);
-void    control_close(int, struct control_sock *);
-void    control_dispatch_imsg(int, short, void *);
-void    control_imsg_forward(struct imsg *);
-void    control_run(struct privsep *, struct privsep_proc *, void *);
-
-int     control_dispatch_ofp(int, struct privsep_proc *, struct imsg *);
-
-static struct privsep_proc procs[] = {
-       { "ofp",        PROC_OFP,       control_dispatch_ofp },
-       { "parent",     PROC_PARENT,    NULL },
-       { "ofcconn",    PROC_OFCCONN,   NULL }
-};
-
-void
-control(struct privsep *ps, struct privsep_proc *p)
-{
-       proc_run(ps, p, procs, nitems(procs), control_run, NULL);
-}
-
-void
-control_run(struct privsep *ps, struct privsep_proc *p, void *arg)
-{
-       /*
-        * pledge in the control process:
-        * stdio - for malloc and basic I/O including events.
-        * unix - for the control socket.
-        * recvfd - for the proc fd exchange.
-        */
-       if (pledge("stdio unix recvfd", NULL) == -1)
-               fatal("pledge");
-}
-
-int
-control_dispatch_ofp(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       int              cfd;
-       struct ctl_conn *c;
-       uint8_t         *d = imsg->data;
-       size_t           s;
-
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SWITCH:
-       case IMSG_CTL_MAC:
-               IMSG_SIZE_CHECK(imsg, &cfd);
-               memcpy(&cfd, d, sizeof(cfd));
-
-               if ((c = control_connbyfd(cfd)) == NULL)
-                       fatalx("invalid control connection");
-
-               s = IMSG_DATA_SIZE(imsg) - sizeof(cfd);
-               d += sizeof(cfd);
-               imsg_compose_event(&c->iev, imsg->hdr.type, 0, 0, -1, d, s);
-               return (0);
-       case IMSG_CTL_END:
-               IMSG_SIZE_CHECK(imsg, &cfd);
-               memcpy(&cfd, d, sizeof(cfd));
-
-               if ((c = control_connbyfd(cfd)) == NULL)
-                       fatalx("invalid control connection");
-
-               imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
-               return (0);
-
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-int
-control_init(struct privsep *ps, struct control_sock *cs)
-{
-       struct switchd          *env = ps->ps_env;
-       struct sockaddr_un       sun;
-       int                      fd;
-       mode_t                   old_umask, mode;
-
-       if (cs->cs_name == NULL)
-               return (0);
-
-       if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
-               log_warn("%s: socket", __func__);
-               return (-1);
-       }
-
-       sun.sun_family = AF_UNIX;
-       if (strlcpy(sun.sun_path, cs->cs_name,
-           sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
-               log_warn("%s: %s name too long", __func__, cs->cs_name);
-               close(fd);
-               return (-1);
-       }
-
-       if (unlink(cs->cs_name) == -1)
-               if (errno != ENOENT) {
-                       log_warn("%s: unlink %s", __func__, cs->cs_name);
-                       close(fd);
-                       return (-1);
-               }
-
-       if (cs->cs_restricted) {
-               old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
-               mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
-       } else {
-               old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
-               mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
-       }
-
-       if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
-               log_warn("%s: bind: %s", __func__, cs->cs_name);
-               close(fd);
-               (void)umask(old_umask);
-               return (-1);
-       }
-       (void)umask(old_umask);
-
-       if (chmod(cs->cs_name, mode) == -1) {
-               log_warn("%s: chmod", __func__);
-               close(fd);
-               (void)unlink(cs->cs_name);
-               return (-1);
-       }
-
-       socket_set_blockmode(fd, BM_NONBLOCK);
-       cs->cs_fd = fd;
-       cs->cs_env = env;
-
-       return (0);
-}
-
-int
-control_listen(struct control_sock *cs)
-{
-       if (cs->cs_name == NULL)
-               return (0);
-
-       if (listen(cs->cs_fd, CONTROL_BACKLOG) == -1) {
-               log_warn("%s: listen", __func__);
-               return (-1);
-       }
-
-       event_set(&cs->cs_ev, cs->cs_fd, EV_READ,
-           control_accept, cs);
-       event_add(&cs->cs_ev, NULL);
-       evtimer_set(&cs->cs_evt, control_accept, cs);
-
-       return (0);
-}
-
-/* ARGSUSED */
-void
-control_accept(int listenfd, short event, void *arg)
-{
-       struct control_sock     *cs = arg;
-       int                      connfd;
-       socklen_t                len;
-       struct sockaddr_un       sun;
-       struct ctl_conn         *c;
-
-       event_add(&cs->cs_ev, NULL);
-       if ((event & EV_TIMEOUT))
-               return;
-
-       len = sizeof(sun);
-       if ((connfd = accept(listenfd,
-           (struct sockaddr *)&sun, &len)) == -1) {
-               /*
-                * Pause accept if we are out of file descriptors, or
-                * libevent will haunt us here too.
-                */
-               if (errno == ENFILE || errno == EMFILE) {
-                       struct timeval evtpause = { 1, 0 };
-
-                       event_del(&cs->cs_ev);
-                       evtimer_add(&cs->cs_evt, &evtpause);
-               } else if (errno != EWOULDBLOCK && errno != EINTR &&
-                   errno != ECONNABORTED)
-                       log_warn("%s: accept", __func__);
-               return;
-       }
-
-       socket_set_blockmode(connfd, BM_NONBLOCK);
-
-       if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
-               log_warn("%s", __func__);
-               close(connfd);
-               return;
-       }
-
-       imsg_init(&c->iev.ibuf, connfd);
-       c->iev.handler = control_dispatch_imsg;
-       c->iev.events = EV_READ;
-       c->iev.data = cs;
-       event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
-           c->iev.handler, c->iev.data);
-       event_add(&c->iev.ev, NULL);
-
-       TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
-}
-
-struct ctl_conn *
-control_connbyfd(int fd)
-{
-       struct ctl_conn *c;
-
-       TAILQ_FOREACH(c, &ctl_conns, entry) {
-               if (c->iev.ibuf.fd == fd)
-                       break;
-       }
-
-       return (c);
-}
-
-void
-control_close(int fd, struct control_sock *cs)
-{
-       struct ctl_conn *c;
-
-       if ((c = control_connbyfd(fd)) == NULL) {
-               log_warn("%s: fd %d: not found", __func__, fd);
-               return;
-       }
-
-       msgbuf_clear(&c->iev.ibuf.w);
-       TAILQ_REMOVE(&ctl_conns, c, entry);
-
-       event_del(&c->iev.ev);
-       close(c->iev.ibuf.fd);
-
-       /* Some file descriptors are available again. */
-       if (evtimer_pending(&cs->cs_evt, NULL)) {
-               evtimer_del(&cs->cs_evt);
-               event_add(&cs->cs_ev, NULL);
-       }
-
-       free(c);
-}
-
-/* ARGSUSED */
-void
-control_dispatch_imsg(int fd, short event, void *arg)
-{
-       struct control_sock     *cs = arg;
-       struct switchd          *env = cs->cs_env;
-       struct ctl_conn         *c;
-       struct imsg              imsg;
-       int                      n, v;
-
-       if ((c = control_connbyfd(fd)) == NULL) {
-               log_warn("%s: fd %d: not found", __func__, fd);
-               return;
-       }
-
-       if (event & EV_READ) {
-               if (((n = imsg_read(&c->iev.ibuf)) == -1 && errno != EAGAIN) ||
-                   n == 0) {
-                       control_close(fd, cs);
-                       return;
-               }
-       }
-       if (event & EV_WRITE) {
-               if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) {
-                       control_close(fd, cs);
-                       return;
-               }
-       }
-
-       for (;;) {
-               if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
-                       control_close(fd, cs);
-                       return;
-               }
-
-               if (n == 0)
-                       break;
-
-               control_imsg_forward(&imsg);
-
-               switch (imsg.hdr.type) {
-               case IMSG_CTL_SHOW_SUM:
-                       /* Forward request and use control fd as _id_ */
-                       proc_compose(&env->sc_ps, PROC_OFP,
-                           imsg.hdr.type, &fd, sizeof(fd));
-                       break;
-               case IMSG_CTL_CONNECT:
-               case IMSG_CTL_DISCONNECT:
-                       proc_compose(&env->sc_ps, PROC_PARENT,
-                           imsg.hdr.type, imsg.data, IMSG_DATA_SIZE(&imsg));
-                       break;
-               case IMSG_CTL_NOTIFY:
-                       if (c->flags & CTL_CONN_NOTIFY) {
-                               log_debug("%s: "
-                                   "client requested notify more than once",
-                                   __func__);
-                               imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
-                                   0, 0, -1, NULL, 0);
-                               break;
-                       }
-                       c->flags |= CTL_CONN_NOTIFY;
-                       break;
-               case IMSG_CTL_VERBOSE:
-                       IMSG_SIZE_CHECK(&imsg, &v);
-
-                       memcpy(&v, imsg.data, sizeof(v));
-                       log_setverbose(v);
-
-                       proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1);
-                       proc_forward_imsg(&env->sc_ps, &imsg, PROC_OFP, -1);
-                       break;
-               default:
-                       log_debug("%s: error handling imsg %d",
-                           __func__, imsg.hdr.type);
-                       break;
-               }
-               imsg_free(&imsg);
-       }
-
-       imsg_event_add(&c->iev);
-}
-
-void
-control_imsg_forward(struct imsg *imsg)
-{
-       struct ctl_conn *c;
-
-       TAILQ_FOREACH(c, &ctl_conns, entry)
-               if (c->flags & CTL_CONN_NOTIFY)
-                       imsg_compose(&c->iev.ibuf, imsg->hdr.type,
-                           0, imsg->hdr.pid, -1, imsg->data,
-                           imsg->hdr.len - IMSG_HEADER_SIZE);
-}
diff --git a/usr.sbin/switchd/genmap.sh b/usr.sbin/switchd/genmap.sh
deleted file mode 100644 (file)
index 2c61975..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/sh
-# $OpenBSD: genmap.sh,v 1.6 2016/11/18 16:49:35 reyk Exp $
-
-# Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-TOKEN=""
-MAPFILE=""
-INPUT=""
-HEADER=""
-DESCR=0
-
-args=`getopt di:o:h:t:m: $*`
-
-if [ $? -ne 0 ]; then
-       echo "usage: $0 [-d] -i input -h header -t token [-m mapfile]"
-       exit 1
-fi
-
-set -- $args
-while [ $# -ne 0 ]; do
-       case "$1" in
-       -d)
-               DESCR=1; shift;
-               ;;
-       -i)
-               INPUT="$2"; shift; shift;
-               ;;
-       -h)
-               HEADER="$2"; shift; shift;
-               ;;
-       -t)
-               TOKEN="$2"; shift; shift;
-               ;;
-       -m)
-               MAPFILE="$2"; shift; shift;
-               ;;
-       --)
-               shift;
-               break
-               ;;
-       esac
-done
-
-if [ -z "$MAPFILE" ]; then
-       MAPFILE=$INPUT
-fi
-
-TOK=$(echo ${TOKEN} | tr "[:lower:]" "[:upper:]")
-tok=$(echo ${TOKEN} | tr "[:upper:]" "[:lower:]")
-INC="#include ${HEADER}"
-FILE=$(basename ${INPUT})
-MAP=$(grep "struct constmap ${tok}_" $MAPFILE |
-       sed -Ee "s/.*${tok}_(.+)_map.*/\1/g")
-
-# Print license/copyright notice and headers
-cat <<EOF
-/* Automatically generated from ${FILE}, do not edit */
-EOF
-sed -n '1,/^ \*\//p' $INPUT
-cat <<EOF
-
-#include <sys/types.h>
-${INC}
-#include "ofp_map.h"
-
-EOF
-
-for i in $MAP; do
-       lower=$(echo $i | tr "[:upper:]" "[:lower:]")
-       upper=$(echo $i | tr "[:lower:]" "[:upper:]")
-
-       echo "struct constmap ${tok}_${lower}_map[] = {"
-
-       X="${TOK}_${upper}_"
-
-       if [ $DESCR = 1 ]; then
-               # with the description field
-               grep "$X" $INPUT | grep -v '\\' | sed -Ee \
-                   "s/#define.*${X}([^[:blank:]]+).*\/\* (.+) \*\/$\
-/      { ${X}\1, \"\1\", \"\2\" },/" | grep -v '\#define'
-       else
-               # without the description field
-               grep "$X" $INPUT | grep -v '\\' | sed -Ee \
-                   "s/#define.*${X}([^[:blank:]]+).*\/\* .+ \*\/$\
-/      { ${X}\1, \"\1\" },/" | grep -v '\#define'
-       fi
-
-       echo "  { 0 }"
-       echo "};"
-done
diff --git a/usr.sbin/switchd/imsg_util.c b/usr.sbin/switchd/imsg_util.c
deleted file mode 100644 (file)
index e7e79fd..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*     $OpenBSD: imsg_util.c,v 1.5 2016/09/30 11:57:57 reyk Exp $      */
-
-/*
- * Copyright (c) 2010-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <net/if.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <event.h>
-#include <imsg.h>
-
-#include "switchd.h"
-
-/*
- * Extending the imsg buffer API for internal use
- */
-
-int
-ibuf_cat(struct ibuf *dst, struct ibuf *src)
-{
-       return (ibuf_add(dst, src->buf, ibuf_size(src)));
-}
-
-void
-ibuf_zero(struct ibuf *buf)
-{
-       explicit_bzero(buf->buf, buf->wpos);
-}
-
-void
-ibuf_reset(struct ibuf *buf)
-{
-       ibuf_zero(buf);
-       buf->rpos = buf->wpos = 0;
-}
-
-struct ibuf *
-ibuf_new(void *data, size_t len)
-{
-       struct ibuf     *buf;
-
-       if ((buf = ibuf_dynamic(len,
-           SWITCHD_MSGBUF_MAX)) == NULL)
-               return (NULL);
-
-       ibuf_zero(buf);
-
-       if (data == NULL && len) {
-               if (ibuf_advance(buf, len) == NULL) {
-                       ibuf_free(buf);
-                       return (NULL);
-               }
-       } else {
-               if (ibuf_add(buf, data, len) != 0) {
-                       ibuf_free(buf);
-                       return (NULL);
-               }
-       }
-
-       return (buf);
-}
-
-struct ibuf *
-ibuf_static(void)
-{
-       struct ibuf     *buf;
-
-       if ((buf = ibuf_open(SWITCHD_MSGBUF_MAX)) == NULL)
-               return (NULL);
-
-       ibuf_zero(buf);
-
-       return (buf);
-}
-
-void *
-ibuf_advance(struct ibuf *buf, size_t len)
-{
-       void    *ptr;
-
-       if ((ptr = ibuf_reserve(buf, len)) != NULL)
-               memset(ptr, 0, len);
-
-       return (ptr);
-}
-
-void
-ibuf_release(struct ibuf *buf)
-{
-       if (buf == NULL)
-               return;
-       if (buf->buf != NULL) {
-               ibuf_zero(buf);
-               free(buf->buf);
-       }
-       free(buf);
-}
-
-size_t
-ibuf_length(struct ibuf *buf)
-{
-       if (buf == NULL || buf->buf == NULL)
-               return (0);
-       return (ibuf_size(buf));
-}
-
-uint8_t *
-ibuf_data(struct ibuf *buf)
-{
-       return (ibuf_seek(buf, 0, 0));
-}
-
-void *
-ibuf_getdata(struct ibuf *buf, size_t len)
-{
-       void    *data;
-
-       if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
-               return (NULL);
-       buf->rpos += len;
-
-       return (data);
-}
-
-ssize_t
-ibuf_dataleft(struct ibuf *buf)
-{
-       return (buf->wpos - buf->rpos);
-}
-
-size_t
-ibuf_dataoffset(struct ibuf *buf)
-{
-       return (buf->rpos);
-}
-
-struct ibuf *
-ibuf_get(struct ibuf *buf, size_t len)
-{
-       void            *data;
-
-       if ((data = ibuf_getdata(buf, len)) == NULL)
-               return (NULL);
-
-       return (ibuf_new(data, len));
-}
-
-struct ibuf *
-ibuf_dup(struct ibuf *buf)
-{
-       if (buf == NULL)
-               return (NULL);
-       return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
-}
-
-struct ibuf *
-ibuf_random(size_t len)
-{
-       struct ibuf     *buf;
-       void            *ptr;
-
-       if ((buf = ibuf_open(len)) == NULL)
-               return (NULL);
-       if ((ptr = ibuf_reserve(buf, len)) == NULL) {
-               ibuf_free(buf);
-               return (NULL);
-       }
-       arc4random_buf(ptr, len);
-       return (buf);
-}
-
-int
-ibuf_setsize(struct ibuf *buf, size_t len)
-{
-       if (len > buf->size)
-               return (-1);
-       buf->wpos = len;
-       return (0);
-}
-
-int
-ibuf_setmax(struct ibuf *buf, size_t len)
-{
-       if (len > buf->size)
-               return (-1);
-       buf->max = len;
-       return (0);
-}
-
-int
-ibuf_prepend(struct ibuf *buf, void *data, size_t len)
-{
-       struct ibuf     *new;
-
-       /* Swap buffers (we could also use memmove here) */
-       if ((new = ibuf_new(data, len)) == NULL)
-               return (-1);
-       if (ibuf_cat(new, buf) == -1) {
-               ibuf_release(new);
-               return (-1);
-       }
-       free(buf->buf);
-       memcpy(buf, new, sizeof(*buf));
-       free(new);
-
-       return (0);
-}
diff --git a/usr.sbin/switchd/log.c b/usr.sbin/switchd/log.c
deleted file mode 100644 (file)
index 1d0c004..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*     $OpenBSD: log.c,v 1.5 2017/03/21 12:06:56 bluhm Exp $   */
-
-/*
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <syslog.h>
-#include <errno.h>
-#include <time.h>
-
-static int      debug;
-static int      verbose;
-const char     *log_procname;
-
-void   log_init(int, int);
-void   log_procinit(const char *);
-void   log_setverbose(int);
-int    log_getverbose(void);
-void   log_warn(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_warnx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_info(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_debug(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   logit(int, const char *, ...)
-           __attribute__((__format__ (printf, 2, 3)));
-void   vlog(int, const char *, va_list)
-           __attribute__((__format__ (printf, 2, 0)));
-__dead void fatal(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-__dead void fatalx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-
-void
-log_init(int n_debug, int facility)
-{
-       extern char     *__progname;
-
-       debug = n_debug;
-       verbose = n_debug;
-       log_procinit(__progname);
-
-       if (!debug)
-               openlog(__progname, LOG_PID | LOG_NDELAY, facility);
-
-       tzset();
-}
-
-void
-log_procinit(const char *procname)
-{
-       if (procname != NULL)
-               log_procname = procname;
-}
-
-void
-log_setverbose(int v)
-{
-       verbose = v;
-}
-
-int
-log_getverbose(void)
-{
-       return (verbose);
-}
-
-void
-logit(int pri, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       vlog(pri, fmt, ap);
-       va_end(ap);
-}
-
-void
-vlog(int pri, const char *fmt, va_list ap)
-{
-       char    *nfmt;
-       int      saved_errno = errno;
-
-       if (debug) {
-               /* best effort in out of mem situations */
-               if (asprintf(&nfmt, "%s\n", fmt) == -1) {
-                       vfprintf(stderr, fmt, ap);
-                       fprintf(stderr, "\n");
-               } else {
-                       vfprintf(stderr, nfmt, ap);
-                       free(nfmt);
-               }
-               fflush(stderr);
-       } else
-               vsyslog(pri, fmt, ap);
-
-       errno = saved_errno;
-}
-
-void
-log_warn(const char *emsg, ...)
-{
-       char            *nfmt;
-       va_list          ap;
-       int              saved_errno = errno;
-
-       /* best effort to even work in out of memory situations */
-       if (emsg == NULL)
-               logit(LOG_ERR, "%s", strerror(saved_errno));
-       else {
-               va_start(ap, emsg);
-
-               if (asprintf(&nfmt, "%s: %s", emsg,
-                   strerror(saved_errno)) == -1) {
-                       /* we tried it... */
-                       vlog(LOG_ERR, emsg, ap);
-                       logit(LOG_ERR, "%s", strerror(saved_errno));
-               } else {
-                       vlog(LOG_ERR, nfmt, ap);
-                       free(nfmt);
-               }
-               va_end(ap);
-       }
-
-       errno = saved_errno;
-}
-
-void
-log_warnx(const char *emsg, ...)
-{
-       va_list  ap;
-
-       va_start(ap, emsg);
-       vlog(LOG_ERR, emsg, ap);
-       va_end(ap);
-}
-
-void
-log_info(const char *emsg, ...)
-{
-       va_list  ap;
-
-       va_start(ap, emsg);
-       vlog(LOG_INFO, emsg, ap);
-       va_end(ap);
-}
-
-void
-log_debug(const char *emsg, ...)
-{
-       va_list  ap;
-
-       if (verbose > 1) {
-               va_start(ap, emsg);
-               vlog(LOG_DEBUG, emsg, ap);
-               va_end(ap);
-       }
-}
-
-static void
-vfatalc(int code, const char *emsg, va_list ap)
-{
-       static char     s[BUFSIZ];
-       const char      *sep;
-
-       if (emsg != NULL) {
-               (void)vsnprintf(s, sizeof(s), emsg, ap);
-               sep = ": ";
-       } else {
-               s[0] = '\0';
-               sep = "";
-       }
-       if (code)
-               logit(LOG_CRIT, "%s: %s%s%s",
-                   log_procname, s, sep, strerror(code));
-       else
-               logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
-}
-
-void
-fatal(const char *emsg, ...)
-{
-       va_list ap;
-
-       va_start(ap, emsg);
-       vfatalc(errno, emsg, ap);
-       va_end(ap);
-       exit(1);
-}
-
-void
-fatalx(const char *emsg, ...)
-{
-       va_list ap;
-
-       va_start(ap, emsg);
-       vfatalc(0, emsg, ap);
-       va_end(ap);
-       exit(1);
-}
diff --git a/usr.sbin/switchd/ofcconn.c b/usr.sbin/switchd/ofcconn.c
deleted file mode 100644 (file)
index 1f2973a..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-/*     $OpenBSD: ofcconn.c,v 1.13 2019/06/28 13:32:51 deraadt Exp $    */
-
-/*
- * Copyright (c) 2016 YASUOKA Masahiko <yasuoka@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <net/ofp.h>
-
-#include <errno.h>
-#include <event.h>
-#include <imsg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <imsg.h>
-
-#include "ofp10.h"
-#include "types.h"
-#include "switchd.h"
-
-int     ofcconn_dispatch_parent(int, struct privsep_proc *, struct imsg *);
-
-static struct privsep_proc procs[] = {
-       { "parent",     PROC_PARENT,    ofcconn_dispatch_parent },
-       { "control",    PROC_CONTROL,   NULL },
-};
-
-struct ofcconn;
-
-/* OpenFlow Switch */
-struct ofsw {
-       int                      os_fd;
-       char                    *os_name;
-       int                      os_write_ready;
-       TAILQ_HEAD(,ofcconn)     os_ofcconns;
-       struct event             os_evio;
-       TAILQ_ENTRY(ofsw)        os_next;
-};
-TAILQ_HEAD(, ofsw)      ofsw_list = TAILQ_HEAD_INITIALIZER(ofsw_list);
-
-/* OpenFlow Channel Connection */
-struct ofcconn {
-       struct ofsw             *oc_sw;
-       char                    *oc_name;
-       struct sockaddr_storage  oc_peer;
-       int                      oc_sock;
-       int                      oc_write_ready;
-       int                      oc_connected;
-       int                      oc_conn_fails;
-       struct ibuf             *oc_buf;
-       TAILQ_ENTRY(ofcconn)     oc_next;
-       struct event             oc_evsock;
-       struct event             oc_evtimer;
-};
-
-struct ofsw    *ofsw_create(const char *, int);
-void            ofsw_close(struct ofsw *);
-void            ofsw_free(struct ofsw *);
-void            ofsw_on_io(int, short, void *);
-int             ofsw_write(struct ofsw *, struct ofcconn *);
-int             ofsw_ofc_write_ready(struct ofsw *);
-void            ofsw_reset_event_handlers(struct ofsw *);
-int             ofsw_new_ofcconn(struct ofsw *, struct switch_address *);
-int             ofcconn_connect(struct ofcconn *);
-void            ofcconn_on_sockio(int, short, void *);
-void            ofcconn_connect_again(struct ofcconn *);
-void            ofcconn_on_timer(int, short, void *);
-void            ofcconn_reset_event_handlers(struct ofcconn *);
-void            ofcconn_io_fail(struct ofcconn *);
-void            ofcconn_close(struct ofcconn *);
-void            ofcconn_free(struct ofcconn *);
-void            ofcconn_shutdown_all(void);
-int             ofcconn_send_hello(struct ofcconn *);
-void            ofcconn_run(struct privsep *, struct privsep_proc *, void *);
-
-void
-ofcconn(struct privsep *ps, struct privsep_proc *p)
-{
-       p->p_shutdown = ofcconn_shutdown;
-       proc_run(ps, p, procs, nitems(procs), ofcconn_run, NULL);
-}
-
-void
-ofcconn_run(struct privsep *ps, struct privsep_proc *p, void *arg)
-{
-       /*
-        * pledge in the ofcconn process:
-        * stdio - for malloc and basic I/O including events.
-        * inet - for socket operations and OpenFlow connections.
-        * recvfd - for receiving new sockets on reload.
-        */
-       if (pledge("stdio inet recvfd", NULL) == -1)
-               fatal("pledge");
-}
-
-void
-ofcconn_shutdown(void)
-{
-       struct ofsw     *e, *t;
-
-       TAILQ_FOREACH_SAFE(e, &ofsw_list, os_next, t) {
-               ofsw_close(e);
-               ofsw_free(e);
-       }
-}
-
-int
-ofcconn_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       struct ofsw                     *os;
-       struct switch_client             swc;
-       struct sockaddr_un              *un;
-
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_CONNECT:
-               if (IMSG_DATA_SIZE(imsg) < sizeof(swc)) {
-                       log_warnx("%s: IMSG_CTL_CONNECT: "
-                           "invalid message size", __func__);
-                       return (0);
-               }
-               memcpy(&swc, imsg->data, sizeof(swc));
-               un = (struct sockaddr_un *)&swc.swc_addr.swa_addr;
-
-               if ((os = ofsw_create(un->sun_path, imsg->fd)) != NULL)
-                       ofsw_new_ofcconn(os, &swc.swc_target);
-               return (0);
-       case IMSG_CTL_DISCONNECT:
-               if (IMSG_DATA_SIZE(imsg) < sizeof(swc)) {
-                       log_warnx("%s: IMSG_CTL_DEVICE_DISCONNECT: "
-                           "invalid message size", __func__);
-                       return (0);
-               }
-               memcpy(&swc, imsg->data, sizeof(swc));
-               un = (struct sockaddr_un *)&swc.swc_addr.swa_addr;
-
-               TAILQ_FOREACH(os, &ofsw_list, os_next) {
-                       if (!strcmp(os->os_name, un->sun_path))
-                               break;
-               }
-               if (os) {
-                       log_warnx("%s: closed by request", os->os_name);
-                       ofsw_close(os);
-                       ofsw_free(os);
-               }
-               return (0);
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-struct ofsw *
-ofsw_create(const char *name, int fd)
-{
-       struct ofsw     *os = NULL;
-
-       if ((os = calloc(1, sizeof(struct ofsw))) == NULL) {
-               log_warn("%s: calloc failed", __func__);
-               goto fail;
-       }
-       if ((os->os_name = strdup(name)) == NULL) {
-               log_warn("%s: strdup failed", __func__);
-               goto fail;
-       }
-       os->os_fd = fd;
-       TAILQ_INIT(&os->os_ofcconns);
-       TAILQ_INSERT_TAIL(&ofsw_list, os, os_next);
-
-       event_set(&os->os_evio, os->os_fd, EV_READ|EV_WRITE, ofsw_on_io, os);
-       event_add(&os->os_evio, NULL);
-
-       return (os);
-
- fail:
-       if (os != NULL)
-               free(os->os_name);
-       free(os);
-
-       return (NULL);
-}
-
-void
-ofsw_close(struct ofsw *os)
-{
-       struct ofcconn  *oc, *oct;
-
-       if (os->os_fd >= 0) {
-               close(os->os_fd);
-               event_del(&os->os_evio);
-               os->os_fd = -1;
-       }
-       TAILQ_FOREACH_SAFE(oc, &os->os_ofcconns, oc_next, oct) {
-               ofcconn_close(oc);
-               ofcconn_free(oc);
-       }
-}
-
-void
-ofsw_free(struct ofsw *os)
-{
-       if (os == NULL)
-               return;
-
-       TAILQ_REMOVE(&ofsw_list, os, os_next);
-       free(os->os_name);
-       free(os);
-}
-
-void
-ofsw_on_io(int fd, short evmask, void *ctx)
-{
-       struct ofsw             *os = ctx;
-       struct ofcconn          *oc, *oct;
-       static char              msg[65536];/* max size of OpenFlow message */
-       ssize_t                  msgsz, sz;
-       struct ofp_header       *hdr;
-
-       if (evmask & EV_WRITE || os->os_write_ready) {
-               os->os_write_ready = 1;
-               if (ofsw_write(os, NULL) == -1)
-                       return;
-       }
-
-       if ((evmask & EV_READ) && ofsw_ofc_write_ready(os)) {
-               if ((msgsz = read(os->os_fd, msg, sizeof(msg))) <= 0) {
-                       if (msgsz == -1)
-                               log_warn("%s: %s read", __func__, os->os_name);
-                       else
-                               log_warnx("%s: %s closed", __func__,
-                                   os->os_name);
-                       ofsw_close(os);
-                       ofsw_free(os);
-                       return;
-               }
-               hdr = (struct ofp_header *)msg;
-               if (hdr->oh_type != OFP_T_HELLO) {
-                       TAILQ_FOREACH_SAFE(oc, &os->os_ofcconns, oc_next, oct) {
-                               if ((sz = write(oc->oc_sock, msg, msgsz))
-                                   != msgsz) {
-                                       log_warn("%s: sending a message to "
-                                           "%s failed", os->os_name,
-                                           oc->oc_name);
-                                       ofcconn_io_fail(oc);
-                                       continue;
-                               }
-                               oc->oc_write_ready = 0;
-                               ofcconn_reset_event_handlers(oc);
-                       }
-               }
-       }
-       ofsw_reset_event_handlers(os);
-
-       return;
-}
-
-int
-ofsw_write(struct ofsw *os, struct ofcconn *oc0)
-{
-       struct ofcconn          *oc = oc0;
-       struct ofp_header       *hdr;
-       u_char                  *msg;
-       ssize_t                  sz, msglen;
-       int                      remain = 0;
-       unsigned char            buf[65536];
-
-       if (!os->os_write_ready)
-               return (0);
-
- again:
-       if (oc != NULL) {
-               hdr = ibuf_seek(oc->oc_buf, 0, sizeof(*hdr));
-               if (hdr == NULL)
-                       return (0);
-               msglen = ntohs(hdr->oh_length);
-               msg = ibuf_seek(oc->oc_buf, 0, msglen);
-               if (msg == NULL)
-                       return (0);
-       } else {
-               TAILQ_FOREACH(oc, &os->os_ofcconns, oc_next) {
-                       hdr = ibuf_seek(oc->oc_buf, 0, sizeof(*hdr));
-                       if (hdr == NULL)
-                               continue;
-                       msglen = ntohs(hdr->oh_length);
-                       msg = ibuf_seek(oc->oc_buf, 0, msglen);
-                       if (msg != NULL)
-                               break;
-               }
-               if (oc == NULL)
-                       return (0);     /* no message to write yet */
-       }
-       if (hdr->oh_type != OFP_T_HELLO) {
-               if ((sz = write(os->os_fd, msg, msglen)) != msglen) {
-                       if (sz == -1)
-                               log_warn("%s: %s write failed", __func__,
-                                   os->os_name);
-                       else
-                               log_warn("%s: %s write partially", __func__,
-                                   os->os_name);
-                       ofsw_close(os);
-                       ofsw_free(os);
-                       return (-1);
-               }
-               os->os_write_ready = 0;
-       }
-
-       /* XXX preserve the remaining part */
-       if ((remain = oc->oc_buf->wpos - msglen) > 0)
-               memcpy(buf, (caddr_t)msg + msglen, remain);
-       ibuf_reset(oc->oc_buf);
-
-       /* XXX put the remaining part again */
-       if (remain > 0)
-               ibuf_add(oc->oc_buf, buf, remain);
-
-       if (os->os_write_ready) {
-               oc = NULL;
-               goto again;
-       }
-
-       return (0);
-}
-
-int
-ofsw_ofc_write_ready(struct ofsw *os)
-{
-       struct ofcconn  *oc;
-       int              write_ready = 0;
-
-       TAILQ_FOREACH(oc, &os->os_ofcconns, oc_next) {
-               if (oc->oc_write_ready)
-                       write_ready = 1;
-               else
-                       break;
-       }
-       if (oc != NULL)
-               return (0);
-
-       return (write_ready);
-}
-
-void
-ofsw_reset_event_handlers(struct ofsw *os)
-{
-       short   evmask = 0, oevmask;
-
-       oevmask = event_pending(&os->os_evio, EV_READ|EV_WRITE, NULL);
-
-       if (ofsw_ofc_write_ready(os))
-               evmask |= EV_READ;
-       if (!os->os_write_ready)
-               evmask |= EV_WRITE;
-
-       if (oevmask != evmask) {
-               if (oevmask)
-                       event_del(&os->os_evio);
-               event_set(&os->os_evio, os->os_fd, evmask, ofsw_on_io, os);
-               event_add(&os->os_evio, NULL);
-       }
-}
-
-int
-ofsw_new_ofcconn(struct ofsw *os, struct switch_address *swa)
-{
-       struct ofcconn  *oc = NULL;
-       char             buf[128];
-
-       if ((oc = calloc(1, sizeof(struct ofcconn))) == NULL) {
-               log_warn("%s: calloc failed", __func__);
-               goto fail;
-       }
-
-       if (asprintf(&oc->oc_name, "tcp:%s",
-           print_host(&swa->swa_addr, buf, sizeof(buf))) == -1) {
-               log_warn("%s: strdup failed", __func__);
-               goto fail;
-       }
-       if ((oc->oc_buf = ibuf_new(NULL, 0)) == NULL) {
-               log_warn("%s: failed to get new ibuf", __func__);
-               goto fail;
-       }
-       oc->oc_sw = os;
-       oc->oc_sock = -1;
-       memcpy(&oc->oc_peer, &swa->swa_addr, sizeof(oc->oc_peer));
-
-       if (ntohs(((struct sockaddr_in *)&oc->oc_peer)->sin_port) == 0)
-               ((struct sockaddr_in *)&oc->oc_peer)->sin_port =
-                   htons(SWITCHD_CTLR_PORT);
-
-       evtimer_set(&oc->oc_evtimer, ofcconn_on_timer, oc);
-       TAILQ_INSERT_TAIL(&os->os_ofcconns, oc, oc_next);
-
-       return (ofcconn_connect(oc));
-
- fail:
-       if (oc != NULL) {
-               free(oc->oc_name);
-               ibuf_release(oc->oc_buf);
-       }
-       free(oc);
-
-       return (-1);
-}
-
-int
-ofcconn_connect(struct ofcconn *oc)
-{
-       int              sock = -1;
-       struct timeval   tv;
-
-       if ((sock = socket(oc->oc_peer.ss_family, SOCK_STREAM | SOCK_NONBLOCK,
-           IPPROTO_TCP)) == -1) {
-               log_warn("%s: failed to open socket for channel with %s",
-                   oc->oc_sw->os_name, oc->oc_name);
-               goto fail;
-       }
-
-       if (connect(sock, (struct sockaddr *)&oc->oc_peer,
-           oc->oc_peer.ss_len) == -1) {
-               if (errno != EINPROGRESS) {
-                       log_warn("%s: failed to connect channel to %s",
-                           oc->oc_sw->os_name, oc->oc_name);
-                       goto fail;
-               }
-       }
-
-       oc->oc_sock = sock;
-       event_set(&oc->oc_evsock, oc->oc_sock, EV_READ|EV_WRITE,
-           ofcconn_on_sockio, oc);
-       event_add(&oc->oc_evsock, NULL);
-
-       tv.tv_sec = SWITCHD_CONNECT_TIMEOUT;
-       tv.tv_usec = 0;
-       event_add(&oc->oc_evtimer, &tv);
-
-       return (0);
-
- fail:
-       if (sock >= 0)
-               close(sock);
-
-       oc->oc_conn_fails++;
-       ofcconn_connect_again(oc);
-
-       return (-1);
-}
-
-void
-ofcconn_on_sockio(int fd, short evmask, void *ctx)
-{
-       struct ofcconn  *oc = ctx;
-       ssize_t          sz;
-       size_t           wpos;
-       int              err;
-       socklen_t        optlen;
-
-       if (evmask & EV_WRITE) {
-               if (oc->oc_connected == 0) {
-                       optlen = sizeof(err);
-                       getsockopt(oc->oc_sock, SOL_SOCKET, SO_ERROR, &err,
-                           &optlen);
-                       if (err != 0) {
-                               log_warnx("%s: connection error with %s: %s",
-                                   oc->oc_sw->os_name, oc->oc_name,
-                                   strerror(err));
-                               oc->oc_conn_fails++;
-                               ofcconn_close(oc);
-                               ofcconn_connect_again(oc);
-                               return;
-                       }
-                       log_info("%s: OpenFlow channel to %s connected",
-                           oc->oc_sw->os_name, oc->oc_name);
-
-                       event_del(&oc->oc_evtimer);
-                       oc->oc_connected = 1;
-                       oc->oc_conn_fails = 0;
-                       if (ofcconn_send_hello(oc) != 0)
-                               return;
-               } else
-                       oc->oc_write_ready = 1;
-       }
-
-       if ((evmask & EV_READ) && ibuf_left(oc->oc_buf) > 0) {
-               wpos = ibuf_length(oc->oc_buf);
-
-               /* XXX temporally fix not to access unallocated area */
-               if (wpos + ibuf_left(oc->oc_buf) > oc->oc_buf->size) {
-                       ibuf_reserve(oc->oc_buf, ibuf_left(oc->oc_buf));
-                       ibuf_setsize(oc->oc_buf, wpos);
-               }
-
-               if ((sz = read(oc->oc_sock, ibuf_data(oc->oc_buf) + wpos,
-                   ibuf_left(oc->oc_buf))) <= 0) {
-                       if (sz == 0)
-                               log_warnx("%s: %s: connection closed by peer",
-                                   oc->oc_sw->os_name, oc->oc_name);
-                       else
-                               log_warn("%s: %s: connection read error",
-                                   oc->oc_sw->os_name, oc->oc_name);
-                       goto fail;
-               }
-               if (ibuf_setsize(oc->oc_buf, wpos + sz) == -1)
-                       goto fail;
-
-               if (ofsw_write(oc->oc_sw, oc) == -1)
-                       return; /* oc is already freeed */
-       }
-       ofcconn_reset_event_handlers(oc);
-       ofsw_reset_event_handlers(oc->oc_sw);
-
-       return;
-
- fail:
-       ofcconn_close(oc);
-       ofcconn_connect_again(oc);
-}
-
-void
-ofcconn_connect_again(struct ofcconn *oc)
-{
-       struct timeval   tv;
-       const int        ofcconn_backoffs[] = { 1, 2, 4, 8, 16 };
-
-       tv.tv_sec = (oc->oc_conn_fails < (int)nitems(ofcconn_backoffs))
-           ? ofcconn_backoffs[oc->oc_conn_fails]
-           : ofcconn_backoffs[nitems(ofcconn_backoffs) - 1];
-       tv.tv_usec = 0;
-       event_add(&oc->oc_evtimer, &tv);
-}
-
-void
-ofcconn_on_timer(int fd, short evmask, void *ctx)
-{
-       struct ofcconn  *oc = ctx;
-
-       if (oc->oc_sock < 0)
-               ofcconn_connect(oc);
-       else if (!oc->oc_connected) {
-               log_warnx("%s: timeout connecting channel to %s",
-                   oc->oc_sw->os_name, oc->oc_name);
-               ofcconn_close(oc);
-               oc->oc_conn_fails++;
-               ofcconn_connect_again(oc);
-       }
-}
-
-void
-ofcconn_reset_event_handlers(struct ofcconn *oc)
-{
-       short   evmask = 0, oevmask;
-
-       oevmask = event_pending(&oc->oc_evsock, EV_READ|EV_WRITE, NULL);
-
-       if (ibuf_left(oc->oc_buf) > 0)
-               evmask |= EV_READ;
-       if (!oc->oc_write_ready)
-               evmask |= EV_WRITE;
-
-       if (oevmask != evmask) {
-               if (oevmask)
-                       event_del(&oc->oc_evsock);
-               if (evmask) {
-                       event_set(&oc->oc_evsock, oc->oc_sock, evmask,
-                           ofcconn_on_sockio, oc);
-                       event_add(&oc->oc_evsock, NULL);
-               }
-       }
-}
-
-void
-ofcconn_io_fail(struct ofcconn *oc)
-{
-       ofcconn_close(oc);
-       ofcconn_connect_again(oc);
-}
-
-void
-ofcconn_close(struct ofcconn *oc)
-{
-       if (oc->oc_sock >= 0) {
-               event_del(&oc->oc_evsock);
-               close(oc->oc_sock);
-               oc->oc_sock = -1;
-               oc->oc_write_ready = 0;
-       }
-       event_del(&oc->oc_evtimer);
-       oc->oc_connected = 0;
-}
-
-void
-ofcconn_free(struct ofcconn *oc)
-{
-       if (oc == NULL)
-               return;
-       TAILQ_REMOVE(&oc->oc_sw->os_ofcconns, oc, oc_next);
-       ibuf_release(oc->oc_buf);
-       free(oc->oc_name);
-       free(oc);
-}
-
-int
-ofcconn_send_hello(struct ofcconn *oc)
-{
-       struct ofp_header        hdr;
-       ssize_t                  sz;
-
-       hdr.oh_version = OFP_V_1_3;
-       hdr.oh_type = OFP_T_HELLO;
-       hdr.oh_length = htons(sizeof(hdr));
-       hdr.oh_xid = htonl(0xffffffffUL);
-
-       sz = sizeof(hdr);
-       if (write(oc->oc_sock, &hdr, sz) != sz) {
-               log_warn("%s: %s: %s; write", __func__, oc->oc_sw->os_name,
-                   oc->oc_name);
-               ofcconn_close(oc);
-               ofcconn_connect_again(oc);
-               return (-1);
-       }
-
-       return (0);
-}
diff --git a/usr.sbin/switchd/ofp.c b/usr.sbin/switchd/ofp.c
deleted file mode 100644 (file)
index bf0ef10..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*     $OpenBSD: ofp.c,v 1.18 2016/12/22 15:31:43 rzalamena Exp $      */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/queue.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <net/ofp.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <event.h>
-
-#include "ofp10.h"
-#include "switchd.h"
-#include "ofp_map.h"
-
-int     ofp_dispatch_parent(int, struct privsep_proc *, struct imsg *);
-int     ofp_dispatch_control(int, struct privsep_proc *, struct imsg *);
-void    ofp_run(struct privsep *, struct privsep_proc *, void *);
-int     ofp_add_device(struct switchd *, int, const char *);
-
-static struct privsep_proc procs[] = {
-       { "control",    PROC_CONTROL,   ofp_dispatch_control },
-       { "parent",     PROC_PARENT,    ofp_dispatch_parent }
-};
-
-void
-ofp(struct privsep *ps, struct privsep_proc *p)
-{
-       ofrelay(ps, p);
-       proc_run(ps, p, procs, nitems(procs), ofp_run, NULL);
-}
-
-void
-ofp_run(struct privsep *ps, struct privsep_proc *p, void *arg)
-{
-       struct switchd  *sc = ps->ps_env;
-
-       /*
-        * pledge in the ofp process:
-        * stdio - for malloc and basic I/O including events.
-        * inet - for handling tcp connections with OpenFlow peers.
-        * recvfd - for receiving new sockets on reload.
-        */
-       if (pledge("stdio inet recvfd", NULL) == -1)
-               fatal("pledge");
-
-       TAILQ_INIT(&sc->sc_conns);
-       sc->sc_tap = -1;
-
-       ofrelay_run(ps, p, NULL);
-}
-
-int
-ofp_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_SUM:
-               return (switch_dispatch_control(fd, p, imsg));
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-int
-ofp_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       struct privsep                  *ps = p->p_ps;
-       struct switchd                  *sc = ps->ps_env;
-       struct switch_client             swc;
-       struct switch_connection        *con;
-
-       switch (imsg->hdr.type) {
-       case IMSG_TAPFD:
-               if (sc->sc_tap != -1)
-                       close(sc->sc_tap);
-               sc->sc_tap = imsg->fd;
-               return (0);
-       case IMSG_CTL_CONNECT:
-       case IMSG_CTL_DISCONNECT:
-               IMSG_SIZE_CHECK(imsg, &swc);
-               memcpy(&swc, imsg->data, sizeof(swc));
-
-               if (imsg->hdr.type == IMSG_CTL_CONNECT)
-                       ofrelay_attach(&sc->sc_server, imsg->fd,
-                           (struct sockaddr *)&swc.swc_addr.swa_addr);
-               else if ((con = switchd_connbyaddr(sc,
-                   (struct sockaddr *)&swc.swc_addr.swa_addr)) != NULL)
-                       ofp_close(con);
-               return (0);
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-int
-ofp_input(struct switch_connection *con, struct ibuf *ibuf)
-{
-       struct switchd          *sc = con->con_sc;
-       struct ofp_header       *oh;
-
-       if ((oh = ibuf_seek(ibuf, 0, sizeof(*oh))) == NULL) {
-               log_debug("short header");
-               return (-1);
-       }
-
-       /* Check for message version match. */
-       if (con->con_state > OFP_STATE_HELLO_WAIT &&
-           con->con_version != OFP_V_0 &&
-           oh->oh_version != con->con_version) {
-               log_debug("wrong version %s, expected %s",
-                   print_map(oh->oh_version, ofp_v_map),
-                   print_map(con->con_version, ofp_v_map));
-               return (-1);
-       }
-
-       /* Check the state machine to decide whether or not to allow. */
-       if (con->con_state <= OFP_STATE_HELLO_WAIT &&
-           oh->oh_type > OFP_T_ERROR) {
-               log_debug("expected hello, got %s",
-                   print_map(oh->oh_type, ofp_t_map));
-               return (-1);
-       }
-
-       switch (oh->oh_version) {
-       case OFP_V_1_0:
-               if (ofp10_input(sc, con, oh, ibuf) != 0)
-                       return (-1);
-               break;
-       case OFP_V_1_3:
-               if (ofp13_input(sc, con, oh, ibuf) != 0)
-                       return (-1);
-               break;
-       case OFP_V_1_1:
-       case OFP_V_1_2:
-               /* FALLTHROUGH */
-       default:
-               (void)ofp10_validate(sc,
-                   &con->con_peer, &con->con_local, oh, ibuf);
-               ofp10_hello(sc, con, oh, ibuf);
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-ofp_open(struct privsep *ps, struct switch_connection *con)
-{
-       struct switch_control   *sw;
-
-       /* Get associated switch, if it exists */
-       sw = switch_get(con);
-
-       log_info("%s: new connection %u.%u from switch %u",
-           __func__, con->con_id, con->con_instance,
-           sw == NULL ? 0 : sw->sw_id);
-
-       /* Send the hello with the latest version we support. */
-       if (ofp_send_hello(ps->ps_env, con, OFP_V_1_3) == -1)
-               return (-1);
-
-       if (ofp_nextstate(ps->ps_env, con, OFP_STATE_HELLO_WAIT) == -1)
-               return (-1);
-
-       return (0);
-}
-
-void
-ofp_close(struct switch_connection *con)
-{
-       ofrelay_close(con);
-}
-
-int
-ofp_nextstate(struct switchd *sc, struct switch_connection *con,
-    enum ofp_state state)
-{
-       int             rv = 0;
-
-       switch (con->con_state) {
-       case OFP_STATE_CLOSED:
-               if (state != OFP_STATE_HELLO_WAIT)
-                       return (-1);
-
-               break;
-
-       case OFP_STATE_HELLO_WAIT:
-               if (state != OFP_STATE_FEATURE_WAIT)
-                       return (-1);
-
-               rv = ofp_send_featuresrequest(sc, con);
-               break;
-
-       case OFP_STATE_FEATURE_WAIT:
-               if (state != OFP_STATE_ESTABLISHED)
-                       return (-1);
-
-               if (con->con_version != OFP_V_1_3)
-                       break;
-
-#if 0
-               /* Let's not ask this while we don't use it. */
-               ofp13_flow_stats(sc, con, OFP_PORT_ANY, OFP_GROUP_ID_ANY,
-                   OFP_TABLE_ID_ALL);
-               ofp13_desc(sc, con);
-#endif
-               rv |= ofp13_table_features(sc, con, 0);
-               rv |= ofp13_setconfig(sc, con, OFP_CONFIG_FRAG_NORMAL,
-                   OFP_CONTROLLER_MAXLEN_NO_BUFFER);
-               break;
-
-
-       case OFP_STATE_ESTABLISHED:
-               if (state != OFP_STATE_CLOSED)
-                       return (-1);
-
-               break;
-
-       default:
-               return (-1);
-       }
-
-       /* Set the next state. */
-       con->con_state = state;
-
-       return (rv);
-}
diff --git a/usr.sbin/switchd/ofp10.c b/usr.sbin/switchd/ofp10.c
deleted file mode 100644 (file)
index e1dbc72..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*     $OpenBSD: ofp10.c,v 1.21 2019/05/05 21:33:00 akoshibe Exp $     */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ofp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <imsg.h>
-#include <event.h>
-
-#include "ofp10.h"
-#include "switchd.h"
-#include "ofp_map.h"
-
-
-int     ofp10_packet_match(struct packet *, struct ofp10_match *, unsigned int);
-
-int     ofp10_features_reply(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_validate_features_reply(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_echo_request(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_validate_error(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_error(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_validate_packet_in(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_packet_in(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp10_validate_packet_out(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-
-struct ofp_callback ofp10_callbacks[] = {
-       { OFP10_T_HELLO,                ofp10_hello, ofp_validate_hello },
-       { OFP10_T_ERROR,                NULL, ofp10_validate_error },
-       { OFP10_T_ECHO_REQUEST,         ofp10_echo_request, NULL },
-       { OFP10_T_ECHO_REPLY,           NULL, NULL },
-       { OFP10_T_EXPERIMENTER,         NULL, NULL },
-       { OFP10_T_FEATURES_REQUEST,     NULL, NULL },
-       { OFP10_T_FEATURES_REPLY,       ofp10_features_reply,
-                                       ofp10_validate_features_reply },
-       { OFP10_T_GET_CONFIG_REQUEST,   NULL, NULL },
-       { OFP10_T_GET_CONFIG_REPLY,     NULL, NULL },
-       { OFP10_T_SET_CONFIG,           NULL, NULL },
-       { OFP10_T_PACKET_IN,            ofp10_packet_in, ofp10_validate_packet_in },
-       { OFP10_T_FLOW_REMOVED,         NULL, NULL },
-       { OFP10_T_PORT_STATUS,          NULL, NULL },
-       { OFP10_T_PACKET_OUT,           NULL, ofp10_validate_packet_out },
-       { OFP10_T_FLOW_MOD,             NULL, NULL },
-       { OFP10_T_PORT_MOD,             NULL, NULL },
-       { OFP10_T_STATS_REQUEST,        NULL, NULL },
-       { OFP10_T_STATS_REPLY,          NULL, NULL },
-       { OFP10_T_BARRIER_REQUEST,      NULL, NULL },
-       { OFP10_T_BARRIER_REPLY,        NULL, NULL },
-       { OFP10_T_QUEUE_GET_CONFIG_REQUEST, NULL, NULL },
-       { OFP10_T_QUEUE_GET_CONFIG_REPLY, NULL, NULL }
-};
-
-int
-ofp10_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       uint8_t type;
-
-       if (ofp_validate_header(sc, src, dst, oh, OFP_V_1_0) != 0) {
-               log_debug("\tinvalid header");
-               return (-1);
-       }
-       if (ibuf == NULL) {
-               /* The response packet buffer is optional */
-               return (0);
-       }
-       type = oh->oh_type;
-       if (ofp10_callbacks[type].validate != NULL &&
-           ofp10_callbacks[type].validate(sc, src, dst, oh, ibuf) != 0) {
-               log_debug("\tinvalid packet");
-               return (-1);
-       }
-       return (0);
-}
-
-int
-ofp10_validate_packet_in(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp10_packet_in  *pin;
-       uint8_t                 *p;
-       size_t                   len, plen;
-       off_t                    off;
-
-       off = 0;
-       if ((pin = ibuf_seek(ibuf, off, sizeof(*pin))) == NULL)
-               return (-1);
-       log_debug("\tbuffer %d port %s "
-           "length %u reason %u",
-           ntohl(pin->pin_buffer_id),
-           print_map(ntohs(pin->pin_port), ofp10_port_map),
-           ntohs(pin->pin_total_len),
-           pin->pin_reason);
-       off += sizeof(*pin);
-
-       len = ntohs(pin->pin_total_len);
-       plen = ibuf_length(ibuf) - off;
-
-       if (plen < len) {
-               log_debug("\ttruncated packet %zu < %zu", plen, len);
-
-               /* Buffered packets can be truncated */
-               if (pin->pin_buffer_id != OFP_PKTOUT_NO_BUFFER)
-                       len = plen;
-               else
-                       return (-1);
-       }
-       if ((p = ibuf_seek(ibuf, off, len)) == NULL)
-               return (-1);
-       if (sc->sc_tap != -1)
-               (void)write(sc->sc_tap, p, len);
-
-       return (0);
-}
-
-int
-ofp10_validate_packet_out(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp10_packet_out         *pout;
-       size_t                           len;
-       off_t                            off;
-       struct ofp_action_header        *ah;
-       struct ofp10_action_output      *ao;
-
-       off = 0;
-       if ((pout = ibuf_seek(ibuf, off, sizeof(*pout))) == NULL) {
-               log_debug("%s: seek failed: length %zd",
-                   __func__, ibuf_length(ibuf));
-               return (-1);
-       }
-       log_debug("\tbuffer %d port %s "
-           "actions length %u",
-           ntohl(pout->pout_buffer_id),
-           print_map(ntohs(pout->pout_port), ofp10_port_map),
-           ntohs(pout->pout_actions_len));
-       len = ntohs(pout->pout_actions_len);
-
-       off += sizeof(*pout);
-       while ((ah = ibuf_seek(ibuf, off, len)) != NULL &&
-           ntohs(ah->ah_len) >= (uint16_t)sizeof(*ah)) {
-               switch (ntohs(ah->ah_type)) {
-               case OFP10_ACTION_OUTPUT:
-                       ao = (struct ofp10_action_output *)ah;
-                       log_debug("\t\taction type %s length %d "
-                           "port %s max length %d",
-                           print_map(ntohs(ao->ao_type), ofp10_action_map),
-                           ntohs(ao->ao_len),
-                           print_map(ntohs(ao->ao_port), ofp10_port_map),
-                           ntohs(ao->ao_max_len));
-                       break;
-               default:
-                       log_debug("\t\taction type %s length %d",
-                           print_map(ntohs(ah->ah_type), ofp10_action_map),
-                           ntohs(ah->ah_len));
-                       break;
-               }
-               if (pout->pout_buffer_id == (uint32_t)-1)
-                       break;
-               off += ntohs(ah->ah_len);
-       }
-
-       return (0);
-}
-
-int
-ofp10_validate_error(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_error                *err;
-       off_t                            off;
-       const char                      *code;
-
-       off = 0;
-       if ((err = ibuf_seek(ibuf, off, sizeof(*err))) == NULL) {
-               log_debug("%s: seek failed: length %zd",
-                   __func__, ibuf_length(ibuf));
-               return (-1);
-       }
-
-       switch (ntohs(err->err_type)) {
-       case OFP10_ERRTYPE_FLOW_MOD_FAILED:
-               code = print_map(ntohs(err->err_code), ofp10_errflowmod_map);
-               break;
-       default:
-               code = NULL;
-               break;
-       }
-
-       log_debug("\terror type %s code %u%s%s",
-           print_map(ntohs(err->err_type), ofp10_errtype_map),
-           ntohs(err->err_code),
-           code == NULL ? "" : ": ",
-           code == NULL ? "" : code);
-
-       return (0);
-}
-
-int
-ofp10_input(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       if (ofp10_validate(sc, &con->con_peer, &con->con_local, oh, ibuf) != 0)
-               return (-1);
-
-       if (ofp10_callbacks[oh->oh_type].cb == NULL) {
-               log_debug("message not supported: %s",
-                   print_map(oh->oh_type, ofp10_t_map));
-               return (-1);
-       }
-       if (ofp10_callbacks[oh->oh_type].cb(sc, con, oh, ibuf) != 0)
-               return (-1);
-
-       return (0);
-}
-
-int
-ofp10_hello(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       if (switch_add(con) == NULL) {
-               log_debug("%s: failed to add switch", __func__);
-               return (-1);
-       }
-
-       if (ofp_recv_hello(sc, con, oh, ibuf) == -1)
-               return (-1);
-
-       return (ofp_nextstate(sc, con, OFP_STATE_FEATURE_WAIT));
-}
-
-int
-ofp10_features_reply(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       return (ofp_nextstate(sc, con, OFP_STATE_ESTABLISHED));
-}
-
-int
-ofp10_validate_features_reply(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_switch_features      *swf;
-       struct ofp10_phy_port           *swp;
-       off_t                            poff;
-       int                              portslen;
-       char                            *mac;
-
-       if ((swf = ibuf_seek(ibuf, 0, sizeof(*swf))) == NULL)
-               return (-1);
-
-       log_debug("\tdatapath_id %#016llx nbuffers %u ntables %d "
-           "capabilities %#08x actions %#08x",
-           be64toh(swf->swf_datapath_id), ntohl(swf->swf_nbuffers),
-           swf->swf_ntables, ntohl(swf->swf_capabilities),
-           ntohl(swf->swf_actions));
-
-       poff = sizeof(*swf);
-       portslen = ntohs(oh->oh_length) - sizeof(*swf);
-       if (portslen <= 0)
-               return (0);
-
-       while (portslen > 0) {
-               if ((swp = ibuf_seek(ibuf, poff, sizeof(*swp))) == NULL)
-                       return (-1);
-
-               mac = ether_ntoa((void *)swp->swp_macaddr);
-               log_debug("no %s macaddr %s name %s config %#08x state %#08x "
-                   "cur %#08x advertised %#08x supported %#08x peer %#08x",
-                   print_map(ntohs(swp->swp_number), ofp10_port_map), mac,
-                   swp->swp_name, swp->swp_config, swp->swp_state,
-                   swp->swp_cur, swp->swp_advertised, swp->swp_supported,
-                   swp->swp_peer);
-
-               portslen -= sizeof(*swp);
-               poff += sizeof(*swp);
-       }
-
-       return (0);
-}
-
-int
-ofp10_echo_request(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       /* Echo reply */
-       oh->oh_type = OFP10_T_ECHO_REPLY;
-       if (ofp10_validate(sc, &con->con_local, &con->con_peer, oh, NULL) != 0)
-               return (-1);
-       ofp_output(con, oh, NULL);
-
-       return (0);
-}
-
-int
-ofp10_packet_match(struct packet *pkt, struct ofp10_match *m, uint32_t flags)
-{
-       struct ether_header     *eh = pkt->pkt_eh;
-
-       memset(m, 0, sizeof(*m));
-       m->m_wildcards = htonl(~flags);
-
-       if ((flags & (OFP10_WILDCARD_DL_SRC|OFP10_WILDCARD_DL_DST)) &&
-           (eh == NULL))
-               return (-1);
-
-       if (flags & OFP10_WILDCARD_DL_SRC)
-               memcpy(m->m_dl_src, eh->ether_shost, ETHER_ADDR_LEN);
-       if (flags & OFP10_WILDCARD_DL_DST)
-               memcpy(m->m_dl_dst, eh->ether_dhost, ETHER_ADDR_LEN);
-
-       return (0);
-}
-
-int
-ofp10_packet_in(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *ih, struct ibuf *ibuf)
-{
-       struct ofp10_packet_in          *pin;
-       struct ofp10_packet_out         *pout;
-       struct ofp10_action_output      *ao;
-       struct ofp10_flow_mod           *fm;
-       struct ofp_header               *oh;
-       struct packet                    pkt;
-       struct ibuf                     *obuf = NULL;
-       int                              ret = -1;
-       size_t                           len;
-       uint32_t                         srcport, dstport;
-       int                              addflow = 0;
-       int                              addpacket = 0;
-
-       if ((pin = ibuf_getdata(ibuf, sizeof(*pin))) == NULL)
-               return (-1);
-
-       memset(&pkt, 0, sizeof(pkt));
-       len = ntohs(pin->pin_total_len);
-
-       srcport = ntohs(pin->pin_port);
-
-       if (packet_ether_input(ibuf, len, &pkt) == -1 &&
-           pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
-               return(-1);
-
-       if (packet_input(sc, con->con_switch,
-           srcport, &dstport, &pkt) == -1 ||
-           (dstport > OFP10_PORT_MAX &&
-           dstport != OFP10_PORT_LOCAL &&
-           dstport != OFP10_PORT_CONTROLLER)) {
-               /* fallback to flooding */
-               dstport = OFP10_PORT_FLOOD;
-       } else if (srcport == dstport) {
-               /*
-                * silently drop looping packet
-                * (don't use OFP10_PORT_INPUT here)
-                */
-               ret = 0;
-               goto done;
-       } else {
-               addflow = 1;
-       }
-
-       if ((obuf = ibuf_static()) == NULL)
-               goto done;
-
- again:
-       if (addflow) {
-               if ((fm = ibuf_advance(obuf, sizeof(*fm))) == NULL)
-                       goto done;
-
-               ofp10_packet_match(&pkt, &fm->fm_match, OFP10_WILDCARD_DL_DST);
-
-               oh = &fm->fm_oh;
-               fm->fm_cookie = 0; /* XXX should we set a cookie? */
-               fm->fm_command = htons(OFP_FLOWCMD_ADD);
-               fm->fm_idle_timeout = htons(sc->sc_cache_timeout);
-               fm->fm_hard_timeout = 0; /* permanent */
-               fm->fm_priority = 0;
-               fm->fm_buffer_id = pin->pin_buffer_id;
-               fm->fm_flags = htons(OFP_FLOWFLAG_SEND_FLOW_REMOVED);
-               if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
-                       addpacket = 1;
-       } else {
-               if ((pout = ibuf_advance(obuf, sizeof(*pout))) == NULL)
-                       goto done;
-
-               oh = &pout->pout_oh;
-               pout->pout_buffer_id = pin->pin_buffer_id;
-               pout->pout_port = pin->pin_port;
-               pout->pout_actions_len = htons(sizeof(*ao));
-
-               if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
-                       addpacket = 1;
-       }
-
-       if ((ao = ibuf_advance(obuf, sizeof(*ao))) == NULL)
-               goto done;
-       ao->ao_type = htons(OFP_ACTION_OUTPUT);
-       ao->ao_len =  htons(sizeof(*ao));
-       ao->ao_port = htons((uint16_t)dstport);
-       ao->ao_max_len = 0;
-
-       /* Add optional packet payload to packet-out. */
-       if (addflow == 0 && addpacket &&
-           imsg_add(obuf, pkt.pkt_buf, pkt.pkt_len) == -1)
-               goto done;
-
-       /* Set output header */
-       memcpy(oh, ih, sizeof(*oh));
-       oh->oh_length = htons(ibuf_length(obuf));
-       oh->oh_type = addflow ? OFP10_T_FLOW_MOD : OFP10_T_PACKET_OUT;
-       oh->oh_xid = htonl(con->con_xidnxt++);
-
-       if (ofp10_validate(sc, &con->con_local, &con->con_peer, oh, obuf) != 0)
-               goto done;
-
-       ofp_output(con, NULL, obuf);
-
-       if (addflow && addpacket) {
-               /* loop to output the packet again */
-               addflow = 0;
-               if ((obuf = ibuf_static()) == NULL)
-                       goto done;
-               goto again;
-       }
-
-       ret = 0;
- done:
-       ibuf_release(obuf);
-       return (ret);
-}
diff --git a/usr.sbin/switchd/ofp10.h b/usr.sbin/switchd/ofp10.h
deleted file mode 100644 (file)
index 8db1e78..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*     $OpenBSD: ofp10.h,v 1.2 2016/09/30 12:48:27 reyk Exp $  */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _NET_OFP10_H_
-#define _NET_OFP10_H_
-
-#include <net/ofp.h>
-
-/* OpenFlow message type */
-#define OFP10_T_HELLO                  0       /* Hello */
-#define OFP10_T_ERROR                  1       /* Error */
-#define OFP10_T_ECHO_REQUEST           2       /* Echo Request */
-#define OFP10_T_ECHO_REPLY             3       /* Echo Reply */
-#define OFP10_T_EXPERIMENTER           4       /* Vendor/Experimenter */
-#define OFP10_T_FEATURES_REQUEST       5       /* Features Request (switch) */
-#define OFP10_T_FEATURES_REPLY         6       /* Features Reply (switch) */
-#define OFP10_T_GET_CONFIG_REQUEST     7       /* Get Config Request (switch) */
-#define OFP10_T_GET_CONFIG_REPLY       8       /* Get Config Reply (switch) */
-#define OFP10_T_SET_CONFIG             9       /* Set Config (switch) */
-#define OFP10_T_PACKET_IN              10      /* Packet In (async) */
-#define OFP10_T_FLOW_REMOVED           11      /* Flow Removed (async) */
-#define OFP10_T_PORT_STATUS            12      /* Port Status (async) */
-#define OFP10_T_PACKET_OUT             13      /* Packet Out (controller) */
-#define OFP10_T_FLOW_MOD               14      /* Flow Mod (controller) */
-#define OFP10_T_PORT_MOD               16      /* Port Mod (controller) */
-#define OFP10_T_STATS_REQUEST          17      /* Stats Request */
-#define OFP10_T_STATS_REPLY            18      /* Stats Reply */
-#define OFP10_T_BARRIER_REQUEST                19      /* Barrier Request */
-#define OFP10_T_BARRIER_REPLY          20      /* Barrier Reply */
-#define OFP10_T_QUEUE_GET_CONFIG_REQUEST 21    /* Queue Get Config Request */
-#define OFP10_T_QUEUE_GET_CONFIG_REPLY 22      /* Queue Get Config Reply */
-#define        OFP10_T_TYPE_MAX                23
-
-/* Ports */
-#define OFP10_PORT_MAX                 0xff00  /* Maximum number of physical ports */
-#define        OFP10_PORT_INPUT                0xfff8  /* Send back to input port */
-#define OFP10_PORT_FLOWTABLE           0xfff9  /* Perform actions in flow table */
-#define OFP10_PORT_NORMAL              0xfffa  /* Let switch decide */
-#define OFP10_PORT_FLOOD               0xfffb  /* All non-block ports except input */
-#define OFP10_PORT_ALL                 0xfffc  /* All ports except input */
-#define OFP10_PORT_CONTROLLER          0xfffd  /* Send to controller */
-#define OFP10_PORT_LOCAL               0xfffe  /* Local virtual OpenFlow port */
-#define OFP10_PORT_ANY                 0xffff  /* No port */
-
-/* Switch port description */
-struct ofp10_phy_port {
-       uint16_t        swp_number;
-       uint8_t         swp_macaddr[ETHER_ADDR_LEN];
-       char            swp_name[OFP_IFNAMSIZ];
-       uint32_t        swp_config;             /* Configuration flags */
-       uint32_t        swp_state;              /* State flags */
-       uint32_t        swp_cur;                /* Current features */
-       uint32_t        swp_advertised;         /* Advertised by the port */
-       uint32_t        swp_supported;          /* Supported by the port */
-       uint32_t        swp_peer;               /* Advertised by peer */
-};
-
-/* Packet-In Message */
-struct ofp10_packet_in {
-       struct ofp_header       pin_oh;         /* OpenFlow header */
-       uint32_t                pin_buffer_id;
-       uint16_t                pin_total_len;
-       uint16_t                pin_port;
-       uint8_t                 pin_reason;
-       uint8_t                 pin_pad;
-       uint8_t                 pin_data[0];
-} __packed;
-
-/* Actions */
-#define OFP10_ACTION_OUTPUT            0       /* Output to switch port */
-#define OFP10_ACTION_SET_VLAN_VID      1       /* Set the 802.1q VLAN id */
-#define OFP10_ACTION_SET_VLAN_PCP      2       /* Set the 802.1q priority */
-#define OFP10_ACTION_STRIP_VLAN                3       /* Strip the 802.1q header */
-#define OFP10_ACTION_SET_DL_SRC                4       /* Ethernet src address */
-#define OFP10_ACTION_SET_DL_DST                5       /* Ethernet dst address */
-#define OFP10_ACTION_SET_NW_SRC                6       /* IP src address */
-#define OFP10_ACTION_SET_NW_DST                7       /* IP dst address */
-#define OFP10_ACTION_SET_NW_TOS                8       /* IP TOS */
-#define OFP10_ACTION_SET_TP_SRC                9       /* TCP/UDP src port */
-#define OFP10_ACTION_SET_TP_DST                10      /* TCP/UDP dst port */
-#define OFP10_ACTION_ENQUEUE           11      /* Output to queue */
-#define OFP10_ACTION_EXPERIMENTER      0xffff  /* Vendor-specific action */
-
-/* Output Action */
-struct ofp10_action_output {
-       uint16_t        ao_type;
-       uint16_t        ao_len;
-       uint16_t        ao_port;
-       uint16_t        ao_max_len;
-} __packed;
-
-/* Packet-Out Message */
-struct ofp10_packet_out {
-       struct ofp_header       pout_oh;        /* OpenFlow header */
-       uint32_t                pout_buffer_id;
-       uint16_t                pout_port;
-       uint16_t                pout_actions_len;
-       struct ofp_action_header pout_actions[0];
-       /* Followed by optional packet data if buffer_id == 0xffffffff */
-} __packed;
-
-/* Flow matching wildcards */
-#define OFP10_WILDCARD_IN_PORT 0x00000001      /* Switch input port */
-#define OFP10_WILDCARD_DL_VLAN 0x00000002      /* VLAN id */
-#define OFP10_WILDCARD_DL_SRC  0x00000004      /* Ethernet src address */
-#define OFP10_WILDCARD_DL_DST  0x00000008      /* Ethernet dst address */
-#define OFP10_WILDCARD_DL_TYPE 0x00000010      /* Ethernet frame type */
-#define OFP10_WILDCARD_NW_PROTO        0x00000020      /* IPv4 protocol */
-#define OFP10_WILDCARD_TP_SRC  0x00000040      /* TCP/UDP source port */
-#define OFP10_WILDCARD_TP_DST  0x00000080      /* TCP/UDP destination port */
-#define OFP10_WILDCARD_NW_SRC  0x00003f00      /* IPv4 source address */
-#define OFP10_WILDCARD_NW_SRC_S        8
-#define OFP10_WILDCARD_NW_DST  0x000fc000      /* IPv4 destination address */
-#define OFP10_WILDCARD_NW_DST_S        14
-#define OFP10_WILDCARD_DL_VLANPCP 0x00100000   /* VLAN prio */
-#define OFP10_WILDCARD_NW_TOS  0x00200000      /* IPv4 ToS/DSCP */
-#define OFP10_WILDCARD_MASK    0x003fffff      /* All wildcard flags */
-
-/* Flow matching */
-struct ofp10_match {
-       uint32_t        m_wildcards;                    /* Wildcard options */
-       uint16_t        m_in_port;                      /* Switch port */
-       uint8_t         m_dl_src[ETHER_ADDR_LEN];       /* Ether src addr */
-       uint8_t         m_dl_dst[ETHER_ADDR_LEN];       /* Ether dst addr */
-       uint16_t        m_dl_vlan;                      /* Input VLAN id */
-       uint8_t         m_dl_vlan_pcp;                  /* Input VLAN prio */
-       uint8_t         m_pad1[1];
-       uint16_t        m_dl_type;                      /* Ether type */
-       uint8_t         m_nw_tos;                       /* IPv4 ToS/DSCP */ 
-       uint8_t         m_nw_proto;                     /* IPv4 Proto */
-       uint8_t         m_pad2[2];
-       uint32_t        m_nw_src;                       /* IPv4 source */
-       uint32_t        m_nw_dst;                       /* IPv4 destination */
-       uint16_t        m_tp_src;                       /* TCP/UDP src port */
-       uint16_t        m_tp_dst;                       /* TCP/UDP dst port */
-} __packed;
-
-/* Flow modification message */
-struct ofp10_flow_mod {
-       struct ofp_header       fm_oh;          /* OpenFlow header */
-       struct ofp10_match      fm_match;
-       uint64_t                fm_cookie;
-       uint16_t                fm_command;
-       uint16_t                fm_idle_timeout;
-       uint16_t                fm_hard_timeout;
-       uint16_t                fm_priority;
-       uint32_t                fm_buffer_id;
-       uint16_t                fm_port;
-       uint16_t                fm_flags;
-       struct ofp_action_header fm_actions[0];
-} __packed;
-
-/* Error types */
-#define OFP10_ERRTYPE_HELLO_FAILED     0       /* Hello protocol failed */
-#define OFP10_ERRTYPE_BAD_REQUEST      1       /* Request was not understood */
-#define OFP10_ERRTYPE_BAD_ACTION       2       /* Error in action */
-#define OFP10_ERRTYPE_FLOW_MOD_FAILED  3       /* Problem modifying flow */
-#define OFP10_ERRTYPE_PORT_MOD_FAILED  4       /* Port mod request failed */
-#define OFP10_ERRTYPE_QUEUE_OP_FAILED  5       /* Queue operation failed */
-
-/* FLOW MOD error codes */
-#define OFP10_ERRFLOWMOD_ALL_TABLES_FULL 0     /* Not added, full tables */
-#define OFP10_ERRFLOWMOD_OVERLAP       1       /* Overlapping flow */
-#define OFP10_ERRFLOWMOD_EPERM         2       /* Permissions error */
-#define OFP10_ERRFLOWMOD_BAD_TIMEOUT   3       /* non-zero idle/hardtimeout */
-#define OFP10_ERRFLOWMOD_BAD_COMMAND   4       /* Unknown command */
-#define OFP10_ERRFLOWMOD_UNSUPPORTED   5       /* Unsupported action list */
-
-#endif /* _NET_OPF_H_ */
diff --git a/usr.sbin/switchd/ofp13.c b/usr.sbin/switchd/ofp13.c
deleted file mode 100644 (file)
index 7213024..0000000
+++ /dev/null
@@ -1,2258 +0,0 @@
-/*     $OpenBSD: ofp13.c,v 1.47 2019/11/27 17:37:32 akoshibe Exp $     */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2016 Rafael Zalamena <rzalamena@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ofp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-#include <netmpls/mpls.h>
-
-#include <endian.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <imsg.h>
-#include <event.h>
-
-#include "switchd.h"
-#include "ofp_map.h"
-
-int     ofp13_echo_request(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_validate_features_reply(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_features_reply(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_validate_error(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_validate_action(struct switchd *, struct ofp_header *,
-           struct ibuf *, off_t *, struct ofp_action_header *);
-int     ofp13_validate_instruction(struct switchd *, struct ofp_header *,
-           struct ibuf *, off_t *, struct ofp_instruction *);
-int     ofp13_validate_flow_mod(struct switchd *, struct sockaddr_storage *,
-           struct sockaddr_storage *, struct ofp_header *, struct ibuf *);
-int     ofp13_validate_oxm_basic(struct ibuf *, off_t, int, uint8_t);
-int     ofp13_validate_oxm(struct switchd *, struct ofp_ox_match *,
-           struct ofp_header *, struct ibuf *, off_t);
-int     ofp13_validate_packet_in(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_packet_match(struct ibuf *, struct packet *, struct ofp_match *);
-int     ofp13_packet_in(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_flow_removed(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_tableproperties(struct switch_connection *, struct ibuf *,
-           off_t, size_t, int);
-int     ofp13_multipart_reply(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_validate_tableproperty(struct ibuf *, off_t, int);
-int     ofp13_multipart_reply_validate(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-int     ofp13_validate_packet_out(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-
-struct ofp_multipart *
-           ofp13_multipart_request(struct switch_connection *, struct ibuf *,
-           uint16_t, uint16_t);
-int     ofp13_multipart_request_validate(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-
-int     ofp13_error(struct switchd *, struct switch_connection *,
-           struct ofp_header *, struct ibuf *, uint16_t, uint16_t);
-
-struct ofp_group_mod *
-           ofp13_group(struct switch_connection *, struct ibuf *,
-           uint32_t, uint16_t, uint8_t);
-struct ofp_bucket *
-           ofp13_bucket(struct ibuf *, uint16_t, uint32_t, uint32_t);
-
-int     ofp13_setconfig_validate(struct switchd *,
-           struct sockaddr_storage *, struct sockaddr_storage *,
-           struct ofp_header *, struct ibuf *);
-
-int     ofp13_switchconfigure(struct switchd *, struct switch_connection *);
-int     ofp13_getflowtable(struct switch_connection *);
-
-struct ofp_callback ofp13_callbacks[] = {
-       { OFP_T_HELLO,                  ofp13_hello, ofp_validate_hello },
-       { OFP_T_ERROR,                  NULL, ofp13_validate_error },
-       { OFP_T_ECHO_REQUEST,           ofp13_echo_request, NULL },
-       { OFP_T_ECHO_REPLY,             NULL, NULL },
-       { OFP_T_EXPERIMENTER,           NULL, NULL },
-       { OFP_T_FEATURES_REQUEST,       NULL, NULL },
-       { OFP_T_FEATURES_REPLY,         ofp13_features_reply,
-                                       ofp13_validate_features_reply },
-       { OFP_T_GET_CONFIG_REQUEST,     NULL, NULL },
-       { OFP_T_GET_CONFIG_REPLY,       NULL, NULL },
-       { OFP_T_SET_CONFIG,             NULL, ofp13_setconfig_validate },
-       { OFP_T_PACKET_IN,              ofp13_packet_in,
-                                       ofp13_validate_packet_in },
-       { OFP_T_FLOW_REMOVED,           ofp13_flow_removed, NULL },
-       { OFP_T_PORT_STATUS,            NULL, NULL },
-       { OFP_T_PACKET_OUT,             NULL, ofp13_validate_packet_out },
-       { OFP_T_FLOW_MOD,               NULL, ofp13_validate_flow_mod },
-       { OFP_T_GROUP_MOD,              NULL, NULL },
-       { OFP_T_PORT_MOD,               NULL, NULL },
-       { OFP_T_TABLE_MOD,              NULL, NULL },
-       { OFP_T_MULTIPART_REQUEST,      NULL,
-                                       ofp13_multipart_request_validate },
-       { OFP_T_MULTIPART_REPLY,        ofp13_multipart_reply,
-                                       ofp13_multipart_reply_validate },
-       { OFP_T_BARRIER_REQUEST,        NULL, NULL },
-       { OFP_T_BARRIER_REPLY,          NULL, NULL },
-       { OFP_T_QUEUE_GET_CONFIG_REQUEST, NULL, NULL },
-       { OFP_T_QUEUE_GET_CONFIG_REPLY, NULL, NULL },
-       { OFP_T_ROLE_REQUEST,           NULL, NULL },
-       { OFP_T_ROLE_REPLY,             NULL, NULL },
-       { OFP_T_GET_ASYNC_REQUEST,      NULL, NULL },
-       { OFP_T_GET_ASYNC_REPLY,        NULL, NULL },
-       { OFP_T_SET_ASYNC,              NULL, NULL },
-       { OFP_T_METER_MOD,              NULL, NULL },
-};
-
-int
-ofp13_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       uint8_t type;
-
-       if (ofp_validate_header(sc, src, dst, oh, OFP_V_1_3) != 0) {
-               log_debug("\tinvalid header");
-               return (-1);
-       }
-       if (ibuf == NULL) {
-               /* The response packet buffer is optional */
-               return (0);
-       }
-       type = oh->oh_type;
-       if (ofp13_callbacks[type].validate != NULL &&
-           ofp13_callbacks[type].validate(sc, src, dst, oh, ibuf) != 0) {
-               log_debug("\tinvalid packet");
-               return (-1);
-       }
-       return (0);
-}
-
-int
-ofp13_validate_oxm_basic(struct ibuf *ibuf, off_t off, int hasmask,
-    uint8_t type)
-{
-       uint8_t         *ui8;
-       uint16_t        *ui16;
-       uint32_t        *ui32;
-       uint64_t        *ui64;
-       int              i, len;
-       char             hex[8], buf[64], maskbuf[64];
-
-       switch (type) {
-       case OFP_XM_T_IN_PORT:
-       case OFP_XM_T_IN_PHY_PORT:
-       case OFP_XM_T_MPLS_LABEL:
-               if (hasmask)
-                       return (-1);
-               if ((ui32 = ibuf_seek(ibuf, off, sizeof(*ui32))) == NULL)
-                       return (-1);
-
-               log_debug("\t\t%u", ntohl(*ui32));
-               break;
-
-       case OFP_XM_T_META:
-       case OFP_XM_T_TUNNEL_ID:
-               len = sizeof(*ui64);
-               if (hasmask)
-                       len *= 2;
-
-               if ((ui64 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-
-               if (hasmask)
-                       log_debug("\t\t%llu mask %#16llx",
-                           be64toh(*ui64), be64toh(*(ui64 + 1)));
-               else
-                       log_debug("\t\t%llu", be64toh(*ui64));
-               break;
-
-       case OFP_XM_T_ARP_SHA:
-       case OFP_XM_T_ARP_THA:
-       case OFP_XM_T_IPV6_ND_SLL:
-       case OFP_XM_T_IPV6_ND_TLL:
-               if (hasmask)
-                       return (-1);
-               if ((ui8 = ibuf_seek(ibuf, off, ETHER_ADDR_LEN)) == NULL)
-                       return (-1);
-
-               buf[0] = 0;
-               for (i = 0; i < ETHER_ADDR_LEN; i++) {
-                       snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
-                       strlcat(buf, hex, sizeof(buf));
-               }
-
-               log_debug("\t\t%s", buf);
-               break;
-
-       case OFP_XM_T_ETH_DST:
-       case OFP_XM_T_ETH_SRC:
-               len = ETHER_ADDR_LEN;
-               if (hasmask)
-                       len *= 2;
-
-               if ((ui8 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-
-               buf[0] = 0;
-               for (i = 0; i < ETHER_ADDR_LEN; i++) {
-                       snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
-                       strlcat(buf, hex, sizeof(buf));
-               }
-
-               if (hasmask) {
-                       maskbuf[0] = 0;
-                       for (i = 0; i < ETHER_ADDR_LEN; i++) {
-                               snprintf(hex, sizeof(hex), "%02x", *(ui8 +
-                                   (i + ETHER_ADDR_LEN)));
-                               strlcat(maskbuf, hex, sizeof(maskbuf));
-                       }
-                       log_debug("\t\t%s mask %s", buf, maskbuf);
-               } else
-                       log_debug("\t\t%s", buf);
-               break;
-
-       case OFP_XM_T_ETH_TYPE:
-               if (hasmask)
-                       return (-1);
-               len = sizeof(*ui16);
-               if ((ui16 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-               log_debug("\t\t0x%04x", ntohs(*ui16));
-               break;
-
-       case OFP_XM_T_TCP_SRC:
-       case OFP_XM_T_TCP_DST:
-       case OFP_XM_T_UDP_SRC:
-       case OFP_XM_T_UDP_DST:
-       case OFP_XM_T_SCTP_SRC:
-       case OFP_XM_T_SCTP_DST:
-       case OFP_XM_T_ARP_OP:
-               if (hasmask)
-                       return (-1);
-               if ((ui16 = ibuf_seek(ibuf, off, sizeof(*ui16))) == NULL)
-                       return (-1);
-
-               log_debug("\t\t%d", ntohs(*ui16));
-               break;
-
-       case OFP_XM_T_VLAN_VID:
-       case OFP_XM_T_IPV6_EXTHDR:
-               len = sizeof(*ui16);
-               if (hasmask)
-                       len *= 2;
-
-               if ((ui16 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-
-               if (type == OFP_XM_T_VLAN_VID) {
-                       /* Remove the VID present bit to display. */
-                       if (hasmask)
-                               log_debug("\t\t%d mask %#04x",
-                                   ntohs(*ui16) & ~OFP_XM_VID_PRESENT,
-                                   ntohs(*(ui16 + 1)));
-                       else
-                               log_debug("\t\t%d",
-                                   ntohs(*ui16) & ~OFP_XM_VID_PRESENT);
-                       break;
-               }
-
-               if (hasmask)
-                       log_debug("\t\t%d mask %#04x",
-                           ntohs(*ui16), ntohs(*(ui16 + 1)));
-               else
-                       log_debug("\t\t%d", ntohs(*ui16));
-               break;
-
-       case OFP_XM_T_IP_DSCP:
-       case OFP_XM_T_IP_ECN:
-       case OFP_XM_T_IP_PROTO:
-       case OFP_XM_T_ICMPV4_TYPE:
-       case OFP_XM_T_ICMPV4_CODE:
-       case OFP_XM_T_ICMPV6_TYPE:
-       case OFP_XM_T_ICMPV6_CODE:
-       case OFP_XM_T_MPLS_TC:
-       case OFP_XM_T_MPLS_BOS:
-               if (hasmask)
-                       return (-1);
-               if ((ui8 = ibuf_seek(ibuf, off, sizeof(*ui8))) == NULL)
-                       return (-1);
-
-               log_debug("\t\t%#02x", *ui8);
-               break;
-
-       case OFP_XM_T_IPV4_SRC:
-       case OFP_XM_T_IPV4_DST:
-       case OFP_XM_T_ARP_SPA:
-       case OFP_XM_T_ARP_TPA:
-       case OFP_XM_T_IPV6_FLABEL:
-               len = sizeof(*ui32);
-               if (hasmask)
-                       len *= 2;
-
-               if ((ui32 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-
-               if (hasmask)
-                       log_debug("\t\t%#08x mask %#08x",
-                           ntohl(*ui32), ntohl(*(ui32 + 1)));
-               else
-                       log_debug("\t\t%#08x", ntohl(*ui32));
-               break;
-
-       case OFP_XM_T_IPV6_ND_TARGET:
-               if (hasmask)
-                       return (-1);
-               if ((ui8 = ibuf_seek(ibuf, off,
-                   sizeof(struct in6_addr))) == NULL)
-                       return (-1);
-
-               buf[0] = 0;
-               for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
-                       snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
-                       strlcat(buf, hex, sizeof(buf));
-               }
-
-               log_debug("\t\t%s", buf);
-               break;
-
-       case OFP_XM_T_IPV6_SRC:
-       case OFP_XM_T_IPV6_DST:
-               len = sizeof(struct in6_addr);
-               if (hasmask)
-                       len *= 2;
-
-               if ((ui8 = ibuf_seek(ibuf, off, len)) == NULL)
-                       return (-1);
-
-               buf[0] = 0;
-               for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
-                       snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
-                       strlcat(buf, hex, sizeof(buf));
-               }
-
-               if (hasmask) {
-                       maskbuf[0] = 0;
-                       for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
-                               snprintf(hex, sizeof(hex), "%02x", *(ui8 +
-                                   (i + sizeof(struct in6_addr))));
-                               strlcat(maskbuf, hex, sizeof(maskbuf));
-                       }
-                       log_debug("\t\t%s mask %s", buf, maskbuf);
-               } else
-                       log_debug("\t\t%s", buf);
-               break;
-
-       case OFP_XM_T_PBB_ISID:
-               /* TODO teach me how to read 24 bits and convert to be. */
-               break;
-
-       default:
-               log_debug("\t\tUnknown type");
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-ofp13_validate_oxm(struct switchd *sc, struct ofp_ox_match *oxm,
-    struct ofp_header *oh, struct ibuf *ibuf, off_t off)
-{
-       uint16_t         class;
-       uint8_t          type;
-       int              hasmask;
-
-       /* match element is always followed by data */
-       if (oxm->oxm_length == 0)
-               return (0);
-
-       type = OFP_OXM_GET_FIELD(oxm);
-       hasmask = OFP_OXM_GET_HASMASK(oxm);
-       class = ntohs(oxm->oxm_class);
-       off += sizeof(*oxm);
-
-       log_debug("\tox match class %s type %s hasmask %s length %u",
-           print_map(class, ofp_oxm_c_map),
-           print_map(type, ofp_xm_t_map),
-           hasmask ? "yes" : "no",
-           oxm->oxm_length);
-
-       switch (class) {
-       case OFP_OXM_C_NXM_0:
-       case OFP_OXM_C_NXM_1:
-               /* TODO teach me how to read NXM_*. */
-               break;
-
-       case OFP_OXM_C_OPENFLOW_BASIC:
-               return (ofp13_validate_oxm_basic(ibuf, off, hasmask, type));
-
-       case OFP_OXM_C_OPENFLOW_EXPERIMENTER:
-               /* Implementation dependent: there is nothing to do here. */
-               break;
-
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-ofp13_validate_packet_in(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_packet_in    *pin;
-       struct ofp_match        *om;
-       struct ofp_ox_match     *oxm;
-       uint8_t                 *p;
-       ssize_t                  len, mlen, plen;
-       off_t                    moff, off;
-
-       off = 0;
-       if ((pin = ibuf_seek(ibuf, off, sizeof(*pin))) == NULL)
-               return (-1);
-       log_debug("\tbuffer %s length %u reason %s table %s cookie 0x%#016llx",
-           print_map(ntohl(pin->pin_buffer_id), ofp_pktout_map),
-           ntohs(pin->pin_total_len),
-           print_map(ntohs(pin->pin_reason), ofp_pktin_map),
-           print_map(pin->pin_table_id, ofp_table_id_map),
-           be64toh(pin->pin_cookie));
-       off += offsetof(struct ofp_packet_in, pin_match);
-
-       om = &pin->pin_match;
-       mlen = ntohs(om->om_length);
-       log_debug("\tmatch type %s length %zu (padded to %zu)",
-           print_map(ntohs(om->om_type), ofp_match_map),
-           mlen, OFP_ALIGN(mlen) + ETHER_ALIGN);
-       mlen -= sizeof(*om);
-
-       /* current match offset, aligned offset after all matches */
-       moff = off + sizeof(*om);
-       off += OFP_ALIGN(mlen) + ETHER_ALIGN;
-
-       switch (htons(om->om_type)) {
-       case OFP_MATCH_OXM:
-               do {
-                       if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
-                               return (-1);
-                       if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
-                               return (-1);
-                       moff += sizeof(*oxm) + oxm->oxm_length;
-                       mlen -= sizeof(*oxm) + oxm->oxm_length;
-               } while (mlen > 0 && oxm->oxm_length);
-               break;
-       case OFP_MATCH_STANDARD:
-               /* deprecated */
-               break;
-       }
-
-       len = ntohs(pin->pin_total_len);
-       plen = ibuf_length(ibuf) - off;
-
-       if (plen < len) {
-               log_debug("\ttruncated packet %zu < %zu", plen, len);
-
-               /* Buffered packets can be truncated */
-               if (pin->pin_buffer_id != OFP_PKTOUT_NO_BUFFER)
-                       len = plen;
-               else
-                       return (-1);
-       }
-       if ((p = ibuf_seek(ibuf, off, len)) == NULL)
-               return (-1);
-       if (sc->sc_tap != -1)
-               (void)write(sc->sc_tap, p, len);
-
-       return (0);
-}
-
-int
-ofp13_validate_packet_out(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_packet_out           *pout;
-       size_t                           len, plen, diff;
-       off_t                            off, noff;
-       struct ofp_action_header        *ah;
-
-       off = 0;
-       if ((pout = ibuf_seek(ibuf, off, sizeof(*pout))) == NULL) {
-               log_debug("%s: seek failed: length %zd",
-                   __func__, ibuf_length(ibuf));
-               return (-1);
-       }
-
-       off += sizeof(*pout);
-       len = ntohs(pout->pout_actions_len);
-       log_debug("\tbuffer %s in_port %s actions_len %lu",
-           print_map(ntohl(pout->pout_buffer_id), ofp_pktout_map),
-           print_map(ntohl(pout->pout_in_port), ofp_port_map), len);
-
-       while (len > 0) {
-               if ((ah = ibuf_seek(ibuf, off, sizeof(*ah))) == NULL)
-                       return (-1);
-
-               noff = off;
-               ofp13_validate_action(sc, oh, ibuf, &off, ah);
-
-               diff = off - noff;
-               /* Loop prevention. */
-               if (off < noff || diff == 0)
-                       return (-1);
-
-               len -= diff;
-       }
-
-       /* Check for encapsulated packet truncation. */
-       len = ntohs(oh->oh_length) - off;
-       plen = ibuf_length(ibuf) - off;
-
-       if (plen < len) {
-               log_debug("\ttruncated packet %lu < %lu", plen, len);
-
-               /* Buffered packets can be truncated */
-               if (pout->pout_buffer_id != htonl(OFP_PKTOUT_NO_BUFFER))
-                       len = plen;
-               else
-                       return (-1);
-       }
-       if (ibuf_seek(ibuf, off, len) == NULL)
-               return (-1);
-
-       return (0);
-}
-
-int
-ofp13_validate_error(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_error                *err;
-       off_t                            off;
-       const char                      *code;
-
-       off = 0;
-       if ((err = ibuf_seek(ibuf, off, sizeof(*err))) == NULL) {
-               log_debug("%s: seek failed: length %zd",
-                   __func__, ibuf_length(ibuf));
-               return (-1);
-       }
-
-       switch (ntohs(err->err_type)) {
-       case OFP_ERRTYPE_FLOW_MOD_FAILED:
-               code = print_map(ntohs(err->err_code), ofp_errflowmod_map);
-               break;
-       case OFP_ERRTYPE_BAD_MATCH:
-               code = print_map(ntohs(err->err_code), ofp_errmatch_map);
-               break;
-       case OFP_ERRTYPE_BAD_INSTRUCTION:
-               code = print_map(ntohs(err->err_code), ofp_errinst_map);
-               break;
-       case OFP_ERRTYPE_BAD_REQUEST:
-               code = print_map(ntohs(err->err_code), ofp_errreq_map);
-               break;
-       default:
-               code = NULL;
-               break;
-       }
-
-       log_debug("\terror type %s code %u%s%s",
-           print_map(ntohs(err->err_type), ofp_errtype_map),
-           ntohs(err->err_code),
-           code == NULL ? "" : ": ",
-           code == NULL ? "" : code);
-
-       return (0);
-}
-
-int
-ofp13_input(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       if (ofp13_validate(sc, &con->con_peer, &con->con_local, oh, ibuf) != 0)
-               return (-1);
-
-       if (ofp13_callbacks[oh->oh_type].cb == NULL) {
-               log_debug("%s: message not supported: %s", __func__,
-                   print_map(oh->oh_type, ofp_t_map));
-               return (-1);
-       }
-       if (ofp13_callbacks[oh->oh_type].cb(sc, con, oh, ibuf) != 0) {
-               log_debug("%s: message parsing failed: %s", __func__,
-                   print_map(oh->oh_type, ofp_t_map));
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-ofp13_hello(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       if (switch_add(con) == NULL) {
-               log_debug("%s: failed to add switch", __func__);
-               return (-1);
-       }
-
-       if (ofp_recv_hello(sc, con, oh, ibuf) == -1)
-               return (-1);
-
-       return (ofp_nextstate(sc, con, OFP_STATE_FEATURE_WAIT));
-}
-
-int
-ofp13_echo_request(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       /* Echo reply */
-       oh->oh_type = OFP_T_ECHO_REPLY;
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, NULL) != 0)
-               return (-1);
-       ofp_output(con, oh, NULL);
-
-       return (0);
-}
-
-int
-ofp13_validate_features_reply(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_switch_features      *swf;
-
-       if ((swf = ibuf_seek(ibuf, 0, sizeof(*swf))) == NULL)
-               return (-1);
-
-       log_debug("\tdatapath_id %#016llx nbuffers %u ntables %d aux_id %d "
-           "capabilities %#08x",
-           be64toh(swf->swf_datapath_id), ntohl(swf->swf_nbuffers),
-           swf->swf_ntables, swf->swf_aux_id, ntohl(swf->swf_capabilities));
-       return (0);
-}
-
-int
-ofp13_features_reply(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       return (ofp_nextstate(sc, con, OFP_STATE_ESTABLISHED));
-}
-
-int
-ofp13_validate_action(struct switchd *sc, struct ofp_header *oh,
-    struct ibuf *ibuf, off_t *off, struct ofp_action_header *ah)
-{
-       struct ofp_action_output        *ao;
-       struct ofp_action_mpls_ttl      *amt;
-       struct ofp_action_push          *ap;
-       struct ofp_action_pop_mpls      *apm;
-       struct ofp_action_group         *ag;
-       struct ofp_action_nw_ttl        *ant;
-       struct ofp_action_set_field     *asf;
-       struct ofp_action_set_queue     *asq;
-       struct ofp_ox_match             *oxm;
-       size_t                           len;
-       int                              type;
-       off_t                            moff;
-
-       type = ntohs(ah->ah_type);
-       len = ntohs(ah->ah_len);
-
-       switch (type) {
-       case OFP_ACTION_OUTPUT:
-               if (len != sizeof(*ao))
-                       return (-1);
-               if ((ao = ibuf_seek(ibuf, *off, sizeof(*ao))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu port %s max_len %s",
-                   print_map(type, ofp_action_map), len,
-                   print_map(ntohl(ao->ao_port), ofp_port_map),
-                   print_map(ntohs(ao->ao_max_len),
-                   ofp_controller_maxlen_map));
-               break;
-       case OFP_ACTION_SET_MPLS_TTL:
-               if (len != sizeof(*amt))
-                       return (-1);
-               if ((amt = ibuf_seek(ibuf, *off, sizeof(*amt))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu ttl %d",
-                   print_map(type, ofp_action_map), len, amt->amt_ttl);
-               break;
-       case OFP_ACTION_PUSH_VLAN:
-       case OFP_ACTION_PUSH_MPLS:
-       case OFP_ACTION_PUSH_PBB:
-               if (len != sizeof(*ap))
-                       return (-1);
-               if ((ap = ibuf_seek(ibuf, *off, sizeof(*ap))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu ethertype %#04x",
-                   print_map(type, ofp_action_map), len,
-                   ntohs(ap->ap_ethertype));
-               break;
-       case OFP_ACTION_POP_MPLS:
-               if (len != sizeof(*apm))
-                       return (-1);
-               if ((apm = ibuf_seek(ibuf, *off, sizeof(*apm))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu ethertype %#04x",
-                   print_map(type, ofp_action_map), len,
-                   ntohs(apm->apm_ethertype));
-               break;
-       case OFP_ACTION_SET_QUEUE:
-               if (len != sizeof(*asq))
-                       return (-1);
-               if ((asq = ibuf_seek(ibuf, *off, sizeof(*asq))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu queue_id %u",
-                   print_map(type, ofp_action_map), len,
-                   ntohl(asq->asq_queue_id));
-               break;
-       case OFP_ACTION_GROUP:
-               if (len != sizeof(*ag))
-                       return (-1);
-               if ((ag = ibuf_seek(ibuf, *off, sizeof(*ag))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu group_id %s",
-                   print_map(type, ofp_action_map), len,
-                   print_map(ntohl(ag->ag_group_id), ofp_group_id_map));
-               break;
-       case OFP_ACTION_SET_NW_TTL:
-               if (len != sizeof(*ant))
-                       return (-1);
-               if ((ant = ibuf_seek(ibuf, *off, sizeof(*ant))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\t\taction %s len %lu ttl %d",
-                   print_map(type, ofp_action_map), len, ant->ant_ttl);
-               break;
-       case OFP_ACTION_SET_FIELD:
-               if (len < sizeof(*asf) || len != OFP_ALIGN(len))
-                       return (-1);
-               if ((asf = ibuf_seek(ibuf, *off, sizeof(*asf))) == NULL)
-                       return (-1);
-
-               moff = *off + sizeof(*asf) - sizeof(asf->asf_field);
-               *off += len;
-               log_debug("\t\taction %s len %lu",
-                   print_map(type, ofp_action_map), len);
-
-               len -= sizeof(*asf) - sizeof(asf->asf_field);
-               if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
-                       return (-1);
-               if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
-                       return (-1);
-
-               len -= sizeof(*oxm) + oxm->oxm_length;
-               if (len >= OFP_ALIGNMENT)
-                       return (-1);
-               break;
-
-       default:
-               if (len < sizeof(*ah))
-                       return (-1);
-
-               /* Generic header without information. */
-               *off += len;
-               log_debug("\t\taction %s len %lu",
-                   print_map(type, ofp_action_map), len);
-               break;
-       }
-
-       return (0);
-}
-
-int
-ofp13_validate_instruction(struct switchd *sc, struct ofp_header *oh,
-    struct ibuf *ibuf, off_t *off, struct ofp_instruction *i)
-{
-       struct ofp_instruction_actions          *ia;
-       struct ofp_instruction_goto_table       *igt;
-       struct ofp_instruction_write_metadata   *iwm;
-       struct ofp_instruction_meter            *im;
-       struct ofp_action_header                *ah;
-       int                                      type;
-       size_t                                   len;
-       off_t                                    oldoff, diff;
-
-       type = ntohs(i->i_type);
-       len = ntohs(i->i_len);
-
-       switch (type) {
-       case OFP_INSTRUCTION_T_GOTO_TABLE:
-               if (len != sizeof(*igt))
-                       return (-1);
-               if ((igt = ibuf_seek(ibuf, *off, sizeof(*igt))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\tinstruction %s length %lu table_id %s",
-                   print_map(type, ofp_instruction_t_map), len,
-                   print_map(igt->igt_table_id, ofp_table_id_map));
-               break;
-       case OFP_INSTRUCTION_T_WRITE_META:
-               if (len != sizeof(*iwm))
-                       return (-1);
-               if ((iwm = ibuf_seek(ibuf, *off, sizeof(*iwm))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\tinstruction %s length %lu "
-                   "metadata %#016llx mask %#016llx",
-                   print_map(type, ofp_instruction_t_map), len,
-                   be64toh(iwm->iwm_metadata),
-                   be64toh(iwm->iwm_metadata_mask));
-               break;
-       case OFP_INSTRUCTION_T_METER:
-               if (len != sizeof(*im))
-                       return (-1);
-               if ((im = ibuf_seek(ibuf, *off, sizeof(*im))) == NULL)
-                       return (-1);
-
-               *off += len;
-               log_debug("\tinstruction %s length %lu meter_id %d",
-                   print_map(type, ofp_instruction_t_map), len,
-                   im->im_meter_id);
-               break;
-       case OFP_INSTRUCTION_T_WRITE_ACTIONS:
-       case OFP_INSTRUCTION_T_CLEAR_ACTIONS:
-       case OFP_INSTRUCTION_T_APPLY_ACTIONS:
-               if (len < sizeof(*ia))
-                       return (-1);
-               if ((ia = ibuf_seek(ibuf, *off, sizeof(*ia))) == NULL)
-                       return (-1);
-
-               log_debug("\tinstruction %s length %lu",
-                   print_map(type, ofp_instruction_t_map), len);
-
-               *off += sizeof(*ia);
-               len -= sizeof(*ia);
-               while (len) {
-                       oldoff = *off;
-                       if ((ah = ibuf_seek(ibuf, *off, sizeof(*ah))) == NULL ||
-                           ofp13_validate_action(sc, oh, ibuf, off, ah) == -1)
-                               return (-1);
-
-                       diff = *off - oldoff;
-                       /* Loop prevention. */
-                       if (*off < oldoff || diff == 0)
-                               break;
-
-                       len -= diff;
-               }
-               break;
-       default:
-               if (len < sizeof(*i))
-                       return (-1);
-
-               log_debug("\tinstruction %s length %lu",
-                   print_map(type, ofp_instruction_t_map), len);
-               *off += len;
-               break;
-       }
-
-       return (0);
-}
-
-int
-ofp13_validate_flow_mod(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_flow_mod             *fm;
-       struct ofp_match                *om;
-       struct ofp_instruction          *i;
-       struct ofp_ox_match             *oxm;
-       off_t                            off, moff, offdiff;
-       int                              matchlen, matchtype, left;
-
-       off = 0;
-       if ((fm = ibuf_seek(ibuf, off, sizeof(*fm))) == NULL)
-               return (-1);
-
-       log_debug("\tcommand %s table %s timeout (idle %d hard %d) "
-           "priority %d buffer_id %s out_port %s out_group %s "
-           "flags %#04x cookie %#016llx mask %#016llx",
-           print_map(fm->fm_command, ofp_flowcmd_map),
-           print_map(fm->fm_table_id, ofp_table_id_map),
-           ntohs(fm->fm_idle_timeout), ntohs(fm->fm_hard_timeout),
-           ntohs(fm->fm_priority),
-           print_map(ntohl(fm->fm_buffer_id), ofp_pktout_map),
-           print_map(ntohl(fm->fm_out_port), ofp_port_map),
-           print_map(ntohl(fm->fm_out_group), ofp_group_id_map),
-           ntohs(fm->fm_flags), be64toh(fm->fm_cookie),
-           be64toh(fm->fm_cookie_mask));
-
-       off += offsetof(struct ofp_flow_mod, fm_match);
-
-       om = &fm->fm_match;
-       matchtype = ntohs(om->om_type);
-       matchlen = ntohs(om->om_length);
-
-       moff = off + sizeof(*om);
-       off += OFP_ALIGN(matchlen);
-
-       matchlen -= sizeof(*om);
-       while (matchlen) {
-               if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL ||
-                   ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
-                       return (-1);
-               moff += sizeof(*oxm) + oxm->oxm_length;
-               matchlen -= sizeof(*oxm) + oxm->oxm_length;
-       }
-
-       left = ntohs(oh->oh_length) - off;
-       moff = off;
-       while (left) {
-               if ((i = ibuf_seek(ibuf, moff, sizeof(*i))) == NULL ||
-                   ofp13_validate_instruction(sc, oh, ibuf, &moff, i) == -1)
-                       return (-1);
-
-               offdiff = moff - off;
-               /* Loop prevention. */
-               if (moff < off || offdiff == 0)
-                       break;
-
-               left -= offdiff;
-               off = moff;
-       }
-
-       return (0);
-}
-
-int
-ofp13_packet_match(struct ibuf *ibuf, struct packet *pkt, struct ofp_match *om)
-{
-       struct ether_header     *eh = pkt->pkt_eh;
-       size_t                   padsize, startpos, endpos, omlen;
-
-       if (eh == NULL)
-               return (-1);
-
-       startpos = ibuf->wpos;
-       if (oxm_etheraddr(ibuf, 1, eh->ether_shost, NULL) == -1)
-               return (-1);
-       if (oxm_etheraddr(ibuf, 0, eh->ether_dhost, NULL) == -1)
-               return (-1);
-       endpos = ibuf->wpos;
-
-       omlen = sizeof(*om) + (endpos - startpos);
-       padsize = OFP_ALIGN(omlen) - omlen;
-
-       om->om_type = htons(OFP_MATCH_OXM);
-       om->om_length = htons(omlen);
-       if (padsize && ibuf_advance(ibuf, padsize) == NULL)
-               return (-1);
-
-       return (0);
-}
-
-int
-ofp13_packet_in(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *ih, struct ibuf *ibuf)
-{
-       struct ofp_packet_in            *pin;
-       struct ofp_packet_out           *pout;
-       struct ofp_flow_mod             *fm;
-       struct ofp_header               *oh;
-       struct ofp_match                *om;
-       struct ofp_ox_match             *oxm;
-       struct packet                    pkt;
-       struct ibuf                     *obuf = NULL;
-       int                              table, ret = -1;
-       ssize_t                          len, mlen;
-       uint32_t                         srcport = 0, dstport;
-       int                              addflow = 0, sendbuffer = 0;
-       off_t                            off, moff;
-       void                            *ptr;
-       struct ofp_instruction_actions  *ia;
-
-       if ((pin = ibuf_getdata(ibuf, sizeof(*pin))) == NULL)
-               return (-1);
-
-       /* We only handle no matches right now. */
-       if (pin->pin_reason != OFP_PKTIN_REASON_NO_MATCH)
-               return (-1);
-
-       memset(&pkt, 0, sizeof(pkt));
-       len = ntohs(pin->pin_total_len);
-
-       /* very basic way of getting the source port */
-       om = &pin->pin_match;
-       mlen = ntohs(om->om_length);
-       off = (OFP_ALIGN(mlen) + ETHER_ALIGN) - sizeof(pin->pin_match);
-       moff = ibuf_dataoffset(ibuf);
-
-       do {
-               if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
-                       return (-1);
-
-               /* Find IN_PORT */
-               switch (ntohs(oxm->oxm_class)) {
-               case OFP_OXM_C_OPENFLOW_BASIC:
-                       switch (OFP_OXM_GET_FIELD(oxm)) {
-                       case OFP_XM_T_IN_PORT:
-                               moff += sizeof(*oxm);
-                               if ((ptr = ibuf_seek(ibuf, moff,
-                                   sizeof(srcport))) == NULL)
-                                       return (-1);
-                               srcport = htonl(*(uint32_t *)ptr);
-                               mlen = 0; /* break loop */
-                               break;
-                       default:
-                               /* ignore unsupported match types */
-                               break;
-                       }
-               default:
-                       /* ignore unsupported match classes */
-                       break;
-               }
-               moff += sizeof(*oxm) + oxm->oxm_length;
-               mlen -= sizeof(*oxm) + oxm->oxm_length;
-       } while (mlen > 0 && oxm->oxm_length);
-
-       /* Skip all matches and seek to the packet */
-       if (ibuf_getdata(ibuf, off) == NULL)
-               return (-1);
-
-       if (packet_ether_input(ibuf, len, &pkt) == -1 &&
-           pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
-               return(-1);
-
-       if (packet_input(sc, con->con_switch,
-           srcport, &dstport, &pkt) == -1 ||
-           (dstport > OFP_PORT_MAX &&
-           dstport != OFP_PORT_LOCAL &&
-           dstport != OFP_PORT_CONTROLLER)) {
-               /* fallback to flooding */
-               dstport = OFP_PORT_FLOOD;
-       } else if (srcport == dstport) {
-               /*
-                * silently drop looping packet
-                * (don't use OFP_PORT_INPUT here)
-                */
-               ret = 0;
-               goto done;
-       } else {
-               addflow = 1;
-       }
-
-       if ((obuf = ibuf_static()) == NULL)
-               goto done;
-
- again:
-       if (addflow) {
-               table = ofp13_getflowtable(con);
-               if (table > OFP_TABLE_ID_MAX || table < 0) {
-                       /* This switch doesn't support installing flows. */
-                       addflow = 0;
-                       goto again;
-               }
-
-               if ((fm = ibuf_advance(obuf, sizeof(*fm))) == NULL)
-                       goto done;
-
-               oh = &fm->fm_oh;
-               fm->fm_cookie = 0; /* XXX should we set a cookie? */
-               fm->fm_command = OFP_FLOWCMD_ADD;
-               fm->fm_idle_timeout = htons(sc->sc_cache_timeout);
-               fm->fm_hard_timeout = 0; /* permanent */
-               fm->fm_priority = 0;
-               fm->fm_buffer_id = pin->pin_buffer_id;
-               fm->fm_table_id = table;
-               fm->fm_flags = htons(OFP_FLOWFLAG_SEND_FLOW_REMOVED);
-               if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
-                       sendbuffer = 1;
-
-               /* Write flow matches to create an entry. */
-               if (ofp13_packet_match(obuf, &pkt, &fm->fm_match) == -1)
-                       goto done;
-
-               /*
-                * Write the instruction action header and add the output
-                * action.
-                */
-               if ((ia = ibuf_advance(obuf, sizeof(*ia))) == NULL ||
-                   action_output(obuf, dstport,
-                   OFP_CONTROLLER_MAXLEN_NO_BUFFER) == -1)
-                       goto done;
-
-               ia->ia_type = htons(OFP_INSTRUCTION_T_APPLY_ACTIONS);
-               ia->ia_len = htons(sizeof(*ia) +
-                   sizeof(struct ofp_action_output));
-       } else {
-               if ((pout = ibuf_advance(obuf, sizeof(*pout))) == NULL)
-                       goto done;
-
-               oh = &pout->pout_oh;
-               pout->pout_buffer_id = pin->pin_buffer_id;
-               pout->pout_in_port = htonl(srcport);
-               pout->pout_actions_len =
-                   htons(sizeof(struct ofp_action_output));
-
-               if (action_output(obuf, dstport,
-                   OFP_CONTROLLER_MAXLEN_NO_BUFFER) == -1)
-                       goto done;
-
-               /* Add optional packet payload */
-               if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER) &&
-                   imsg_add(obuf, pkt.pkt_buf, pkt.pkt_len) == -1)
-                       goto done;
-       }
-
-       /* Set output header */
-       oh->oh_version = OFP_V_1_3;
-       oh->oh_length = htons(ibuf_length(obuf));
-       oh->oh_type = addflow ? OFP_T_FLOW_MOD : OFP_T_PACKET_OUT;
-       oh->oh_xid = htonl(con->con_xidnxt++);
-
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, obuf) != 0)
-               goto done;
-
-       ofp_output(con, NULL, obuf);
-
-       if (sendbuffer) {
-               ibuf_release(obuf);
-
-               /* loop to output the packet again */
-               addflow = sendbuffer = 0;
-               if ((obuf = ibuf_static()) == NULL)
-                       goto done;
-               goto again;
-       }
-
-       ret = 0;
- done:
-       ibuf_release(obuf);
-       return (ret);
-}
-
-int
-ofp13_flow_removed(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *ih, struct ibuf *ibuf)
-{
-       struct ofp_flow_removed         *fr;
-
-       if ((fr = ibuf_getdata(ibuf, sizeof(*fr))) == NULL)
-               return (-1);
-
-       log_debug("cookie %#016llx priority %d reason %s table_id %s "
-           "duration(%u sec, %u nsec) timeout idle %d hard %d "
-           "packet %llu byte %llu",
-           be64toh(fr->fr_cookie), ntohs(fr->fr_priority),
-           print_map(fr->fr_reason, ofp_flowrem_reason_map),
-           print_map(fr->fr_table_id, ofp_table_id_map),
-           ntohl(fr->fr_duration_sec), ntohl(fr->fr_duration_nsec),
-           ntohs(fr->fr_idle_timeout), ntohs(fr->fr_hard_timeout),
-           be64toh(fr->fr_packet_count), be64toh(fr->fr_byte_count));
-
-       return (0);
-}
-
-int
-ofp13_tableproperties(struct switch_connection *con, struct ibuf *ibuf,
-    off_t off, size_t total, int new)
-{
-       struct ofp_table_features               *tf;
-       struct ofp_table_feature_property       *tp;
-       struct ofp_instruction                  *i;
-       struct ofp_action_header                *ah;
-       struct ofp_ox_match                     *oxm;
-       struct switch_table                     *st;
-       uint8_t                                 *next_table;
-       int                                      remaining, type, length;
-       int                                      hlen, padsize;
-       int                                      class, dtype, dlen;
-
-       /*
-        * This is a new table features reply, free our previous tables
-        * to get the updated ones.
-        */
-       if (new)
-               switch_freetables(con);
-
- next_table:
-       if ((tf = ibuf_seek(ibuf, off, sizeof(*tf))) == NULL)
-               return (-1);
-
-       hlen = htons(tf->tf_length);
-       total -= hlen;
-       remaining = hlen - sizeof(*tf);
-       off += sizeof(*tf);
-
-       st = switch_tablelookup(con, tf->tf_tableid);
-       if (st == NULL) {
-               st = switch_newtable(con, tf->tf_tableid);
-               if (st == NULL)
-                       return (-1);
-       }
-
-       st->st_maxentries = ntohl(tf->tf_max_entries);
-
- next_table_property:
-       if ((tp = ibuf_seek(ibuf, off, sizeof(*tp))) == NULL) {
-               switch_deltable(con, st);
-               return (-1);
-       }
-
-       type = ntohs(tp->tp_type);
-       length = ntohs(tp->tp_length);
-
-       /* Calculate the padding. */
-       padsize = OFP_ALIGN(length) - length;
-       remaining -= OFP_ALIGN(length);
-       length -= sizeof(*tp);
-       off += sizeof(*tp);
-
-       switch (type) {
-       case OFP_TABLE_FEATPROP_INSTRUCTION:
-       case OFP_TABLE_FEATPROP_INSTRUCTION_MISS:
-               if (type == OFP_TABLE_FEATPROP_INSTRUCTION)
-                       st->st_instructions = 0;
-               else
-                       st->st_instructionsmiss = 0;
-
-               while (length) {
-                       if ((i = ibuf_seek(ibuf, off, sizeof(*i))) == NULL) {
-                               switch_deltable(con, st);
-                               return (-1);
-                       }
-
-                       dtype = ntohs(i->i_type);
-                       dlen = ntohs(i->i_len);
-                       if (type == OFP_TABLE_FEATPROP_INSTRUCTION)
-                               st->st_instructions |= 1ULL << dtype;
-                       else
-                               st->st_instructionsmiss |= 1ULL << dtype;
-
-                       if (dtype == OFP_INSTRUCTION_T_EXPERIMENTER) {
-                               length -= dlen;
-                               off += dlen;
-                       } else {
-                               length -= sizeof(*i);
-                               off += sizeof(*i);
-                       }
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_NEXT_TABLES:
-       case OFP_TABLE_FEATPROP_NEXT_TABLES_MISS:
-               if (type == OFP_TABLE_FEATPROP_NEXT_TABLES)
-                       memset(st->st_nexttable, 0, sizeof(st->st_nexttable));
-               else
-                       memset(st->st_nexttablemiss, 0,
-                           sizeof(st->st_nexttablemiss));
-
-               while (length) {
-                       if ((next_table = ibuf_seek(ibuf, off,
-                           sizeof(*next_table))) == NULL) {
-                               switch_deltable(con, st);
-                               return (-1);
-                       }
-
-                       if (type == OFP_TABLE_FEATPROP_NEXT_TABLES)
-                               st->st_nexttable[(*next_table) / 64] |=
-                                   1ULL << ((*next_table) % 64);
-                       else
-                               st->st_nexttablemiss[(*next_table) / 64] |=
-                                   1ULL << ((*next_table) % 64);
-
-                       length -= sizeof(*next_table);
-                       off += sizeof(*next_table);
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_WRITE_ACTIONS:
-       case OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS:
-       case OFP_TABLE_FEATPROP_APPLY_ACTIONS:
-       case OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS:
-               if (type == OFP_TABLE_FEATPROP_WRITE_ACTIONS ||
-                   type == OFP_TABLE_FEATPROP_APPLY_ACTIONS)
-                       st->st_actions = 0;
-               else
-                       st->st_actionsmiss = 0;
-
-               while (length) {
-                       /*
-                        * NOTE the OpenFlow 1.3.5 specs says that we only
-                        * get 4 bytes here instead of the full action header.
-                        */
-                       if ((ah = ibuf_seek(ibuf, off, 4)) == NULL) {
-                               switch_deltable(con, st);
-                               return (-1);
-                       }
-
-                       dtype = ntohs(ah->ah_type);
-                       dlen = ntohs(ah->ah_len);
-                       if (type == OFP_TABLE_FEATPROP_WRITE_ACTIONS ||
-                           type == OFP_TABLE_FEATPROP_APPLY_ACTIONS)
-                               st->st_actions |= 1ULL << dtype;
-                       else
-                               st->st_actionsmiss |= 1ULL << dtype;
-
-                       if (dtype == OFP_ACTION_EXPERIMENTER) {
-                               length -= dlen;
-                               off += dlen;
-                       } else {
-                               length -= 4;
-                               off += 4;
-                       }
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_MATCH:
-       case OFP_TABLE_FEATPROP_WILDCARDS:
-       case OFP_TABLE_FEATPROP_WRITE_SETFIELD:
-       case OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS:
-       case OFP_TABLE_FEATPROP_APPLY_SETFIELD:
-       case OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS:
-               if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD ||
-                   type == OFP_TABLE_FEATPROP_APPLY_SETFIELD)
-                       st->st_setfield = 0;
-               else if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS ||
-                       type == OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS)
-                       st->st_setfieldmiss = 0;
-               else if (type == OFP_TABLE_FEATPROP_MATCH)
-                       st->st_match = 0;
-               else
-                       st->st_wildcard = 0;
-
-               while (length) {
-                       if ((oxm = ibuf_seek(ibuf, off,
-                           sizeof(*oxm))) == NULL) {
-                               switch_deltable(con, st);
-                               return (-1);
-                       }
-
-                       class = ntohs(oxm->oxm_class);
-                       if (class != OFP_OXM_C_OPENFLOW_BASIC) {
-                               if (class == OFP_OXM_C_OPENFLOW_EXPERIMENTER) {
-                                       length -= sizeof(*oxm) + 4;
-                                       off += sizeof(*oxm) + 4;
-                               } else {
-                                       length -= sizeof(*oxm);
-                                       off += sizeof(*oxm);
-                               }
-                               continue;
-                       }
-
-                       dtype = OFP_OXM_GET_FIELD(oxm);
-                       if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD ||
-                           type == OFP_TABLE_FEATPROP_APPLY_SETFIELD)
-                               st->st_setfield |= 1ULL << dtype;
-                       else if
-                           (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS ||
-                           type == OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS)
-                               st->st_setfieldmiss |= 1ULL << dtype;
-                       else if (type == OFP_TABLE_FEATPROP_MATCH)
-                               st->st_match |= 1ULL << dtype;
-                       else
-                               st->st_wildcard |= 1ULL << dtype;
-
-                       length -= sizeof(*oxm);
-                       off += sizeof(*oxm);
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_EXPERIMENTER:
-       case OFP_TABLE_FEATPROP_EXPERIMENTER_MISS:
-               off += length;
-               break;
-
-       default:
-               log_debug("Unsupported table property %d", type);
-               return (-1);
-       }
-
-       if (padsize)
-               off += padsize;
-       if (remaining > 0)
-               goto next_table_property;
-       if (total > 0)
-               goto next_table;
-
-       return (0);
-}
-
-int
-ofp13_multipart_reply(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_multipart            *mp;
-       int                              type, flags, more, new = 0;
-       int                              remaining;
-       off_t                            off;
-
-       off = 0;
-       if ((mp = ibuf_seek(ibuf, 0, sizeof(*mp))) == NULL)
-               return (-1);
-
-       type = ntohs(mp->mp_type);
-       flags = ntohs(mp->mp_flags);
-       remaining = ntohs(oh->oh_length) - sizeof(*mp);
-       off += sizeof(*mp);
-
-       more = (flags & OFP_MP_FLAG_REPLY_MORE) == OFP_MP_FLAG_REPLY_MORE;
-       /* Signalize new requests. */
-       if (ofp_multipart_lookup(con, oh->oh_xid) == NULL)
-               new = 1;
-
-       if (more) {
-               if (ofp_multipart_add(con, oh->oh_xid, type) == -1) {
-                       ofp13_error(sc, con, oh, ibuf,
-                           OFP_ERRTYPE_BAD_REQUEST,
-                           OFP_ERRREQ_MULTIPART_OVERFLOW);
-                       ofp_multipart_del(con, oh->oh_xid);
-                       return (0);
-               }
-
-               /*
-                * We don't need to concatenate with other messages,
-                * because the specification says that switches don't
-                * break objects. We should only need this if our parser
-                * requires the whole data before hand, but then we have
-                * better ways to achieve the same thing.
-                */
-       } else
-               ofp_multipart_del(con, oh->oh_xid);
-
-       switch (type) {
-       case OFP_MP_T_TABLE_FEATURES:
-               if (ofp13_tableproperties(con, ibuf, off, remaining, new))
-                       return (-1);
-
-               /* We finished receiving tables, configure the switch. */
-               if (more == 0)
-                       return (ofp13_switchconfigure(sc, con));
-               break;
-       }
-
-       return (0);
-}
-
-int
-ofp13_validate_tableproperty(struct ibuf *ibuf, off_t off, int remaining)
-{
-       struct ofp_table_features               *tf;
-       struct ofp_table_feature_property       *tp;
-       struct ofp_instruction                  *i;
-       struct ofp_action_header                *ah;
-       struct ofp_ox_match                     *oxm;
-       uint8_t                                 *nexttable;
-       int                                      hlen, htype, tplen;
-       int                                      type, length, class;
-       int                                      padsize;
-
- next_table:
-       if ((tf = ibuf_seek(ibuf, off, sizeof(*tf))) == NULL)
-               return (-1);
-
-       hlen = ntohs(tf->tf_length);
-       log_debug("\t\ttable features length %d tableid %s "
-           " name \"%s\" metadata match %#016llx write %#016llx "
-           "config %u max_entries %u",
-           hlen, print_map(tf->tf_tableid, ofp_table_id_map), tf->tf_name,
-           be64toh(tf->tf_metadata_match),
-           be64toh(tf->tf_metadata_write), ntohl(tf->tf_config),
-           ntohl(tf->tf_max_entries));
-
-       off += sizeof(*tf);
-       remaining -= sizeof(*tf);
-       hlen -= sizeof(*tf);
-
- next_property:
-       if ((tp = ibuf_seek(ibuf, off, sizeof(*tp))) == NULL)
-               return (-1);
-
-       off += sizeof(*tp);
-       htype = ntohs(tp->tp_type);
-       tplen = ntohs(tp->tp_length);
-       padsize = OFP_ALIGN(tplen) - tplen;
-       remaining -= tplen;
-       hlen -= tplen;
-
-       /* Don't count the header bytes for payload. */
-       tplen -= sizeof(*tp);
-
-       log_debug("\t\t%s (length %d):",
-           print_map(htype, ofp_table_featprop_map), tplen);
-       if (tplen <= 0)
-               goto empty_table;
-
-       switch (htype) {
-       case OFP_TABLE_FEATPROP_INSTRUCTION:
-       case OFP_TABLE_FEATPROP_INSTRUCTION_MISS:
-               while (tplen > 0) {
-                       if ((i = ibuf_seek(ibuf, off, sizeof(*i))) == NULL)
-                               return (-1);
-
-                       type = ntohs(i->i_type);
-                       length = ntohs(i->i_len);
-                       if (type == OFP_INSTRUCTION_T_EXPERIMENTER) {
-                               tplen -= length;
-                               off += length;
-                       } else {
-                               tplen -= sizeof(*i);
-                               off += sizeof(*i);
-                       }
-
-                       log_debug("\t\t\ttype %s length %d",
-                           print_map(type, ofp_instruction_t_map), length);
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_NEXT_TABLES:
-       case OFP_TABLE_FEATPROP_NEXT_TABLES_MISS:
-               while (tplen > 0) {
-                       if ((nexttable = ibuf_seek(ibuf, off,
-                           sizeof(*nexttable))) == NULL)
-                               return (-1);
-
-                       log_debug("\t\t\t%d", *nexttable);
-
-                       off += sizeof(*nexttable);
-                       tplen -= sizeof(*nexttable);
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_WRITE_ACTIONS:
-       case OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS:
-       case OFP_TABLE_FEATPROP_APPLY_ACTIONS:
-       case OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS:
-               while (tplen > 0) {
-                       /* NOTE: we read the action header without the pad. */
-                       if ((ah = ibuf_seek(ibuf, off, 4)) == NULL)
-                               return (-1);
-
-                       type = ntohs(ah->ah_type);
-                       length = ntohs(ah->ah_len);
-                       log_debug("\t\t\taction %s length %d",
-                           print_map(type, ofp_action_map), length);
-                       if (type == OFP_ACTION_EXPERIMENTER) {
-                               tplen -= length;
-                               off += length;
-                       } else {
-                               tplen -= 4;
-                               off += 4;
-                       }
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_MATCH:
-       case OFP_TABLE_FEATPROP_WILDCARDS:
-       case OFP_TABLE_FEATPROP_WRITE_SETFIELD:
-       case OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS:
-       case OFP_TABLE_FEATPROP_APPLY_SETFIELD:
-       case OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS:
-               while (tplen > 0) {
-                       if ((oxm = ibuf_seek(ibuf, off, sizeof(*oxm))) == NULL)
-                               return (-1);
-
-                       class = ntohs(oxm->oxm_class);
-                       type = OFP_OXM_GET_FIELD(oxm);
-                       length = oxm->oxm_length;
-                       if (class == OFP_OXM_C_OPENFLOW_EXPERIMENTER) {
-                               off += sizeof(*oxm) + 4;
-                               tplen -= sizeof(*oxm) + 4;
-                       } else {
-                               off += sizeof(*oxm);
-                               tplen -= sizeof(*oxm);
-                       }
-
-                       log_debug("\t\t\tclass %s type %s length %d",
-                           print_map(class, ofp_oxm_c_map),
-                           print_map(type, ofp_xm_t_map), length);
-               }
-               break;
-
-       case OFP_TABLE_FEATPROP_EXPERIMENTER:
-       case OFP_TABLE_FEATPROP_EXPERIMENTER_MISS:
-               off += tplen;
-               break;
-
-       default:
-               return (-1);
-       }
-
- empty_table:
-       if (padsize) {
-               off += padsize;
-               remaining -= padsize;
-               hlen -= padsize;
-       }
-       if (hlen > 0)
-               goto next_property;
-       if (remaining > 0)
-               goto next_table;
-
-       return (0);
-}
-
-int
-ofp13_multipart_reply_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_multipart            *mp;
-       struct ofp_flow_stats           *fs;
-       struct ofp_desc                 *d;
-       struct ofp_match                *om;
-       struct ofp_ox_match             *oxm;
-       struct ofp_instruction          *oi;
-       int                              mptype, mpflags, hlen;
-       int                              remaining, matchlen, matchtype;
-       int                              ilen, padsize;
-       off_t                            off, moff, offdiff;
-
-       remaining = ntohs(oh->oh_length);
-
-       off = 0;
-       if ((mp = ibuf_seek(ibuf, off, sizeof(*mp))) == NULL)
-               return (-1);
-
-       mptype = ntohs(mp->mp_type);
-       mpflags = ntohs(mp->mp_flags);
-       log_debug("\ttype %s flags %#04x",
-           print_map(mptype, ofp_mp_t_map), mpflags);
-
-       off += sizeof(*mp);
-       remaining -= sizeof(*mp);
-       if (remaining == 0) {
-               log_debug("\tempty reply");
-               return (0);
-       }
-
-       switch (mptype) {
-       case OFP_MP_T_DESC:
-               if ((d = ibuf_seek(ibuf, off, sizeof(*d))) == NULL)
-                       return (-1);
-
-               off += sizeof(*d);
-               remaining -= sizeof(*d);
-               log_debug("\tmfr_desc \"%s\" hw_desc \"%s\" sw_desc \"%s\" "
-                   "serial_num \"%s\" dp_desc \"%s\"",
-                   d->d_mfr_desc, d->d_hw_desc, d->d_sw_desc,
-                   d->d_serial_num, d->d_dp_desc);
-               break;
-
-       case OFP_MP_T_FLOW:
- read_next_flow:
-               if ((fs = ibuf_seek(ibuf, off, sizeof(*fs))) == NULL)
-                       return (-1);
-
-               hlen = ntohs(fs->fs_length);
-               remaining -= hlen;
-               moff = off + sizeof(*fs);
-               off += hlen;
-
-               log_debug("\tflow length %d table_id %s duration sec %u "
-                   "nsec %u prio %d timeout idle %d hard %d flags %#04x "
-                   "cookie %#016llx packet count %llu byte count %llu",
-                   hlen, print_map(fs->fs_table_id, ofp_table_id_map),
-                   ntohl(fs->fs_duration_sec), ntohl(fs->fs_duration_nsec),
-                   ntohs(fs->fs_priority), ntohs(fs->fs_idle_timeout),
-                   ntohs(fs->fs_hard_timeout), ntohs(fs->fs_flags),
-                   be64toh(fs->fs_cookie), be64toh(fs->fs_packet_count),
-                   be64toh(fs->fs_byte_count));
-
-               om = &fs->fs_match;
-               matchtype = ntohs(om->om_type);
-               matchlen = ntohs(om->om_length);
-               padsize = OFP_ALIGN(matchlen) - matchlen;
-               ilen = hlen -
-                   ((sizeof(*fs) - sizeof(*om)) + matchlen + padsize);
-
-               /* We don't know how to parse anything else yet. */
-               if (matchtype != OFP_MATCH_OXM)
-                       break;
-
-               matchlen -= sizeof(*om);
-               while (matchlen) {
-                       if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
-                               return (-1);
-                       if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
-                               return (-1);
-                       moff += sizeof(*oxm) + oxm->oxm_length;
-                       matchlen -= sizeof(*oxm) + oxm->oxm_length;
-               }
-
-               moff += padsize;
-
-               while (ilen) {
-                       offdiff = moff;
-                       if ((oi = ibuf_seek(ibuf, moff, sizeof(*oi))) == NULL ||
-                           ofp13_validate_instruction(sc, oh, ibuf,
-                           &moff, oi) == -1)
-                               return (-1);
-                       /* Avoid loops. */
-                       if ((moff - offdiff) == 0)
-                               return (-1);
-
-                       ilen -= moff - offdiff;
-               }
-
-               if (remaining)
-                       goto read_next_flow;
-               break;
-
-       case OFP_MP_T_AGGREGATE:
-       case OFP_MP_T_TABLE:
-       case OFP_MP_T_PORT_STATS:
-       case OFP_MP_T_QUEUE:
-       case OFP_MP_T_GROUP:
-       case OFP_MP_T_GROUP_DESC:
-       case OFP_MP_T_GROUP_FEATURES:
-       case OFP_MP_T_METER:
-       case OFP_MP_T_METER_CONFIG:
-       case OFP_MP_T_METER_FEATURES:
-               break;
-
-       case OFP_MP_T_TABLE_FEATURES:
-               if (ofp13_validate_tableproperty(ibuf, off, remaining))
-                       return (-1);
-               break;
-
-       case OFP_MP_T_PORT_DESC:
-       case OFP_MP_T_EXPERIMENTER:
-               break;
-
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-/* Don't forget to update mp->mp_oh.oh_length */
-struct ofp_multipart *
-ofp13_multipart_request(struct switch_connection *con, struct ibuf *ibuf,
-    uint16_t type, uint16_t flags)
-{
-       struct ofp_multipart            *mp;
-       struct ofp_header               *oh;
-
-       if ((mp = ibuf_advance(ibuf, sizeof(*mp))) == NULL)
-               return (NULL);
-
-       oh = &mp->mp_oh;
-       oh->oh_version = OFP_V_1_3;
-       oh->oh_type = OFP_T_MULTIPART_REQUEST;
-       oh->oh_xid = htonl(con->con_xidnxt++);
-       mp->mp_type = htons(type);
-       mp->mp_flags = htons(flags);
-       return (mp);
-}
-
-int
-ofp13_multipart_request_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_multipart            *mp;
-       struct ofp_match                *om;
-       struct ofp_flow_stats_request   *fsr;
-       struct ofp_ox_match             *oxm;
-       off_t                            off, moff;
-       int                              type, flags, totallen;
-       int                              matchlen, matchtype;
-
-       off = 0;
-       if ((mp = ibuf_seek(ibuf, off, sizeof(*mp))) == NULL)
-               return (-1);
-
-       type = ntohs(mp->mp_type);
-       flags = ntohs(mp->mp_flags);
-       log_debug("\ttype %s flags %#04x",
-           print_map(type, ofp_mp_t_map), flags);
-
-       totallen = ntohs(oh->oh_length);
-       off += sizeof(*mp);
-
-       switch (type) {
-       case OFP_MP_T_DESC:
-               /* This type doesn't use a payload. */
-               if (totallen != sizeof(*mp))
-                       return (-1);
-               break;
-
-       case OFP_MP_T_FLOW:
-               if ((fsr = ibuf_seek(ibuf, off, sizeof(*fsr))) == NULL)
-                       return (-1);
-
-               om = &fsr->fsr_match;
-               matchtype = ntohs(om->om_type);
-               matchlen = ntohs(om->om_length);
-               log_debug("\ttable_id %s out_port %s out_group %s "
-                   "cookie %#016llx mask %#016llx match type %s length %d "
-                   "(padded to %d)",
-                   print_map(fsr->fsr_table_id, ofp_table_id_map),
-                   print_map(ntohl(fsr->fsr_out_port), ofp_port_map),
-                   print_map(ntohl(fsr->fsr_out_group), ofp_group_id_map),
-                   be64toh(fsr->fsr_cookie), be64toh(fsr->fsr_cookie_mask),
-                   print_map(matchtype, ofp_match_map), matchlen,
-                   OFP_ALIGN(matchlen));
-
-               /* Get the first OXM byte offset. */
-               moff = off + sizeof(*fsr);
-
-               /* Don't count the header bytes. */
-               matchlen -= sizeof(*om);
-
-               /* We don't know how to parse anything else yet. */
-               if (matchtype != OFP_MATCH_OXM)
-                       break;
-
-               while (matchlen) {
-                       if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
-                               return (-1);
-                       if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
-                               return (-1);
-                       moff += sizeof(*oxm) + oxm->oxm_length;
-                       matchlen -= sizeof(*oxm) + oxm->oxm_length;
-               }
-               break;
-
-       case OFP_MP_T_AGGREGATE:
-       case OFP_MP_T_TABLE:
-       case OFP_MP_T_PORT_STATS:
-       case OFP_MP_T_QUEUE:
-       case OFP_MP_T_GROUP:
-       case OFP_MP_T_GROUP_DESC:
-       case OFP_MP_T_GROUP_FEATURES:
-       case OFP_MP_T_METER:
-       case OFP_MP_T_METER_CONFIG:
-       case OFP_MP_T_METER_FEATURES:
-               break;
-
-       case OFP_MP_T_TABLE_FEATURES:
-               if (totallen == sizeof(*mp)) {
-                       log_debug("\tempty table properties request");
-                       break;
-               }
-               break;
-
-       case OFP_MP_T_PORT_DESC:
-       case OFP_MP_T_EXPERIMENTER:
-               break;
-
-       default:
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-ofp13_desc(struct switchd *sc, struct switch_connection *con)
-{
-       struct ofp_header               *oh;
-       struct ofp_multipart            *mp;
-       struct ibuf                     *ibuf;
-       int                              rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL)
-               return (-1);
-
-       if ((mp = ofp13_multipart_request(con, ibuf, OFP_MP_T_DESC, 0)) == NULL)
-               goto done;
-
-       oh = &mp->mp_oh;
-       oh->oh_length = htons(sizeof(*mp));
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-int
-ofp13_flow_stats(struct switchd *sc, struct switch_connection *con,
-    uint32_t out_port, uint32_t out_group, uint8_t table_id)
-{
-       struct ofp_header               *oh;
-       struct ofp_multipart            *mp;
-       struct ofp_flow_stats_request   *fsr;
-       struct ofp_match                *om;
-       struct ibuf                     *ibuf;
-       int                              padsize, rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL)
-               return (-1);
-
-       if ((mp = ofp13_multipart_request(con, ibuf, OFP_MP_T_FLOW, 0)) == NULL)
-               goto done;
-       if ((fsr = ibuf_advance(ibuf, sizeof(*fsr))) == NULL)
-               goto done;
-
-       oh = &mp->mp_oh;
-       fsr->fsr_table_id = table_id;
-       fsr->fsr_out_port = htonl(out_port);
-       fsr->fsr_out_group = htonl(out_group);
-
-       om = &fsr->fsr_match;
-       om->om_type = htons(OFP_MATCH_OXM);
-       om->om_length = htons(sizeof(*om));
-       padsize = OFP_ALIGN(sizeof(*om)) - sizeof(*om);
-       if (padsize && ibuf_advance(ibuf, padsize) == NULL)
-               goto done;
-
-       oh->oh_length = htons(ibuf_length(ibuf));
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-int
-ofp13_table_features(struct switchd *sc, struct switch_connection *con,
-    uint8_t tableid)
-{
-       struct ofp_header               *oh;
-       struct ofp_multipart            *mp;
-       struct ibuf                     *ibuf;
-       int                              rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL)
-               return (-1);
-
-       if ((mp = ofp13_multipart_request(con, ibuf,
-           OFP_MP_T_TABLE_FEATURES, 0)) == NULL)
-               goto done;
-
-       oh = &mp->mp_oh;
-       oh->oh_length = htons(sizeof(*mp));
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-int
-ofp13_error(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf, uint16_t type, uint16_t code)
-{
-       struct ibuf             *obuf;
-       struct ofp_error        *err;
-       struct ofp_header       *header;
-       int                      dlen, rv = -1;
-
-       if ((obuf = ibuf_static()) == NULL ||
-           (err = ibuf_advance(obuf, sizeof(*err))) == NULL)
-               goto done;
-
-       header = &err->err_oh;
-       err->err_type = htons(type);
-       err->err_code = htons(code);
-
-       /* Copy the first message bytes for the error payload. */
-       dlen = ibuf_size(ibuf);
-       if (dlen > OFP_ERRDATA_MAX)
-               dlen = OFP_ERRDATA_MAX;
-       if (ibuf_add(obuf, ibuf_seek(ibuf, 0, dlen), dlen) == -1)
-               goto done;
-
-       header->oh_version = OFP_V_1_3;
-       header->oh_type = OFP_T_ERROR;
-       header->oh_length = htons(ibuf_length(obuf));
-       header->oh_xid = oh->oh_xid;
-       if (ofp13_validate(sc, &con->con_peer, &con->con_local, header,
-           obuf) == -1)
-               goto done;
-
-       rv = ofp_output(con, NULL, obuf);
-
- done:
-       ibuf_free(obuf);
-       return (rv);
-}
-
-/*
- * The valid commands for groups are:
- * OFP_GROUPCMD_{ADD,MODIFY,DELETE}
- *
- * The valid type for groups are:
- * OFP_GROUP_T_{ALL,SELECT,INDIRECT,FAST_FAILOVER}
- *
- * You have to update the gm->gm_oh.oh_length = htons(ibuf_length(ibuf));
- */
-struct ofp_group_mod *
-ofp13_group(struct switch_connection *con, struct ibuf *ibuf,
-    uint32_t gid, uint16_t cmd, uint8_t type)
-{
-       struct ofp_group_mod            *gm;
-       struct ofp_header               *oh;
-
-       if ((gm = ibuf_advance(ibuf, sizeof(*gm))) == NULL)
-               return (NULL);
-
-       oh = &gm->gm_oh;
-       oh->oh_version = OFP_V_1_3;
-       oh->oh_type = OFP_T_GROUP_MOD;
-       oh->oh_xid = htonl(con->con_xidnxt++);
-       gm->gm_command = htons(cmd);
-       gm->gm_type = type;
-       gm->gm_group_id = htonl(gid);
-       return (gm);
-}
-
-/* Remember to update b->b_len. */
-struct ofp_bucket *
-ofp13_bucket(struct ibuf *ibuf, uint16_t weight, uint32_t watchport,
-    uint32_t watchgroup)
-{
-       struct ofp_bucket               *b;
-
-       if ((b = ibuf_advance(ibuf, sizeof(*b))) == NULL)
-               return (NULL);
-
-       b->b_weight = htons(weight);
-       b->b_watch_port = htonl(watchport);
-       b->b_watch_group = htonl(watchgroup);
-       return (b);
-}
-
-int
-ofp13_setconfig_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_switch_config        *cfg;
-
-       if ((cfg = ibuf_seek(ibuf, 0, sizeof(*cfg))) == NULL)
-               return (-1);
-
-       log_debug("\tflags %#04x miss_send_len %s",
-           ntohs(cfg->cfg_flags), print_map(ntohs(cfg->cfg_miss_send_len),
-           ofp_controller_maxlen_map));
-       return (0);
-}
-
-int
-ofp13_setconfig(struct switchd *sc, struct switch_connection *con,
-     uint16_t flags, uint16_t misslen)
-{
-       struct ibuf                     *ibuf;
-       struct ofp_switch_config        *cfg;
-       struct ofp_header               *oh;
-       int                              rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL ||
-           (cfg = ibuf_advance(ibuf, sizeof(*cfg))) == NULL)
-               goto done;
-
-       cfg->cfg_flags = htons(flags);
-       cfg->cfg_miss_send_len = htons(misslen);
-
-       oh = &cfg->cfg_oh;
-       oh->oh_version = OFP_V_1_3;
-       oh->oh_type = OFP_T_SET_CONFIG;
-       oh->oh_length = htons(ibuf_length(ibuf));
-       oh->oh_xid = htonl(con->con_xidnxt++);
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-/*
- * Flow modification message.
- *
- * After the flow-mod header we have N OXM filters to match packets, when
- * you finish adding them you must update match header:
- * fm_match.om_length = sizeof(fm_match) + OXM length.
- *
- * Then you must add flow instructions and update the OFP header length:
- * fm_oh.oh_length =
- *     sizeof(*fm) + (fm_match.om_len - sizeof(fm_match)) + instructionslen.
- * or
- * fm_oh.oh_length = ibuf_length(ibuf).
- *
- * Note on match payload:
- * After adding all matches and before starting to insert instructions you
- * must add the mandatory padding to fm_match. You can calculate the padding
- * size with this formula:
- * padsize = OFP_ALIGN(fm_match.om_length) - fm_match.om_length;
- *
- * Note on Table-miss:
- * To make a table miss you need to set priority 0 and don't add any
- * matches, just instructions.
- */
-struct ofp_flow_mod *
-ofp13_flowmod(struct switch_connection *con, struct ibuf *ibuf,
-    uint8_t cmd)
-{
-       struct ofp_flow_mod             *fm;
-
-       if ((fm = ibuf_advance(ibuf, sizeof(*fm))) == NULL)
-               return (NULL);
-
-       fm->fm_oh.oh_version = OFP_V_1_3;
-       fm->fm_oh.oh_type = OFP_T_FLOW_MOD;
-       fm->fm_oh.oh_length = htons(sizeof(*fm));
-       fm->fm_oh.oh_xid = htonl(con->con_xidnxt++);
-
-       fm->fm_command = cmd;
-       fm->fm_buffer_id = htonl(OFP_PKTOUT_NO_BUFFER);
-       fm->fm_flags = htons(OFP_FLOWFLAG_SEND_FLOW_REMOVED);
-
-       fm->fm_match.om_type = htons(OFP_MATCH_OXM);
-       fm->fm_match.om_length = htons(sizeof(fm->fm_match));
-
-       return (fm);
-}
-
-int
-ofp13_tablemiss_sendctrl(struct switchd *sc, struct switch_connection *con,
-    uint8_t table)
-{
-       struct oflowmod_ctx      ctx;
-       struct ibuf             *ibuf;
-       int                      ret;
-
-       if ((ibuf = oflowmod_open(&ctx, con, NULL, OFP_V_1_3)) == NULL)
-               goto err;
-
-       if (oflowmod_iopen(&ctx) == -1)
-               goto err;
-
-       /* Update header */
-       ctx.ctx_fm->fm_table_id = table;
-
-       if (oflowmod_instruction(&ctx,
-           OFP_INSTRUCTION_T_APPLY_ACTIONS) == -1)
-               goto err;
-       if (action_output(ibuf, OFP_PORT_CONTROLLER,
-           OFP_CONTROLLER_MAXLEN_MAX) == -1)
-               goto err;
-
-       if (oflowmod_iclose(&ctx) == -1)
-               goto err;
-       if (oflowmod_close(&ctx) == -1)
-               goto err;
-
-       if (ofp13_validate(sc, &con->con_local, &con->con_peer,
-           &ctx.ctx_fm->fm_oh, ibuf) != 0)
-               goto err;
-
-       ret = ofp_output(con, NULL, ibuf);
-       ibuf_release(ibuf);
-
-       return (ret);
-
- err:
-       (void)oflowmod_err(&ctx, __func__, __LINE__);
-       return (-1);
-}
-
-int
-ofp13_switchconfigure(struct switchd *sc, struct switch_connection *con)
-{
-       struct switch_table             *st;
-
-       /* Look for a table with 'apply' and 'output' support for miss. */
-       TAILQ_FOREACH(st, &con->con_stlist, st_entry) {
-               if ((st->st_instructionsmiss &
-                   (1ULL << OFP_INSTRUCTION_T_APPLY_ACTIONS)) == 0)
-                       continue;
-               if ((st->st_actionsmiss & (1ULL << OFP_ACTION_OUTPUT)) == 0)
-                       continue;
-
-               break;
-       }
-       if (st == NULL) {
-               log_warn("No apply output for this switch");
-               return (-1);
-       }
-
-       /* Install the flow to receive packets from the switch. */
-       return (ofp13_tablemiss_sendctrl(sc, con, st->st_table));
-}
-
-int
-ofp13_getflowtable(struct switch_connection *con)
-{
-       struct switch_table             *st;
-
-       /* Look for a table with 'apply' and 'output' support. */
-       TAILQ_FOREACH(st, &con->con_stlist, st_entry) {
-               if ((st->st_instructions &
-                   (1ULL << OFP_INSTRUCTION_T_APPLY_ACTIONS)) == 0)
-                       continue;
-               if ((st->st_actions & (1ULL << OFP_ACTION_OUTPUT)) == 0)
-                       continue;
-
-               break;
-       }
-       if (st == NULL)
-               return (-1);
-
-       return (st->st_table);
-}
diff --git a/usr.sbin/switchd/ofp_common.c b/usr.sbin/switchd/ofp_common.c
deleted file mode 100644 (file)
index 323ce04..0000000
+++ /dev/null
@@ -1,1488 +0,0 @@
-/*     $OpenBSD: ofp_common.c,v 1.11 2019/11/21 06:22:57 akoshibe Exp $        */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2016 Rafael Zalamena <rzalamena@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ofp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-#include <netmpls/mpls.h>
-
-#include <endian.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <imsg.h>
-#include <event.h>
-
-#include "switchd.h"
-#include "ofp_map.h"
-
-int            ofp_setversion(struct switch_connection *, int);
-
-int
-ofp_validate_header(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, uint8_t version)
-{
-       struct constmap *tmap;
-
-       /* For debug, don't verify the header if the version is unset */
-       if (version != OFP_V_0 &&
-           (oh->oh_version != version ||
-           oh->oh_type >= OFP_T_TYPE_MAX))
-               return (-1);
-
-       switch (version) {
-       case OFP_V_1_0:
-       case OFP_V_1_1:
-               tmap = ofp10_t_map;
-               break;
-       case OFP_V_1_3:
-       default:
-               tmap = ofp_t_map;
-               break;
-       }
-
-       log_debug("%s > %s: version %s type %s length %u xid %u",
-           print_host(src, NULL, 0),
-           print_host(dst, NULL, 0),
-           print_map(oh->oh_version, ofp_v_map),
-           print_map(oh->oh_type, tmap),
-           ntohs(oh->oh_length), ntohl(oh->oh_xid));
-
-       return (0);
-}
-
-int
-ofp_validate(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf, uint8_t version)
-{
-       switch (version) {
-       case OFP_V_1_0:
-               return (ofp10_validate(sc, src, dst, oh, ibuf));
-       case OFP_V_1_3:
-               return (ofp13_validate(sc, src, dst, oh, ibuf));
-       default:
-               return (-1);
-       }
-
-       /* NOTREACHED */
-}
-
-int
-ofp_output(struct switch_connection *con, struct ofp_header *oh,
-    struct ibuf *obuf)
-{
-       struct ibuf     *buf;
-
-       if ((buf = ibuf_static()) == NULL)
-               return (-1);
-       if ((oh != NULL) &&
-           (ibuf_add(buf, oh, sizeof(*oh)) == -1)) {
-               ibuf_release(buf);
-               return (-1);
-       }
-       if ((obuf != NULL) &&
-           (ibuf_cat(buf, obuf) == -1)) {
-               ibuf_release(buf);
-               return (-1);
-       }
-
-       ofrelay_write(con, buf);
-
-       return (0);
-}
-
-int
-ofp_send_hello(struct switchd *sc, struct switch_connection *con, int version)
-{
-       struct ofp_hello_element_header *he;
-       struct ofp_header               *oh;
-       struct ibuf                     *ibuf;
-       size_t                           hstart, hend;
-       uint32_t                        *bmp;
-       int                              rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL ||
-           (oh = ibuf_advance(ibuf, sizeof(*oh))) == NULL ||
-           (he = ibuf_advance(ibuf, sizeof(*he))) == NULL)
-               goto done;
-
-       /* Write down all versions we support. */
-       hstart = ibuf->wpos;
-       if ((bmp = ibuf_advance(ibuf, sizeof(*bmp))) == NULL)
-               goto done;
-
-       *bmp = htonl((1 << OFP_V_1_0) | (1 << OFP_V_1_3));
-       hend = ibuf->wpos;
-
-       /* Fill the headers. */
-       oh->oh_version = version;
-       oh->oh_type = OFP_T_HELLO;
-       oh->oh_length = htons(ibuf_length(ibuf));
-       oh->oh_xid = htonl(con->con_xidnxt++);
-       he->he_type = htons(OFP_HELLO_T_VERSION_BITMAP);
-       he->he_length = htons(sizeof(*he) + (hend - hstart));
-
-       if (ofp_validate(sc, &con->con_local, &con->con_peer, oh, ibuf,
-           version) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-int
-ofp_validate_hello(struct switchd *sc,
-    struct sockaddr_storage *src, struct sockaddr_storage *dst,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_hello_element_header *he;
-       uint32_t                        *bmp;
-       off_t                            poff;
-       int                              helen, i, ver;
-
-       /* No extra element headers. */
-       if (ntohs(oh->oh_length) == sizeof(*oh))
-               return (0);
-
-       /* Test for supported element headers. */
-       if ((he = ibuf_seek(ibuf, sizeof(*oh), sizeof(*he))) == NULL)
-               return (-1);
-       if (he->he_type != htons(OFP_HELLO_T_VERSION_BITMAP))
-               return (-1);
-
-       log_debug("\tversion bitmap:");
-
-       /* Validate header sizes. */
-       helen = ntohs(he->he_length);
-       if (helen < (int)sizeof(*he))
-               return (-1);
-       else if (helen == sizeof(*he))
-               return (0);
-
-       helen -= sizeof(*he);
-       /* Invalid bitmap size. */
-       if ((helen % sizeof(*bmp)) != 0)
-               return (-1);
-
-       ver = 0;
-       poff = sizeof(*oh) + sizeof(*he);
-       while (helen > 0) {
-               if ((bmp = ibuf_seek(ibuf, poff, sizeof(*bmp))) == NULL)
-                       return (-1);
-
-               for (i = 0; i < 32; i++, ver++) {
-                       if ((ntohl(*bmp) & (1 << i)) == 0)
-                               continue;
-
-                       log_debug("\t\tversion %s",
-                           print_map(ver, ofp_v_map));
-               }
-
-               helen -= sizeof(*bmp);
-               poff += sizeof(*bmp);
-       }
-
-       return (0);
-}
-
-int
-ofp_setversion(struct switch_connection *con, int version)
-{
-       switch (version) {
-       case OFP_V_1_0:
-       case OFP_V_1_3:
-               con->con_version = version;
-               return (0);
-
-       default:
-               return (-1);
-       }
-}
-
-int
-ofp_recv_hello(struct switchd *sc, struct switch_connection *con,
-    struct ofp_header *oh, struct ibuf *ibuf)
-{
-       struct ofp_hello_element_header *he;
-       uint32_t                        *bmp;
-       off_t                            poff;
-       int                              helen, i, ver;
-
-       /* No extra element headers, just use the header version. */
-       if (ntohs(oh->oh_length) == sizeof(*oh))
-               return (ofp_setversion(con, oh->oh_version));
-
-       /* Read the element header. */
-       if ((he = ibuf_seek(ibuf, sizeof(*oh), sizeof(*he))) == NULL)
-               return (-1);
-
-       /* We don't support anything else than the version bitmap. */
-       if (he->he_type != htons(OFP_HELLO_T_VERSION_BITMAP))
-               return (-1);
-
-       /* Validate header sizes. */
-       helen = ntohs(he->he_length);
-       if (helen < (int)sizeof(*he))
-               return (-1);
-       else if (helen == sizeof(*he))
-               return (ofp_setversion(con, oh->oh_version));
-
-       helen -= sizeof(*he);
-       /* Invalid bitmap size. */
-       if ((helen % sizeof(*bmp)) != 0)
-               return (-1);
-
-       ver = 0;
-       poff = sizeof(*oh) + sizeof(*he);
-
-       /* Loop through the bitmaps and choose the higher version. */
-       while (helen > 0) {
-               if ((bmp = ibuf_seek(ibuf, poff, sizeof(*bmp))) == NULL)
-                       return (-1);
-
-               for (i = 0; i < 32; i++, ver++) {
-                       if ((ntohl(*bmp) & (1 << i)) == 0)
-                               continue;
-
-                       ofp_setversion(con, ver);
-               }
-
-               helen -= sizeof(*bmp);
-               poff += sizeof(*bmp);
-       }
-
-       /* Check if we have set any version, otherwise fallback. */
-       if (con->con_version == OFP_V_0)
-               return (ofp_setversion(con, oh->oh_version));
-
-       return (0);
-}
-
-int
-ofp_send_featuresrequest(struct switchd *sc, struct switch_connection *con)
-{
-       struct ofp_header       *oh;
-       struct ibuf             *ibuf;
-       int                      rv = -1;
-
-       if ((ibuf = ibuf_static()) == NULL ||
-           (oh = ibuf_advance(ibuf, sizeof(*oh))) == NULL)
-               return (-1);
-
-       oh->oh_version = con->con_version;
-       oh->oh_type = OFP_T_FEATURES_REQUEST;
-       oh->oh_length = htons(ibuf_length(ibuf));
-       oh->oh_xid = htonl(con->con_xidnxt++);
-       if (ofp_validate(sc, &con->con_local, &con->con_peer, oh, ibuf,
-           con->con_version) != 0)
-               goto done;
-
-       rv = ofp_output(con, NULL, ibuf);
-
- done:
-       ibuf_free(ibuf);
-       return (rv);
-}
-
-/* Appends an action with just the generic header. */
-int
-action_new(struct ibuf *ibuf, uint16_t type)
-{
-       struct ofp_action_header        *ah;
-
-       if ((ah = ibuf_advance(ibuf, sizeof(*ah))) == NULL)
-               return (-1);
-
-       ah->ah_type = htons(type);
-       ah->ah_len = htons(sizeof(*ah));
-       return (0);
-}
-
-int
-action_group(struct ibuf *ibuf, uint32_t group)
-{
-       struct ofp_action_group         *ag;
-
-       if ((ag = ibuf_advance(ibuf, sizeof(*ag))) == NULL)
-               return (-1);
-
-       ag->ag_type = htons(OFP_ACTION_GROUP);
-       ag->ag_len = sizeof(*ag);
-       ag->ag_group_id = htonl(group);
-       return (0);
-}
-
-int
-action_output(struct ibuf *ibuf, uint32_t port, uint16_t maxlen)
-{
-       struct ofp_action_output        *ao;
-
-       if ((ao = ibuf_advance(ibuf, sizeof(*ao))) == NULL)
-               return (-1);
-
-       ao->ao_type = htons(OFP_ACTION_OUTPUT);
-       ao->ao_len = htons(sizeof(*ao));
-       ao->ao_port = htonl(port);
-       ao->ao_max_len = htons(maxlen);
-       return (0);
-}
-
-/*
- * This action pushes VLAN/MPLS/PBB tags into the outermost part of the
- * packet. When the type is X ethertype must be Y:
- * - OFP_ACTION_PUSH_VLAN: ETHERTYPE_VLAN or ETHERTYPE_QINQ.
- * - OFP_ACTION_PUSH_MPLS: ETHERTYPE_MPLS or ETHERTYPE_MPLSCAST.
- * - OFP_ACTION_PUSH_PBB: ETHERTYPE_??? (0x88E7).
- */
-int
-action_push(struct ibuf *ibuf, uint16_t type, uint16_t ethertype)
-{
-       struct ofp_action_push          *ap;
-
-       if ((ap = ibuf_advance(ibuf, sizeof(*ap))) == NULL)
-               return (-1);
-
-       ap->ap_type = htons(type);
-       ap->ap_len = htons(sizeof(*ap));
-       ap->ap_ethertype = htons(ethertype);
-       return (0);
-}
-
-/* 
- * This action only pops the outermost VLAN tag and only one at a time,
- * you can only pop multiple VLANs with an action list that is only
- * availiable for OFP_INSTRUCTION_T_APPLY_ACTIONS.
- */
-int
-action_pop_vlan(struct ibuf *ibuf)
-{
-       return (action_new(ibuf, OFP_ACTION_POP_VLAN));
-}
-
-/*
- * Use this with caution since this will pop MPLS shim regardless of the
- * BoS bit state.
- */
-int
-action_pop_mpls(struct ibuf *ibuf, uint16_t ethertype)
-{
-       struct ofp_action_pop_mpls      *apm;
-
-       if ((apm = ibuf_advance(ibuf, sizeof(*apm))) == NULL)
-               return (-1);
-
-       apm->apm_type = htons(OFP_ACTION_POP_MPLS);
-       apm->apm_len = htons(sizeof(*apm));
-       apm->apm_ethertype = htons(ethertype);
-       return (0);
-}
-
-int
-action_copyttlout(struct ibuf *ibuf)
-{
-       return (action_new(ibuf, OFP_ACTION_COPY_TTL_OUT));
-}
-
-int
-action_copyttlin(struct ibuf *ibuf)
-{
-       return (action_new(ibuf, OFP_ACTION_COPY_TTL_IN));
-}
-
-int
-action_decnwttl(struct ibuf *ibuf)
-{
-       return (action_new(ibuf, OFP_ACTION_DEC_NW_TTL));
-}
-
-/*
- * This function should be used with the oxm_*() family.
- *
- * After filling the action_setfield() with oxms you have to set the
- * asf_len with htons(size_of_oxms).
- */
-struct ofp_action_set_field *
-action_setfield(struct ibuf *ibuf)
-{
-       struct ofp_action_set_field     *asf;
-
-       if ((asf = ibuf_advance(ibuf, sizeof(*asf))) == NULL)
-               return (NULL);
-
-       asf->asf_type = htons(OFP_ACTION_SET_FIELD);
-       return (asf);
-}
-
-struct ofp_ox_match *
-oxm_get(struct ibuf *ibuf, uint16_t field, int hasmask, uint8_t len)
-{
-       struct ofp_ox_match     *oxm;
-       size_t                   oxmlen;
-
-       /*
-        * When the mask is used we must always reserve double the space,
-        * because the mask field is the same size of the value.
-        */
-       if (hasmask)
-               len = len * 2;
-
-       oxmlen = sizeof(*oxm) + len;
-       if ((oxm = ibuf_advance(ibuf, oxmlen)) == NULL)
-               return (NULL);
-
-       oxm->oxm_class = htons(OFP_OXM_C_OPENFLOW_BASIC);
-       oxm->oxm_length = len;
-       OFP_OXM_SET_FIELD(oxm, field);
-       if (hasmask)
-               OFP_OXM_SET_HASMASK(oxm);
-
-       return (oxm);
-}
-
-/*
- * OpenFlow port where the packet where received.
- * May be a physical port, a logical port or the reserved port OFPP_LOCAL.
- */
-int
-oxm_inport(struct ibuf *ibuf, uint32_t in_port)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IN_PORT, 0,
-           sizeof(in_port))) == NULL)
-               return (-1);
-
-       in_port = htonl(in_port);
-       memcpy(oxm->oxm_value, &in_port, sizeof(in_port));
-       return (0);
-}
-
-/*
- * Physical port on which the packet was received.
- * Requires: oxm_inport.
- */
-int
-oxm_inphyport(struct ibuf *ibuf, uint32_t in_phy_port)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IN_PHY_PORT, 0,
-           sizeof(in_phy_port))) == NULL)
-               return (-1);
-
-       in_phy_port = htonl(in_phy_port);
-       memcpy(oxm->oxm_value, &in_phy_port, sizeof(in_phy_port));
-       return (0);
-}
-
-/* Table metadata. */
-int
-oxm_metadata(struct ibuf *ibuf, int hasmask, uint64_t metadata, uint64_t mask)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_META, hasmask,
-           sizeof(metadata))) == NULL)
-               return (-1);
-
-       metadata = htobe64(metadata);
-       memcpy(oxm->oxm_value, &metadata, sizeof(metadata));
-       if (hasmask) {
-               mask = htobe64(mask);
-               memcpy(oxm->oxm_value + sizeof(metadata), &mask, sizeof(mask));
-       }
-
-       return (0);
-}
-
-int
-oxm_etheraddr(struct ibuf *ibuf, int issrc, uint8_t *addr, uint8_t *mask)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-       int                      hasmask = (mask != NULL);
-
-       type = issrc ? OFP_XM_T_ETH_SRC : OFP_XM_T_ETH_DST;
-       if ((oxm = oxm_get(ibuf, type, hasmask, ETHER_ADDR_LEN)) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, addr, ETHER_ADDR_LEN);
-       if (hasmask)
-               memcpy(oxm->oxm_value + ETHER_ADDR_LEN, mask, ETHER_ADDR_LEN);
-
-       return (0);
-}
-
-int
-oxm_ethertype(struct ibuf *ibuf, uint16_t type)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ETH_TYPE, 0, sizeof(type))) == NULL)
-               return (-1);
-
-       type = htons(type);
-       memcpy(oxm->oxm_value, &type, sizeof(type));
-       return (0);
-}
-
-int
-oxm_vlanvid(struct ibuf *ibuf, int hasmask, uint16_t vid, uint16_t mask)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_VLAN_VID, hasmask,
-           sizeof(vid))) == NULL)
-               return (-1);
-
-       /* VID uses only the 13 least significant bits. */
-       vid &= 0x1fff;
-       vid = htons(vid);
-       memcpy(oxm->oxm_value, &vid, sizeof(vid));
-       if (hasmask) {
-               mask &= 0x1fff;
-               mask = htons(mask);
-               memcpy(oxm->oxm_value + sizeof(vid), &mask, sizeof(mask));
-       }
-
-       return (0);
-}
-
-/*
- * 802.1Q Prio from the outermost tag.
- *
- * Requires: oxm_vlanvid.
- */
-int
-oxm_vlanpcp(struct ibuf *ibuf, uint8_t pcp)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_VLAN_PCP, 0, sizeof(pcp))) == NULL)
-               return (-1);
-
-       /* PCP only uses the lower 3 bits. */
-       pcp &= 0x07;
-       memcpy(oxm->oxm_value, &pcp, sizeof(pcp));
-       return (0);
-}
-
-/*
- * The Diff Serv Code Point (DSCP) bits avaliable in IPv4 ToS field or
- * IPv6 Traffic Class field.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipdscp(struct ibuf *ibuf, uint8_t dscp)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IP_DSCP, 0, sizeof(dscp))) == NULL)
-               return (-1);
-
-       /* Only the 6 lower bits have meaning. */
-       dscp &= 0x3F;
-       memcpy(oxm->oxm_value, &dscp, sizeof(dscp));
-       return (0);
-}
-
-/*
- * The ECN (Explicit Congestion Notification) bits of IP headers.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipecn(struct ibuf *ibuf, uint8_t ecn)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IP_ECN, 0, sizeof(ecn))) == NULL)
-               return (-1);
-
-       /* Only the 2 most significant bits have meaning. */
-       ecn &= 0x03;
-       memcpy(oxm->oxm_value, &ecn, sizeof(ecn));
-       return (0);
-}
-
-/*
- * The IP protocol byte.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipproto(struct ibuf *ibuf, uint8_t proto)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IP_PROTO, 0, sizeof(proto))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, &proto, sizeof(proto));
-       return (0);
-}
-
-/*
- * The IPv4 address source/destination.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP).
- */
-int
-oxm_ipaddr(struct ibuf *ibuf, int issrc, int hasmask, uint32_t addr,
-    uint32_t mask)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_IPV4_SRC : OFP_XM_T_IPV4_DST;
-       if ((oxm = oxm_get(ibuf, type, hasmask, sizeof(addr))) == NULL)
-               return (-1);
-
-       addr = htonl(addr);
-       memcpy(oxm->oxm_value, &addr, sizeof(addr));
-       if (hasmask) {
-               mask = htonl(mask);
-               memcpy(oxm->oxm_value + sizeof(addr), &mask, sizeof(mask));
-       }
-
-       return (0);
-}
-
-/*
- * The TCP source/destination port.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6)
- * and oxm_ipproto(IPPROTO_TCP).
- */
-int
-oxm_tcpport(struct ibuf *ibuf, int issrc, uint16_t port)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_TCP_SRC : OFP_XM_T_TCP_DST;
-       if ((oxm = oxm_get(ibuf, type, 0, sizeof(port))) == NULL)
-               return (-1);
-
-       port = htons(port);
-       memcpy(oxm->oxm_value, &port, sizeof(port));
-       return (0);
-}
-
-/*
- * The UDP source/destination port.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6)
- * and oxm_ipproto(IPPROTO_UDP).
- */
-int
-oxm_udpport(struct ibuf *ibuf, int issrc, uint16_t port)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_UDP_SRC : OFP_XM_T_UDP_DST;
-       if ((oxm = oxm_get(ibuf, type, 0, sizeof(port))) == NULL)
-               return (-1);
-
-       port = htons(port);
-       memcpy(oxm->oxm_value, &port, sizeof(port));
-       return (0);
-}
-
-/*
- * The SCTP source/destination port.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IP) or oxm_ethertype(ETHERTYPE_IPV6)
- * and oxm_ipproto(IPPROTO_??? -- 132).
- */
-int
-oxm_sctpport(struct ibuf *ibuf, int issrc, uint16_t port)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_SCTP_SRC : OFP_XM_T_SCTP_DST;
-       if ((oxm = oxm_get(ibuf, type, 0, sizeof(port))) == NULL)
-               return (-1);
-
-       port = htons(port);
-       memcpy(oxm->oxm_value, &port, sizeof(port));
-       return (0);
-}
-
-/*
- * The ICMPv4 type in the ICMP header.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP) and oxm_ipproto(IPPROTO_ICMP).
- */
-int
-oxm_icmpv4type(struct ibuf *ibuf, uint8_t type)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ICMPV4_TYPE, 0,
-           sizeof(type))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, &type, sizeof(type));
-       return (0);
-}
-
-/*
- * The ICMPv4 code in the ICMP header.
- *
- * Requires: oxm_ethertype(ETHERTYPE_IP) and oxm_ipproto(IPPROTO_ICMP).
- */
-int
-oxm_icmpv4code(struct ibuf *ibuf, uint8_t code)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ICMPV4_CODE, 0,
-           sizeof(code))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, &code, sizeof(code));
-       return (0);
-}
-
-/*
- * ARP opcode.
- *
- * Requires: oxm_ethertype(ETHERTYPE_ARP).
- */
-int
-oxm_arpop(struct ibuf *ibuf, uint16_t op)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ARP_OP, 0, sizeof(op))) == NULL)
-               return (-1);
-
-       op = htons(op);
-       memcpy(oxm->oxm_value, &op, sizeof(op));
-       return (0);
-}
-
-/*
- * ARP source/target protocol address.
- *
- * Requires: oxm_ethertype(ETHERTYPE_ARP).
- */
-int
-oxm_arpaddr(struct ibuf *ibuf, int issrc, int hasmask, uint32_t addr,
-    uint32_t mask)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_ARP_SPA : OFP_XM_T_ARP_TPA;
-       if ((oxm = oxm_get(ibuf, type, hasmask, sizeof(addr))) == NULL)
-               return (-1);
-
-       addr = htonl(addr);
-       memcpy(oxm->oxm_value, &addr, sizeof(addr));
-       if (hasmask) {
-               mask = htonl(mask);
-               memcpy(oxm->oxm_value + sizeof(addr), &mask, sizeof(mask));
-       }
-
-       return (0);
-}
-
-/*
- * ARP source/target hardware address.
- *
- * Requires: oxm_ethertype(ETHERTYPE_ARP).
- */
-int
-oxm_arphaddr(struct ibuf *ibuf, int issrc, uint8_t *addr, uint8_t *mask)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-       int                      hasmask = (mask != NULL);
-
-       type = issrc ? OFP_XM_T_ARP_SHA : OFP_XM_T_ARP_THA;
-       if ((oxm = oxm_get(ibuf, type, hasmask, ETHER_ADDR_LEN)) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, addr, ETHER_ADDR_LEN);
-       if (hasmask)
-               memcpy(oxm->oxm_value + ETHER_ADDR_LEN, mask, ETHER_ADDR_LEN);
-
-       return (0);
-}
-
-/*
- * The source or destination of the IPv6 address.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipv6addr(struct ibuf *ibuf, int issrc, struct in6_addr *addr,
-    struct in6_addr *mask)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-       int                      hasmask = (mask != NULL);
-
-       type = issrc ? OFP_XM_T_IPV6_SRC : OFP_XM_T_IPV6_DST;
-       if ((oxm = oxm_get(ibuf, type, hasmask, sizeof(*addr))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, addr, sizeof(*addr));
-       if (hasmask)
-               memcpy(oxm->oxm_value + sizeof(*addr), mask, sizeof(*mask));
-
-       return (0);
-}
-
-/*
- * The IPv6 flow label field.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipv6flowlabel(struct ibuf *ibuf, int hasmask, uint32_t flowlabel,
-    uint32_t mask)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IPV6_FLABEL, hasmask,
-           sizeof(flowlabel))) == NULL)
-               return (-1);
-
-       /*
-         * 12 most significants bits forced to 0 and only the 20 lowers
-         * bits have meaning.
-        */
-       flowlabel &= 0x000FFFFFU;
-       flowlabel = htonl(flowlabel);
-       memcpy(oxm->oxm_value, &flowlabel, sizeof(flowlabel));
-       if (hasmask) {
-               mask &= 0x000FFFFFU;
-               mask = htonl(mask);
-               memcpy(oxm->oxm_value + sizeof(flowlabel), &mask, sizeof(mask));
-       }
-
-       return (0);
-}
-
-/*
- * The ICMPv6 type in ICMP header.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6) and oxm_ipproto(IPPROTO_ICMPV6).
- */
-int
-oxm_icmpv6type(struct ibuf *ibuf, uint8_t type)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ICMPV6_TYPE, 0,
-           sizeof(type))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, &type, sizeof(type));
-       return (0);
-}
-
-/*
- * The ICMPv6 code in ICMP header.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6) and oxm_ipproto(IPPROTO_ICMPV6).
- */
-int
-oxm_icmpv6code(struct ibuf *ibuf, uint8_t code)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_ICMPV6_CODE, 0,
-           sizeof(code))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, &code, sizeof(code));
-       return (0);
-}
-
-/*
- * The target address in neighbour discovery message.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6), oxm_ipproto(IPPROTO_ICMPV6)
- * and oxm_icmpv6type(ND_NEIGHBOR_SOLICIT) or
- * oxm_icmpv6type(ND_NEIGHBOR_ADVERT).
- */
-int
-oxm_ipv6ndtarget(struct ibuf *ibuf, struct in6_addr *addr)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IPV6_ND_TARGET, 0,
-           sizeof(*addr))) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, addr, sizeof(*addr));
-       return (0);
-}
-
-/*
- * The source link-layer address in an IPv6 Neighbour discovery.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6), oxm_ipproto(IPPROTO_ICMPV6)
- * and oxm_icmpv6type(ND_NEIGHBOR_SOLICIT).
- */
-int
-oxm_ipv6ndlinkaddr(struct ibuf *ibuf, int issrc, uint8_t *addr)
-{
-       struct ofp_ox_match     *oxm;
-       int                      type;
-
-       type = issrc ? OFP_XM_T_IPV6_ND_SLL : OFP_XM_T_IPV6_ND_TLL;
-       if ((oxm = oxm_get(ibuf, type, 0, ETHER_ADDR_LEN)) == NULL)
-               return (-1);
-
-       memcpy(oxm->oxm_value, addr, ETHER_ADDR_LEN);
-       return (0);
-}
-
-/*
- * The label in the MPLS shim.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_MPLS) or
- * oxm_ethertype(ETHERTYPE_MPLS_MCAST).
- */
-int
-oxm_mplslabel(struct ibuf *ibuf, uint32_t label)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_MPLS_LABEL, 0,
-           sizeof(label))) == NULL)
-               return (-1);
-
-       label &= MPLS_LABEL_MASK;
-       label = htonl(label);
-       memcpy(oxm->oxm_value, &label, sizeof(label));
-       return (0);
-}
-
-/*
- * The TC in the first MPLS shim.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_MPLS) or
- * oxm_ethertype(ETHERTYPE_MPLS_MCAST).
- */
-int
-oxm_mplstc(struct ibuf *ibuf, uint8_t tc)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_MPLS_TC, 0, sizeof(tc))) == NULL)
-               return (-1);
-
-       tc &= 0x07;
-       memcpy(oxm->oxm_value, &tc, sizeof(tc));
-       return (0);
-}
-
-/*
- * The BoS bit in the first MPLS shim.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_MPLS) or
- * oxm_ethertype(ETHERTYPE_MPLS_MCAST).
- */
-int
-oxm_mplsbos(struct ibuf *ibuf, uint8_t bos)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_MPLS_BOS, 0, sizeof(bos))) == NULL)
-               return (-1);
-
-       bos &= 0x01;
-       memcpy(oxm->oxm_value, &bos, sizeof(bos));
-       return (0);
-}
-
-/*
- * Comment shamelessly taken from OpenFlow 1.3.5 specification.
- *
- * Metadata associated with a logical port.
- *
- * If the logical port performs encapsulation and decapsulation, this
- * is the demultiplexing field from the encapsulation header.
- * For example, for a packet received via GRE tunnel including a (32-bit) key,
- * the key is stored in the low 32-bits and the high bits are zeroed.
- * For a MPLS logical port, the low 20 bits represent the MPLS Label.
- * For a VxLAN logical port, the low 24 bits represent the VNI.
- * If the packet is not received through a logical port, the value is 0.
- */
-int
-oxm_tunnelid(struct ibuf *ibuf, int hasmask, uint64_t id, uint64_t mask)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_TUNNEL_ID, hasmask,
-           sizeof(id))) == NULL)
-               return (-1);
-
-       id = htobe64(id);
-       memcpy(oxm->oxm_value, &id, sizeof(id));
-       if (hasmask) {
-               mask = htobe64(mask);
-               memcpy(oxm->oxm_value + sizeof(id), &mask, sizeof(mask));
-       }
-       return (0);
-}
-
-/*
- * The IPv6 extension header.
- *
- * Tip: use the OFP_XM_IPV6_EXTHDR_* macros.
- *
- * Requirements: oxm_ethertype(ETHERTYPE_IPV6).
- */
-int
-oxm_ipv6exthdr(struct ibuf *ibuf, int hasmask, uint16_t exthdr, uint16_t mask)
-{
-       struct ofp_ox_match     *oxm;
-
-       if ((oxm = oxm_get(ibuf, OFP_XM_T_IPV6_EXTHDR, hasmask,
-           sizeof(exthdr))) == NULL)
-               return (-1);
-
-       /* Only the lower 9 bits have meaning. */
-       exthdr &= 0x01FF;
-       exthdr = htons(exthdr);
-       memcpy(oxm->oxm_value, &exthdr, sizeof(exthdr));
-       if (hasmask) {
-               mask &= 0x01FF;
-               mask = htons(mask);
-               memcpy(oxm->oxm_value + sizeof(exthdr), &mask, sizeof(mask));
-       }
-       return (0);
-}
-
-/*
- * Appends a new instruction with hlen size.
- *
- * Remember to set the instruction length (i->i_len) if it has more data,
- * like ofp_instruction_actions, ofp_instruction_goto_table etc...
- */
-struct ofp_instruction *
-ofp_instruction(struct ibuf *ibuf, uint16_t type, uint16_t hlen)
-{
-       struct ofp_instruction  *oi;
-
-       if ((oi = ibuf_advance(ibuf, hlen)) == NULL)
-               return (NULL);
-
-       oi->i_type = htons(type);
-       oi->i_len = htons(hlen);
-       return (oi);
-}
-
-struct multipart_message *
-ofp_multipart_lookup(struct switch_connection *con, uint32_t xid)
-{
-       struct multipart_message        *mm;
-
-       SLIST_FOREACH(mm, &con->con_mmlist, mm_entry) {
-               if (mm->mm_xid != xid)
-                       continue;
-
-               return (mm);
-       }
-
-       return (NULL);
-}
-
-int
-ofp_multipart_add(struct switch_connection *con, uint32_t xid, uint8_t type)
-{
-       struct multipart_message        *mm;
-
-       if ((mm = ofp_multipart_lookup(con, xid)) != NULL) {
-               /*
-                * A multipart reply has the same xid and type, otherwise
-                * something went wrong.
-                */
-               if (mm->mm_type != type)
-                       return (-1);
-
-               return (0);
-       }
-
-       if ((mm = calloc(1, sizeof(*mm))) == NULL)
-               return (-1);
-
-       mm->mm_xid = xid;
-       mm->mm_type = type;
-       SLIST_INSERT_HEAD(&con->con_mmlist, mm, mm_entry);
-       return (0);
-}
-
-void
-ofp_multipart_del(struct switch_connection *con, uint32_t xid)
-{
-       struct multipart_message        *mm;
-
-       SLIST_FOREACH(mm, &con->con_mmlist, mm_entry)
-               if (mm->mm_xid == xid)
-                       break;
-
-       if (mm == NULL)
-               return;
-
-       ofp_multipart_free(con, mm);
-}
-
-void
-ofp_multipart_free(struct switch_connection *con,
-    struct multipart_message *mm)
-{
-       SLIST_REMOVE(&con->con_mmlist, mm, multipart_message, mm_entry);
-       free(mm);
-}
-
-void
-ofp_multipart_clear(struct switch_connection *con)
-{
-       struct multipart_message        *mm;
-
-       while (!SLIST_EMPTY(&con->con_mmlist)) {
-               mm = SLIST_FIRST(&con->con_mmlist);
-               ofp_multipart_free(con, mm);
-       }
-}
-
-struct switch_table *
-switch_tablelookup(struct switch_connection *con, int table)
-{
-       struct switch_table             *st;
-
-       TAILQ_FOREACH(st, &con->con_stlist, st_entry) {
-               if (st->st_table == table)
-                       return (st);
-       }
-
-       return (NULL);
-}
-
-struct switch_table *
-switch_newtable(struct switch_connection *con, int table)
-{
-       struct switch_table             *st;
-
-       if ((st = calloc(1, sizeof(*st))) == NULL)
-               return (NULL);
-
-       st->st_table = table;
-       TAILQ_INSERT_TAIL(&con->con_stlist, st, st_entry);
-
-       return (st);
-}
-
-void
-switch_deltable(struct switch_connection *con, struct switch_table *st)
-{
-       TAILQ_REMOVE(&con->con_stlist, st, st_entry);
-       free(st);
-}
-
-void
-switch_freetables(struct switch_connection *con)
-{
-       struct switch_table             *st;
-
-       while (!TAILQ_EMPTY(&con->con_stlist)) {
-               st = TAILQ_FIRST(&con->con_stlist);
-               switch_deltable(con, st);
-       }
-}
-
-int
-oflowmod_state(struct oflowmod_ctx *ctx, unsigned int old, unsigned int new)
-{
-       if (ctx->ctx_state != old)
-               return (-1);
-       ctx->ctx_state = new;
-       return (0);
-}
-
-int
-oflowmod_err(struct oflowmod_ctx *ctx, const char *func, int line)
-{
-       log_debug("%s: function %s line %d state %d",
-           __func__, func, line, ctx->ctx_state);
-
-       if (ctx->ctx_state >= OFMCTX_ERR)
-               return (-1);
-       if (ctx->ctx_flags & OFMCTX_IBUF)
-               ibuf_release(ctx->ctx_ibuf);
-       ctx->ctx_state = OFMCTX_ERR;
-       return (-1);
-}
-
-struct ibuf *
-oflowmod_open(struct oflowmod_ctx *ctx, struct switch_connection *con,
-    struct ibuf *ibuf, uint8_t version)
-{
-       struct ofp_flow_mod     *fm;
-       struct switch_connection conb;
-
-       switch (version) {
-       case OFP_V_0:
-       case OFP_V_1_3:
-               version = OFP_V_1_3;
-               break;
-       default:
-               log_warnx("%s: unsupported version 0x%02x", __func__, version);
-               return (NULL);
-       }
-
-       memset(ctx, 0, sizeof(*ctx));
-
-       if (oflowmod_state(ctx, OFMCTX_INIT, OFMCTX_OPEN) == -1)
-               goto err;
-
-       if (ibuf == NULL) {
-               ctx->ctx_flags |= OFMCTX_IBUF;
-               if ((ibuf = ibuf_static()) == NULL)
-                       goto err;
-       }
-
-       ctx->ctx_ibuf = ibuf;
-       ctx->ctx_start = ibuf->wpos;
-
-       /*
-        * The connection is not strictly required and might not be
-        * available in other places;  just default to an xid 0.
-        */
-       if (con == NULL) {
-               con = &conb;
-               memset(con, 0, sizeof(*con));
-       }
-
-       /* uses defaults, can be changed by accessing fm later */
-       if ((fm = ofp13_flowmod(con, ibuf, OFP_FLOWCMD_ADD)) == NULL)
-               goto err;
-
-       ctx->ctx_fm = fm;
-
-       return (ctx->ctx_ibuf);
-
- err:
-       (void)oflowmod_err(ctx, __func__, __LINE__);
-       return (NULL);
-}
-
-int
-oflowmod_mopen(struct oflowmod_ctx *ctx)
-{
-       if (oflowmod_state(ctx, OFMCTX_OPEN, OFMCTX_MOPEN) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       ctx->ctx_ostart = ctx->ctx_start +
-           offsetof(struct ofp_flow_mod, fm_match);
-
-       return (0);
-}
-
-int
-oflowmod_mclose(struct oflowmod_ctx *ctx)
-{
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-       struct ofp_flow_mod     *fm = ctx->ctx_fm;
-       size_t                   omlen, padding;
-
-       if (oflowmod_state(ctx, OFMCTX_MOPEN, OFMCTX_MCLOSE) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       ctx->ctx_oend = ibuf->wpos;
-       omlen = ctx->ctx_oend - ctx->ctx_ostart;
-
-       /* Update match length */
-       fm->fm_match.om_length = htons(omlen);
-
-       padding = OFP_ALIGN(omlen) - omlen;
-       if (padding) {
-               ctx->ctx_oend += padding;
-               if (ibuf_advance(ibuf, padding) == NULL)
-                       return (oflowmod_err(ctx, __func__, __LINE__));
-       }
-
-       return (0);
-}
-
-int
-oflowmod_iopen(struct oflowmod_ctx *ctx)
-{
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-
-       if (ctx->ctx_state < OFMCTX_MOPEN &&
-           (oflowmod_mopen(ctx) == -1))
-               return (oflowmod_err(ctx, __func__, __LINE__));
-       if (ctx->ctx_state < OFMCTX_MCLOSE &&
-           (oflowmod_mclose(ctx) == -1))
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       if (oflowmod_state(ctx, OFMCTX_MCLOSE, OFMCTX_IOPEN) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       ctx->ctx_istart = ibuf->wpos;
-
-       return (0);
-}
-
-int
-oflowmod_instruction(struct oflowmod_ctx *ctx, unsigned int type)
-{
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-       struct ofp_instruction  *oi;
-       size_t                   len;
-
-       if (ctx->ctx_state < OFMCTX_IOPEN &&
-           (oflowmod_iopen(ctx) == -1))
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       if (oflowmod_state(ctx, OFMCTX_IOPEN, OFMCTX_IOPEN) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       if (ctx->ctx_oi != NULL && oflowmod_instructionclose(ctx) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       ctx->ctx_oioff = ibuf->wpos;
-
-       switch (type) {
-       case OFP_INSTRUCTION_T_GOTO_TABLE:
-               len = sizeof(struct ofp_instruction_goto_table);
-               break;
-       case OFP_INSTRUCTION_T_WRITE_META:
-               len = sizeof(struct ofp_instruction_write_metadata);
-               break;
-       case OFP_INSTRUCTION_T_WRITE_ACTIONS:
-       case OFP_INSTRUCTION_T_APPLY_ACTIONS:
-       case OFP_INSTRUCTION_T_CLEAR_ACTIONS:
-               len = sizeof(struct ofp_instruction_actions);
-               break;
-       case OFP_INSTRUCTION_T_METER:
-               len = sizeof(struct ofp_instruction_meter);
-               break;
-       case OFP_INSTRUCTION_T_EXPERIMENTER:
-               len = sizeof(struct ofp_instruction_experimenter);
-               break;
-       default:
-               return (oflowmod_err(ctx, __func__, __LINE__));
-       }
-
-       if ((oi = ofp_instruction(ibuf, type, len)) == NULL)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       ctx->ctx_oi = oi;
-
-       return (0);
-}
-
-int
-oflowmod_instructionclose(struct oflowmod_ctx *ctx)
-{
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-       struct ofp_instruction  *oi = ctx->ctx_oi;
-       size_t                   oilen;
-
-       if (ctx->ctx_state < OFMCTX_IOPEN || oi == NULL)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       oilen = ibuf->wpos - ctx->ctx_oioff;
-
-       if (oilen > UINT16_MAX)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       oi->i_len = htons(oilen);
-       ctx->ctx_oi = NULL;
-
-       return (0);
-}
-
-int
-oflowmod_iclose(struct oflowmod_ctx *ctx)
-{
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-
-       if (oflowmod_state(ctx, OFMCTX_IOPEN, OFMCTX_ICLOSE) == -1)
-               return (oflowmod_err(ctx, __func__, __LINE__));
-
-       if (ctx->ctx_oi != NULL && oflowmod_instructionclose(ctx) == -1)
-               return (-1);
-
-       ctx->ctx_iend = ibuf->wpos;
-
-       return (0);
-}
-
-int
-oflowmod_close(struct oflowmod_ctx *ctx)
-{
-       struct ofp_flow_mod     *fm = ctx->ctx_fm;
-       struct ibuf             *ibuf = ctx->ctx_ibuf;
-       size_t                   len;
-
-       /* No matches, calculate default */
-       if (ctx->ctx_state < OFMCTX_MOPEN &&
-           (oflowmod_mopen(ctx) == -1 ||
-           oflowmod_mclose(ctx) == -1))
-               goto err;
-
-       /* No instructions, calculate default */
-       if (ctx->ctx_state < OFMCTX_IOPEN &&
-           (oflowmod_iopen(ctx) == -1 ||
-           oflowmod_iclose(ctx) == -1))
-               goto err;
-
-       if (oflowmod_state(ctx, OFMCTX_ICLOSE, OFMCTX_CLOSE) == -1)
-               goto err;
-
-       /* Update length */
-       len = ibuf->wpos - ctx->ctx_start;
-       fm->fm_oh.oh_length = htons(len);
-
-       return (0);
-
- err:
-       return (oflowmod_err(ctx, __func__, __LINE__));
-
-}
diff --git a/usr.sbin/switchd/ofp_map.h b/usr.sbin/switchd/ofp_map.h
deleted file mode 100644 (file)
index 3519ed1..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*     $OpenBSD: ofp_map.h,v 1.9 2016/11/18 16:56:09 reyk Exp $        */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef OFP_MAP_H
-#define OFP_MAP_H
-
-struct constmap {
-       unsigned int     cm_type;
-       const char      *cm_name;
-       const char      *cm_descr;
-};
-
-/*
- * Each map is generated from lists of #define's in ofp.h, using the format:
- * #define OFP_{MAPNAME}_FLAG  {value}         / * COMMENT * /
- *
- * Please make sure that the flags in ofp.h match this style (incl. comment)
- */
-
-/* OpenFlow 1.0 maps */
-extern struct constmap ofp10_t_map[];
-extern struct constmap ofp10_port_map[];
-extern struct constmap ofp10_action_map[];
-extern struct constmap ofp10_wildcard_map[];
-extern struct constmap ofp10_errtype_map[];
-extern struct constmap ofp10_errflowmod_map[];
-
-/* OpenFlow 1.3+ maps */
-extern struct constmap ofp_v_map[];
-extern struct constmap ofp_t_map[];
-extern struct constmap ofp_pktin_map[];
-extern struct constmap ofp_port_map[];
-extern struct constmap ofp_pktout_map[];
-extern struct constmap ofp_oxm_c_map[];
-extern struct constmap ofp_xm_t_map[];
-extern struct constmap ofp_config_map[];
-extern struct constmap ofp_controller_maxlen_map[];
-extern struct constmap ofp_instruction_t_map[];
-extern struct constmap ofp_portstate_map[];
-extern struct constmap ofp_portconfig_map[];
-extern struct constmap ofp_portmedia_map[];
-extern struct constmap ofp_pktin_reason_map[];
-extern struct constmap ofp_swcap_map[];
-extern struct constmap ofp_table_id_map[];
-extern struct constmap ofp_match_map[];
-extern struct constmap ofp_mp_t_map[];
-extern struct constmap ofp_action_map[];
-extern struct constmap ofp_flowcmd_map[];
-extern struct constmap ofp_flowflag_map[];
-extern struct constmap ofp_flowrem_reason_map[];
-extern struct constmap ofp_group_id_map[];
-extern struct constmap ofp_errtype_map[];
-extern struct constmap ofp_errflowmod_map[];
-extern struct constmap ofp_errmatch_map[];
-extern struct constmap ofp_errinst_map[];
-extern struct constmap ofp_errreq_map[];
-extern struct constmap ofp_table_featprop_map[];
-
-#endif /* OFP_MAP_H */
diff --git a/usr.sbin/switchd/ofrelay.c b/usr.sbin/switchd/ofrelay.c
deleted file mode 100644 (file)
index 653882c..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/*     $OpenBSD: ofrelay.c,v 1.10 2016/12/22 15:31:43 rzalamena Exp $  */
-
-/*
- * Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/queue.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <errno.h>
-#include <event.h>
-
-#include "switchd.h"
-
-void    ofrelay_close(struct switch_connection *);
-void    ofrelay_event(int, short, void *);
-int     ofrelay_input(int, short, void *);
-int     ofrelay_output(int, short, void *);
-void    ofrelay_accept(int, short, void *);
-void    ofrelay_inflight_dec(struct switch_connection *, const char *);
-
-void   *ofrelay_input_open(struct switch_connection *,
-           struct ibuf *, ssize_t *);
-ssize_t         ofrelay_input_close(struct switch_connection *,
-           struct ibuf *, ssize_t);
-int     ofrelay_input_done(struct switch_connection *, struct ibuf *);
-int     ofrelay_bufget(struct switch_connection *, struct ibuf *);
-void    ofrelay_bufput(struct switch_connection *, struct ibuf *);
-
-volatile int    ofrelay_sessions;
-volatile int    ofrelay_inflight;
-static uint32_t         ofrelay_conid;
-
-void
-ofrelay(struct privsep *ps, struct privsep_proc *p)
-{
-       struct switchd          *sc = ps->ps_env;
-       struct switch_server    *srv = &sc->sc_server;
-
-       log_info("listen on %s", print_host(&srv->srv_addr, NULL, 0));
-
-       if ((srv->srv_fd = switchd_listen((struct sockaddr *)
-           &srv->srv_addr)) == -1)
-               fatal("listen");
-}
-
-void
-ofrelay_run(struct privsep *ps, struct privsep_proc *p, void *arg)
-{
-       struct switchd          *sc = ps->ps_env;
-       struct switch_server    *srv = &sc->sc_server;
-
-       TAILQ_INIT(&sc->sc_conns);
-       TAILQ_INIT(&sc->sc_clients);
-
-       srv->srv_sc = sc;
-       event_set(&srv->srv_ev, srv->srv_fd, EV_READ, ofrelay_accept, srv);
-       event_add(&srv->srv_ev, NULL);
-       evtimer_set(&srv->srv_evt, ofrelay_accept, srv);
-}
-
-void
-ofrelay_close(struct switch_connection *con)
-{
-       struct switchd          *sc = con->con_sc;
-       struct switch_server    *srv = con->con_srv;
-
-       log_info("%s: connection %u.%u closed", __func__,
-           con->con_id, con->con_instance);
-
-       if (event_initialized(&con->con_ev))
-               event_del(&con->con_ev);
-
-       TAILQ_REMOVE(&sc->sc_conns, con, con_entry);
-       ofrelay_sessions--;
-
-       switch_freetables(con);
-       ofp_multipart_clear(con);
-       switch_remove(con->con_sc, con->con_switch);
-       msgbuf_clear(&con->con_wbuf);
-       ibuf_release(con->con_rbuf);
-       close(con->con_fd);
-
-       ofrelay_inflight_dec(con, __func__);
-
-       /* Some file descriptors are available again. */
-       if (evtimer_pending(&srv->srv_evt, NULL)) {
-               DPRINTF("%s: accepting again", __func__);
-               evtimer_del(&srv->srv_evt);
-               event_add(&srv->srv_ev, NULL);
-       }
-
-       free(con);
-}
-
-void
-ofrelay_event(int fd, short event, void *arg)
-{
-       struct switch_connection        *con = arg;
-       const char                      *error = NULL;
-
-       event_add(&con->con_ev, NULL);
-       if (event & EV_TIMEOUT) {
-               error = "timeout";
-               goto fail;
-       }
-       if (event & EV_WRITE) {
-               if (ofrelay_output(fd, event, arg) == -1) {
-                       error = "write";
-                       goto fail;
-               }
-       }
-       if (event & EV_READ) {
-               if (ofrelay_input(fd, event, arg) == -1) {
-                       error = "input";
-                       goto fail;
-               }
-       }
-
- fail:
-       if (error != NULL) {
-               DPRINTF("%s: %s error", __func__, error);
-               ofrelay_close(con);
-       }
-}
-
-int
-ofrelay_input(int fd, short event, void *arg)
-{
-       struct switch_connection        *con = arg;
-       struct ibuf             *ibuf = con->con_rbuf;
-       ssize_t                  len, rlen;
-       size_t                   hlen;
-       void                    *buf;
-       struct ofp_header       *oh = NULL;
-
-       if ((buf = ofrelay_input_open(con, ibuf, &len)) == NULL) {
-               log_warn("%s: fd %d, failed to get buffer", __func__, fd);
-               return (-1);
-       }
-
-       /* If we got a new buffer, read the complete openflow header first */
-       if ((hlen = ibuf_length(ibuf)) < sizeof(struct ofp_header)) {
-               oh = (struct ofp_header *)ibuf_data(ibuf);
-               len = sizeof(*oh) - hlen;
-       }
-
-       if ((rlen = read(fd, buf, len)) == -1) {
-               if (errno == EINTR || errno == EAGAIN)
-                       return (0);
-               log_warn("%s: fd %d, failed to read", __func__, fd);
-               return (-1);
-       }
-
-       print_hex(buf, 0, rlen);
-
-       DPRINTF("%s: connection %u.%u read %zd bytes", __func__,
-           con->con_id, con->con_instance, rlen);
-
-       if ((len = ofrelay_input_close(con, ibuf, rlen)) == -1)
-               return (-1);
-       else if (rlen == 0) {
-               /* connection closed */
-               ofrelay_input_done(con, ibuf);
-               return (-1);
-       }
-
-       /* After we verified the openflow header, set the size accordingly */
-       if (oh != NULL && (hlen + rlen) == sizeof(*oh)) {
-               switch (oh->oh_version) {
-               case OFP_V_1_0:
-               case OFP_V_1_1:
-               case OFP_V_1_2:
-               case OFP_V_1_3:
-                       break;
-               default:
-                       DPRINTF("%s: fd %d, openflow version 0x%02x length %d"
-                           " not supported", __func__, fd, oh->oh_version,
-                           ntohs(oh->oh_length));
-                       return (-1);
-               }
-
-               len = ntohs(oh->oh_length);
-               if (len == sizeof(*oh)) {
-                       len = 0;
-               } else if (len > (ssize_t)ibuf->size) {
-                       log_debug("%s: buffer too big: %zu > %zd", __func__,
-                           len, ibuf->size);
-                       return (-1);
-               } else
-                       ibuf_setmax(ibuf, len);
-       }
-
-       if (len > 0)
-               return (len);
-
-       return (ofrelay_input_done(con, ibuf));
-}
-
-void
-ofrelay_write(struct switch_connection *con, struct ibuf *buf)
-{
-       ibuf_close(&con->con_wbuf, buf);
-
-       event_del(&con->con_ev);
-       event_set(&con->con_ev, con->con_fd, EV_READ|EV_WRITE,
-           ofrelay_event, con);
-       event_add(&con->con_ev, NULL);
-}
-
-void *
-ofrelay_input_open(struct switch_connection *con,
-    struct ibuf *buf, ssize_t *len)
-{
-       ssize_t  left;
-
-       left = buf->max - buf->wpos;
-       if (left == 0) {
-               ofrelay_bufget(con, buf);
-               left = buf->max;
-       }
-       if (len)
-               *len = left;
-
-       return (buf->buf + buf->wpos);
-}
-
-ssize_t
-ofrelay_input_close(struct switch_connection *con,
-    struct ibuf *buf, ssize_t len)
-{
-       if (len <= 0)
-               return (0);
-       if (buf->wpos + len > buf->max)
-               return (-1);
-       buf->wpos += len;
-
-       return (buf->max - buf->wpos);
-}
-
-int
-ofrelay_input_done(struct switch_connection *con, struct ibuf *buf)
-{
-       struct switch_control   *sw;
-
-       if (buf->wpos == 0) {
-               ofrelay_bufput(con, buf);
-               return (0);
-       }
-
-       sw = con->con_switch;
-       log_debug("%s: connection %u.%u: %ld bytes from switch %u", __func__,
-           con->con_id, con->con_instance, buf->wpos,
-           sw == NULL ? 0 : sw->sw_id);
-
-       print_hex(buf->buf, 0, buf->wpos);
-
-       if (ofp_input(con, buf) == -1)
-               return (-1);
-
-       /* Update read buffer */
-       if (ofrelay_bufget(con, buf) == -1)
-               return (-1);
-
-       return (0);
-}
-
-int
-ofrelay_bufget(struct switch_connection *con, struct ibuf *buf)
-{
-       ibuf_reset(buf);
-
-       /* Should be a static buffer with maximum size */
-       if (ibuf_setmax(buf, SWITCHD_MSGBUF_MAX) == -1)
-               fatalx("%s: invalid buffer", __func__);
-
-       return (0);
-}
-
-void
-ofrelay_bufput(struct switch_connection *con, struct ibuf *buf)
-{
-       /* Just reset the buffer */
-       ofrelay_bufget(con, buf);
-}
-
-int
-ofrelay_output(int fd, short event, void *arg)
-{
-       struct switch_connection        *con = arg;
-       struct msgbuf                   *wbuf = &con->con_wbuf;
-
-       if (!wbuf->queued) {
-               event_del(&con->con_ev);
-               event_set(&con->con_ev, con->con_fd, EV_READ,
-                   ofrelay_event, con);
-               event_add(&con->con_ev, NULL);
-               return (0);
-       }
-
-       if (ibuf_write(wbuf) <= 0 && errno != EAGAIN)
-               return (-1);
-
-       return (0);
-}
-
-void
-ofrelay_accept(int fd, short event, void *arg)
-{
-       struct switch_server    *srv = arg;
-       struct sockaddr_storage  ss;
-       int                      s;
-       socklen_t                slen;
-
-       event_add(&srv->srv_ev, NULL);
-       if (event & EV_TIMEOUT)
-               return;
-
-       slen = sizeof(ss);
-       if ((s = accept4_reserve(fd, (struct sockaddr *)&ss, &slen,
-           SOCK_NONBLOCK|SOCK_CLOEXEC, SWITCHD_FD_RESERVE,
-           &ofrelay_inflight)) == -1) {
-               /*
-                * Pause accept if we are out of file descriptors, or
-                * libevent will haunt us here too.
-                */
-               if (errno == ENFILE || errno == EMFILE) {
-                       struct timeval evtpause = { 1, 0 };
-
-                       event_del(&srv->srv_ev);
-                       evtimer_add(&srv->srv_evt, &evtpause);
-                       log_warn("%s: deferring connections", __func__);
-               } else
-                       log_warn("%s accept", __func__);
-               return;
-       }
-       ss.ss_len = slen;
-
-       (void)ofrelay_attach(srv, s, (struct sockaddr *)&ss);
-}
-
-void
-ofrelay_inflight_dec(struct switch_connection *con, const char *why)
-{
-       if (con != NULL) {
-               /* the flight already left inflight mode. */
-               if (con->con_inflight == 0)
-                       return;
-               con->con_inflight = 0;
-       }
-
-       /* the file was never opened, thus this was an inflight client. */
-       ofrelay_inflight--;
-       DPRINTF("%s: inflight decremented, now %d, %s",
-           __func__, ofrelay_inflight, why);
-}
-
-int
-ofrelay_attach(struct switch_server *srv, int s, struct sockaddr *sa)
-{
-       struct switchd                  *sc = srv->srv_sc;
-       struct privsep                  *ps = &sc->sc_ps;
-       struct switch_connection        *con = NULL;
-       socklen_t                        slen;
-       int                              ret = -1;
-
-       if (ofrelay_sessions >= SWITCHD_MAX_SESSIONS) {
-               log_warn("too many sessions");
-               goto done;
-       }
-
-       if ((con = calloc(1, sizeof(*con))) == NULL) {
-               log_warn("calloc");
-               goto done;
-       }
-
-       con->con_fd = s;
-       con->con_inflight = 1;
-       con->con_sc = sc;
-       con->con_id = ++ofrelay_conid;
-       con->con_instance = ps->ps_instance + 1;
-       con->con_srv = srv;
-       con->con_state = OFP_STATE_CLOSED;
-       SLIST_INIT(&con->con_mmlist);
-       TAILQ_INIT(&con->con_stlist);
-
-       memcpy(&con->con_peer, sa, sa->sa_len);
-       con->con_port = htons(socket_getport(&con->con_peer));
-
-       if (getsockname(s, (struct sockaddr *)&con->con_local, &slen) == -1) {
-               /* Set local sockaddr to AF_UNSPEC */
-               memset(&con->con_local, 0, sizeof(con->con_local));
-       }
-
-       log_info("%s: new connection %u.%u",
-           __func__, con->con_id, con->con_instance);
-
-       ofrelay_sessions++;
-       TAILQ_INSERT_TAIL(&sc->sc_conns, con, con_entry);
-
-       if ((con->con_rbuf = ibuf_static()) == NULL ||
-           ofrelay_bufget(con, con->con_rbuf) == -1) {
-               log_warn("ibuf");
-               goto done;
-       }
-       msgbuf_init(&con->con_wbuf);
-       con->con_wbuf.fd = s;
-
-       memset(&con->con_ev, 0, sizeof(con->con_ev));
-       event_set(&con->con_ev, con->con_fd, EV_READ, ofrelay_event, con);
-       event_add(&con->con_ev, NULL);
-
-       ret = ofp_open(ps, con);
-
- done:
-       if (con == NULL)
-               close(s);
-       ofrelay_inflight_dec(con, __func__);
-       if (ret != 0)
-               ofrelay_close(con);
-
-       return (ret);
-}
diff --git a/usr.sbin/switchd/packet.c b/usr.sbin/switchd/packet.c
deleted file mode 100644 (file)
index ce93d6f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*     $OpenBSD: packet.c,v 1.6 2019/05/05 21:33:00 akoshibe Exp $     */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <event.h>
-
-#include "switchd.h"
-
-const uint8_t etherbroadcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-const uint8_t etherzeroaddr[] = { 0, 0, 0, 0, 0, 0 };
-
-int     packet_ether_unicast(uint8_t *);
-
-int
-packet_ether_unicast(uint8_t *ea)
-{
-       if (memcmp(ea, etherbroadcastaddr, ETHER_ADDR_LEN) == 0 ||
-           memcmp(ea, etherzeroaddr, ETHER_ADDR_LEN) == 0 ||
-           ETHER_IS_MULTICAST(ea))
-               return (-1);
-       return (0);
-}
-
-int
-packet_ether_input(struct ibuf *ibuf, size_t len, struct packet *pkt)
-{
-       struct ether_header     *eh;
-
-       if (len < sizeof(*eh))
-               return (-1);
-
-       pkt->pkt_len = ibuf_dataleft(ibuf);
-       if ((eh = ibuf_getdata(ibuf, sizeof(*eh))) == NULL) {
-               log_debug("short packet");
-               return (-1);
-       }
-
-       pkt->pkt_eh = eh;
-       pkt->pkt_buf = (uint8_t *)eh;
-
-       return (0);
-}
-
-int
-packet_input(struct switchd *sc, struct switch_control *sw, uint32_t srcport,
-    uint32_t *dstport, struct packet *pkt)
-{
-       struct ether_header     *eh;
-       struct macaddr          *src, *dst;
-
-       if (sw == NULL)
-               return (-1);
-
-       eh = pkt->pkt_eh;
-       if ((packet_ether_unicast(eh->ether_shost) == -1) ||
-           (src = switch_learn(sc, sw, eh->ether_shost, srcport)) == NULL)
-               return (-1);
-
-       if (packet_ether_unicast(eh->ether_dhost) == -1)
-               dst = NULL;
-       else
-               dst = switch_cached(sw, eh->ether_dhost);
-
-       log_debug("%s: %s -> %s, port %u -> %u", __func__,
-           print_ether(eh->ether_shost),
-           print_ether(eh->ether_dhost),
-           src->mac_port,
-           dst == NULL ? OFP_PORT_ANY : dst->mac_port);
-
-       if (dstport)
-               *dstport = dst == NULL ? OFP_PORT_ANY : dst->mac_port;
-
-       return (0);
-}
diff --git a/usr.sbin/switchd/parse.y b/usr.sbin/switchd/parse.y
deleted file mode 100644 (file)
index a77d3fd..0000000
+++ /dev/null
@@ -1,763 +0,0 @@
-/*     $OpenBSD: parse.y,v 1.16 2021/10/15 15:01:29 naddy Exp $        */
-
-/*
- * Copyright (c) 2007-2016 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
- * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 2001 Markus Friedl.  All rights reserved.
- * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
- * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-%{
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <limits.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "switchd.h"
-
-TAILQ_HEAD(files, file)                 files = TAILQ_HEAD_INITIALIZER(files);
-static struct file {
-       TAILQ_ENTRY(file)        entry;
-       FILE                    *stream;
-       char                    *name;
-       size_t                   ungetpos;
-       size_t                   ungetsize;
-       u_char                  *ungetbuf;
-       int                      eof_reached;
-       int                      lineno;
-       int                      errors;
-} *file, *topfile;
-struct file    *pushfile(const char *, int);
-int             popfile(void);
-int             yyparse(void);
-int             yylex(void);
-int             yyerror(const char *, ...)
-    __attribute__((__format__ (printf, 1, 2)))
-    __attribute__((__nonnull__ (1)));
-int             kw_cmp(const void *, const void *);
-int             lookup(char *);
-int             igetc(void);
-int             lgetc(int);
-void            lungetc(int);
-int             findeol(void);
-int             host(const char *, struct sockaddr *, socklen_t);
-
-struct switchd *conf;
-
-TAILQ_HEAD(symhead, sym)        symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
-       TAILQ_ENTRY(sym)         entry;
-       int                      used;
-       int                      persist;
-       char                    *nam;
-       char                    *val;
-};
-int             symset(const char *, const char *, int);
-char           *symget(const char *);
-
-typedef struct {
-       union {
-               int64_t          number;
-               char            *string;
-               in_port_t        port;
-               struct switch_client
-                               *conn;
-       } v;
-       int lineno;
-} YYSTYPE;
-
-%}
-
-%token INCLUDE ERROR LISTEN ON TLS PORT DEVICE FORWARD TO
-%token <v.string>      STRING
-%token  <v.number>     NUMBER
-%type  <v.number>      opttls
-%type  <v.conn>        optofcconn
-%type  <v.port>        port
-
-%%
-
-grammar                : /* empty */
-               | grammar '\n'
-               | grammar include '\n'
-               | grammar listen '\n'
-               | grammar device '\n'
-               | grammar varset '\n'
-               | grammar error '\n'            { file->errors++; }
-               ;
-
-include                : INCLUDE STRING                {
-                       struct file     *nfile;
-
-                       if ((nfile = pushfile($2, 0)) == NULL) {
-                               yyerror("failed to include file %s", $2);
-                               free($2);
-                               YYERROR;
-                       }
-                       free($2);
-
-                       file = nfile;
-                       lungetc('\n');
-               }
-               ;
-
-listen         : LISTEN ON STRING opttls port {
-                       if (host($3,
-                           (struct sockaddr *)&conf->sc_server.srv_addr,
-                           sizeof(conf->sc_server.srv_addr)) != 0) {
-                               free($3);
-                               YYERROR;
-                       }
-                       free($3);
-                       conf->sc_server.srv_tls = $4;
-                       ((struct sockaddr_in *)&conf->sc_server.srv_addr)
-                           ->sin_port = $5;
-               }
-               | LISTEN ON STRING opttls {
-                       if (host($3,
-                           (struct sockaddr *)&conf->sc_server.srv_addr,
-                           sizeof(conf->sc_server.srv_addr)) != 0) {
-                               free($3);
-                               YYERROR;
-                       }
-                       free($3);
-                       conf->sc_server.srv_tls = $4;
-                       ((struct sockaddr_in *)&conf->sc_server.srv_addr)
-                           ->sin_port = htons(SWITCHD_CTLR_PORT);
-               }
-               ;
-
-port           : PORT NUMBER {
-                       if ($2 <= 0 || $2 > (int)USHRT_MAX) {
-                               yyerror("invalid port: %lld", $2);
-                               YYERROR;
-                       }
-                       $$ = htons($2);
-               }
-               ;
-
-opttls         : /* empty */   { $$ = 0; }
-               | TLS           { $$ = 1; }
-               ;
-
-device         : DEVICE STRING optofcconn {
-                       struct switch_client            *c;
-                       struct switch_address            s;
-                       struct sockaddr_un              *un;
-
-                       memset(&s, 0, sizeof(s));
-                       un = (struct sockaddr_un *)&s.swa_addr;
-
-                       if (*$2 != '/') {
-                               yyerror("not an absolute path: %s", $2);
-                               free($2);
-                               YYERROR;
-                       }
-
-                       un->sun_family = AF_LOCAL;
-                       un->sun_len = sizeof(*un);
-                       if (strlcpy(un->sun_path, $2,
-                           sizeof(un->sun_path)) >= sizeof(un->sun_path)) {
-                               yyerror("device name is too long: %s", $2);
-                               free($2);
-                               YYERROR;
-                       }
-                       free($2);
-
-                       TAILQ_FOREACH(c, &conf->sc_clients, swc_next) {
-                               if (sockaddr_cmp((struct sockaddr *)
-                                   &c->swc_addr.swa_addr,
-                                   (struct sockaddr *)&s.swa_addr, -1) == 0)
-                                       break;
-                       }
-                       if (c != NULL) {
-                               yyerror("device name is duplicated");
-                               YYERROR;
-                       }
-
-                       memcpy(&$3->swc_addr, &s, sizeof(s));
-
-                       TAILQ_INSERT_TAIL(&conf->sc_clients, $3, swc_next);
-               }
-               ;
-
-optofcconn     : /* empty */ {
-                       if (($$ = calloc(1,
-                           sizeof(struct switch_client))) == NULL)
-                               fatal("calloc");
-                       $$->swc_addr.swa_type = $$->swc_target.swa_type =
-                           SWITCH_CONN_LOCAL;
-               }
-               | FORWARD TO STRING {
-                       size_t   len;
-
-                       if (($$ = calloc(1,
-                           sizeof(struct switch_client))) == NULL)
-                               fatal("calloc");
-                       len = 4;
-                       if (strncmp($3, "tcp:", len) == 0)
-                               $$->swc_target.swa_type = SWITCH_CONN_TCP;
-                       else if (strncmp($3, "tls:", len) == 0)
-                               $$->swc_target.swa_type = SWITCH_CONN_TLS;
-                       else {
-                               len = 0;
-                               $$->swc_target.swa_type = SWITCH_CONN_TCP;
-                       }
-                       if (parsehostport($3 + len,
-                           (struct sockaddr *)&$$->swc_target.swa_addr,
-                           sizeof($$->swc_target.swa_addr)) == -1) {
-                               yyerror("could not parse host and port part "
-                                   "of forward target");
-                               free($$);
-                               free($3);
-                               YYERROR;
-                       }
-                       free($3);
-               }
-               ;
-
-varset         : STRING '=' STRING     {
-                       if (symset($1, $3, 0) == -1)
-                               fatal("cannot store variable");
-                       free($1);
-                       free($3);
-               }
-               ;
-
-%%
-
-struct keywords {
-       const char      *k_name;
-       int              k_val;
-};
-
-int
-yyerror(const char *fmt, ...)
-{
-       va_list          ap;
-       char            *msg;
-
-       file->errors++;
-       va_start(ap, fmt);
-       if (vasprintf(&msg, fmt, ap) == -1)
-               fatal("yyerror vasprintf");
-       va_end(ap);
-       log_warnx("%s:%d: %s", file->name, yylval.lineno, msg);
-       free(msg);
-       return (0);
-}
-
-int
-kw_cmp(const void *k, const void *e)
-{
-       return (strcmp(k, ((const struct keywords *)e)->k_name));
-}
-
-int
-lookup(char *s)
-{
-       /* this has to be sorted always */
-       static const struct keywords keywords[] = {
-               { "device",             DEVICE },
-               { "forward",            FORWARD },
-               { "include",            INCLUDE },
-               { "listen",             LISTEN },
-               { "on",                 ON },
-               { "port",               PORT },
-               { "tls",                TLS },
-               { "to",                 TO },
-       };
-       const struct keywords   *p;
-
-       p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
-           sizeof(keywords[0]), kw_cmp);
-
-       if (p)
-               return (p->k_val);
-       else
-               return (STRING);
-}
-
-#define START_EXPAND   1
-#define DONE_EXPAND    2
-
-static int     expanding;
-
-int
-igetc(void)
-{
-       int     c;
-
-       while (1) {
-               if (file->ungetpos > 0)
-                       c = file->ungetbuf[--file->ungetpos];
-               else
-                       c = getc(file->stream);
-
-               if (c == START_EXPAND)
-                       expanding = 1;
-               else if (c == DONE_EXPAND)
-                       expanding = 0;
-               else
-                       break;
-       }
-       return (c);
-}
-
-int
-lgetc(int quotec)
-{
-       int             c, next;
-
-       if (quotec) {
-               if ((c = igetc()) == EOF) {
-                       yyerror("reached end of file while parsing "
-                           "quoted string");
-                       if (file == topfile || popfile() == EOF)
-                               return (EOF);
-                       return (quotec);
-               }
-               return (c);
-       }
-
-       while ((c = igetc()) == '\\') {
-               next = igetc();
-               if (next != '\n') {
-                       c = next;
-                       break;
-               }
-               yylval.lineno = file->lineno;
-               file->lineno++;
-       }
-       if (c == '\t' || c == ' ') {
-               /* Compress blanks to a single space. */
-               do {
-                       c = getc(file->stream);
-               } while (c == '\t' || c == ' ');
-               ungetc(c, file->stream);
-               c = ' ';
-       }
-
-       if (c == EOF) {
-               /*
-                * Fake EOL when hit EOF for the first time. This gets line
-                * count right if last line in included file is syntactically
-                * invalid and has no newline.
-                */
-               if (file->eof_reached == 0) {
-                       file->eof_reached = 1;
-                       return ('\n');
-               }
-               while (c == EOF) {
-                       if (file == topfile || popfile() == EOF)
-                               return (EOF);
-                       c = igetc();
-               }
-       }
-       return (c);
-}
-
-void
-lungetc(int c)
-{
-       if (c == EOF)
-               return;
-
-       if (file->ungetpos >= file->ungetsize) {
-               void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
-               if (p == NULL)
-                       err(1, "%s", __func__);
-               file->ungetbuf = p;
-               file->ungetsize *= 2;
-       }
-       file->ungetbuf[file->ungetpos++] = c;
-}
-
-int
-findeol(void)
-{
-       int     c;
-
-       /* skip to either EOF or the first real EOL */
-       while (1) {
-               c = lgetc(0);
-               if (c == '\n') {
-                       file->lineno++;
-                       break;
-               }
-               if (c == EOF)
-                       break;
-       }
-       return (ERROR);
-}
-
-int
-yylex(void)
-{
-       char     buf[8096];
-       char    *p, *val;
-       int      quotec, next, c;
-       int      token;
-
-top:
-       p = buf;
-       while ((c = lgetc(0)) == ' ' || c == '\t')
-               ; /* nothing */
-
-       yylval.lineno = file->lineno;
-       if (c == '#')
-               while ((c = lgetc(0)) != '\n' && c != EOF)
-                       ; /* nothing */
-       if (c == '$' && !expanding) {
-               while (1) {
-                       if ((c = lgetc(0)) == EOF)
-                               return (0);
-
-                       if (p + 1 >= buf + sizeof(buf) - 1) {
-                               yyerror("string too long");
-                               return (findeol());
-                       }
-                       if (isalnum(c) || c == '_') {
-                               *p++ = c;
-                               continue;
-                       }
-                       *p = '\0';
-                       lungetc(c);
-                       break;
-               }
-               val = symget(buf);
-               if (val == NULL) {
-                       yyerror("macro '%s' not defined", buf);
-                       return (findeol());
-               }
-               p = val + strlen(val) - 1;
-               lungetc(DONE_EXPAND);
-               while (p >= val) {
-                       lungetc((unsigned char)*p);
-                       p--;
-               }
-               lungetc(START_EXPAND);
-               goto top;
-       }
-
-       switch (c) {
-       case '\'':
-       case '"':
-               quotec = c;
-               while (1) {
-                       if ((c = lgetc(quotec)) == EOF)
-                               return (0);
-                       if (c == '\n') {
-                               file->lineno++;
-                               continue;
-                       } else if (c == '\\') {
-                               if ((next = lgetc(quotec)) == EOF)
-                                       return (0);
-                               if (next == quotec || next == ' ' ||
-                                   next == '\t')
-                                       c = next;
-                               else if (next == '\n') {
-                                       file->lineno++;
-                                       continue;
-                               } else
-                                       lungetc(next);
-                       } else if (c == quotec) {
-                               *p = '\0';
-                               break;
-                       } else if (c == '\0') {
-                               yyerror("syntax error");
-                               return (findeol());
-                       }
-                       if (p + 1 >= buf + sizeof(buf) - 1) {
-                               yyerror("string too long");
-                               return (findeol());
-                       }
-                       *p++ = c;
-               }
-               yylval.v.string = strdup(buf);
-               if (yylval.v.string == NULL)
-                       fatal("yylex: strdup");
-               return (STRING);
-       }
-
-#define allowed_to_end_number(x) \
-       (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
-
-       if (c == '-' || isdigit(c)) {
-               do {
-                       *p++ = c;
-                       if ((size_t)(p-buf) >= sizeof(buf)) {
-                               yyerror("string too long");
-                               return (findeol());
-                       }
-               } while ((c = lgetc(0)) != EOF && isdigit(c));
-               lungetc(c);
-               if (p == buf + 1 && buf[0] == '-')
-                       goto nodigits;
-               if (c == EOF || allowed_to_end_number(c)) {
-                       const char *errstr = NULL;
-
-                       *p = '\0';
-                       yylval.v.number = strtonum(buf, LLONG_MIN,
-                           LLONG_MAX, &errstr);
-                       if (errstr) {
-                               yyerror("\"%s\" invalid number: %s",
-                                   buf, errstr);
-                               return (findeol());
-                       }
-                       return (NUMBER);
-               } else {
-nodigits:
-                       while (p > buf + 1)
-                               lungetc((unsigned char)*--p);
-                       c = (unsigned char)*--p;
-                       if (c == '-')
-                               return (c);
-               }
-       }
-
-#define allowed_in_string(x) \
-       (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
-       x != '{' && x != '}' && \
-       x != '!' && x != '=' && x != '#' && \
-       x != ','))
-
-       if (isalnum(c) || c == ':' || c == '_' || c == '/') {
-               do {
-                       *p++ = c;
-                       if ((size_t)(p-buf) >= sizeof(buf)) {
-                               yyerror("string too long");
-                               return (findeol());
-                       }
-               } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
-               lungetc(c);
-               *p = '\0';
-               if ((token = lookup(buf)) == STRING)
-                       if ((yylval.v.string = strdup(buf)) == NULL)
-                               fatal("yylex: strdup");
-               return (token);
-       }
-       if (c == '\n') {
-               yylval.lineno = file->lineno;
-               file->lineno++;
-       }
-       if (c == EOF)
-               return (0);
-       return (c);
-}
-
-struct file *
-pushfile(const char *name, int secret)
-{
-       struct file     *nfile;
-
-       if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
-               log_warn("%s", __func__);
-               return (NULL);
-       }
-       if ((nfile->name = strdup(name)) == NULL) {
-               log_warn("%s", __func__);
-               free(nfile);
-               return (NULL);
-       }
-       if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
-               free(nfile->name);
-               free(nfile);
-               return (NULL);
-       }
-       nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
-       nfile->ungetsize = 16;
-       nfile->ungetbuf = malloc(nfile->ungetsize);
-       if (nfile->ungetbuf == NULL) {
-               log_warn("%s", __func__);
-               fclose(nfile->stream);
-               free(nfile->name);
-               free(nfile);
-               return (NULL);
-       }
-       TAILQ_INSERT_TAIL(&files, nfile, entry);
-       return (nfile);
-}
-
-int
-popfile(void)
-{
-       struct file     *prev;
-
-       if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
-               prev->errors += file->errors;
-
-       TAILQ_REMOVE(&files, file, entry);
-       fclose(file->stream);
-       free(file->name);
-       free(file->ungetbuf);
-       free(file);
-       file = prev;
-       return (file ? 0 : EOF);
-}
-
-int
-parse_config(const char *filename, struct switchd *sc)
-{
-       struct sym              *sym;
-       int                      errors = 0;
-       struct sockaddr_in      *sin4;
-
-       conf = sc;
-
-       /* Set the default 0.0.0.0 6653/tcp */
-       memset(&conf->sc_server.srv_addr, 0, sizeof(conf->sc_server.srv_addr));
-       sin4 = (struct sockaddr_in *)&conf->sc_server.srv_addr;
-       sin4->sin_family = AF_INET;
-       sin4->sin_port = htons(SWITCHD_CTLR_PORT);
-       sin4->sin_len = sizeof(struct sockaddr_in);
-
-       if ((file = pushfile(filename, 0)) == NULL) {
-               log_warn("failed to open %s", filename);
-               return (-1);
-       }
-       topfile = file;
-       setservent(1);
-
-       yyparse();
-       errors = file->errors;
-       popfile();
-
-       endservent();
-
-       /* Free macros and check which have not been used. */
-       while ((sym = TAILQ_FIRST(&symhead))) {
-               if (!sym->used)
-                       log_debug("warning: macro '%s' not "
-                           "used\n", sym->nam);
-               free(sym->nam);
-               free(sym->val);
-               TAILQ_REMOVE(&symhead, sym, entry);
-               free(sym);
-       }
-
-       return (errors ? -1 : 0);
-}
-
-int
-symset(const char *nam, const char *val, int persist)
-{
-       struct sym      *sym;
-
-       TAILQ_FOREACH(sym, &symhead, entry) {
-               if (strcmp(nam, sym->nam) == 0)
-                       break;
-       }
-
-       if (sym != NULL) {
-               if (sym->persist == 1)
-                       return (0);
-               else {
-                       free(sym->nam);
-                       free(sym->val);
-                       TAILQ_REMOVE(&symhead, sym, entry);
-                       free(sym);
-               }
-       }
-       if ((sym = calloc(1, sizeof(*sym))) == NULL)
-               return (-1);
-
-       sym->nam = strdup(nam);
-       if (sym->nam == NULL) {
-               free(sym);
-               return (-1);
-       }
-       sym->val = strdup(val);
-       if (sym->val == NULL) {
-               free(sym->nam);
-               free(sym);
-               return (-1);
-       }
-       sym->used = 0;
-       sym->persist = persist;
-       TAILQ_INSERT_TAIL(&symhead, sym, entry);
-       return (0);
-}
-
-int
-cmdline_symset(char *s)
-{
-       char    *sym, *val;
-       int     ret;
-
-       if ((val = strrchr(s, '=')) == NULL)
-               return (-1);
-       sym = strndup(s, val - s);
-       if (sym == NULL)
-               fatal("%s: strndup", __func__);
-       ret = symset(sym, val + 1, 1);
-       free(sym);
-
-       return (ret);
-}
-
-char *
-symget(const char *nam)
-{
-       struct sym      *sym;
-
-       TAILQ_FOREACH(sym, &symhead, entry) {
-               if (strcmp(nam, sym->nam) == 0) {
-                       sym->used = 1;
-                       return (sym->val);
-               }
-       }
-       return (NULL);
-}
-
-int
-host(const char *str, struct sockaddr *sa, socklen_t salen)
-{
-       struct addrinfo  hints, *ai0;
-       int              error;
-
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_flags = AI_NUMERICHOST;
-       hints.ai_family = AF_UNSPEC;
-
-       if ((error = getaddrinfo(str, NULL, &hints, &ai0)) != 0) {
-               yyerror("invalid listen address: %s: %s", str,
-                   gai_strerror(error));
-               return (-1);
-       }
-       if (salen >= ai0->ai_addrlen)
-               memcpy(sa, ai0->ai_addr, ai0->ai_addrlen);
-       else {
-               yyerror("addrlen is invalid: %d", (int)ai0->ai_addrlen);
-               freeaddrinfo(ai0);
-               return (-1);
-       }
-       freeaddrinfo(ai0);
-
-       return (0);
-}
diff --git a/usr.sbin/switchd/proc.c b/usr.sbin/switchd/proc.c
deleted file mode 100644 (file)
index 6f6a87f..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-/*     $OpenBSD: proc.c,v 1.15 2021/04/20 21:11:56 dv Exp $    */
-
-/*
- * Copyright (c) 2010 - 2016 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <paths.h>
-#include <pwd.h>
-#include <event.h>
-#include <imsg.h>
-
-#include "proc.h"
-
-void    proc_exec(struct privsep *, struct privsep_proc *, unsigned int, int,
-           int, char **);
-void    proc_setup(struct privsep *, struct privsep_proc *, unsigned int);
-void    proc_open(struct privsep *, int, int);
-void    proc_accept(struct privsep *, int, enum privsep_procid,
-           unsigned int);
-void    proc_close(struct privsep *);
-int     proc_ispeer(struct privsep_proc *, unsigned int, enum privsep_procid);
-void    proc_shutdown(struct privsep_proc *);
-void    proc_sig_handler(int, short, void *);
-void    proc_range(struct privsep *, enum privsep_procid, int *, int *);
-int     proc_dispatch_null(int, struct privsep_proc *, struct imsg *);
-
-int
-proc_ispeer(struct privsep_proc *procs, unsigned int nproc,
-    enum privsep_procid type)
-{
-       unsigned int    i;
-
-       for (i = 0; i < nproc; i++)
-               if (procs[i].p_id == type)
-                       return (1);
-       return (0);
-}
-
-enum privsep_procid
-proc_getid(struct privsep_proc *procs, unsigned int nproc,
-    const char *proc_name)
-{
-       struct privsep_proc     *p;
-       unsigned int             proc;
-
-       for (proc = 0; proc < nproc; proc++) {
-               p = &procs[proc];
-               if (strcmp(p->p_title, proc_name))
-                       continue;
-
-               return (p->p_id);
-       }
-
-       return (PROC_MAX);
-}
-
-void
-proc_exec(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc,
-    int debug, int argc, char **argv)
-{
-       unsigned int             proc, nargc, i, proc_i;
-       char                    **nargv;
-       struct privsep_proc     *p;
-       char                     num[32];
-       int                      fd;
-
-       /* Prepare the new process argv. */
-       nargv = calloc(argc + 5, sizeof(char *));
-       if (nargv == NULL)
-               fatal("%s: calloc", __func__);
-
-       /* Copy call argument first. */
-       nargc = 0;
-       nargv[nargc++] = argv[0];
-
-       /* Set process name argument and save the position. */
-       nargv[nargc++] = "-P";
-       proc_i = nargc;
-       nargc++;
-
-       /* Point process instance arg to stack and copy the original args. */
-       nargv[nargc++] = "-I";
-       nargv[nargc++] = num;
-       for (i = 1; i < (unsigned int) argc; i++)
-               nargv[nargc++] = argv[i];
-
-       nargv[nargc] = NULL;
-
-       for (proc = 0; proc < nproc; proc++) {
-               p = &procs[proc];
-
-               /* Update args with process title. */
-               nargv[proc_i] = (char *)(uintptr_t)p->p_title;
-
-               /* Fire children processes. */
-               for (i = 0; i < ps->ps_instances[p->p_id]; i++) {
-                       /* Update the process instance number. */
-                       snprintf(num, sizeof(num), "%u", i);
-
-                       fd = ps->ps_pipes[p->p_id][i].pp_pipes[PROC_PARENT][0];
-                       ps->ps_pipes[p->p_id][i].pp_pipes[PROC_PARENT][0] = -1;
-
-                       switch (fork()) {
-                       case -1:
-                               fatal("%s: fork", __func__);
-                               break;
-                       case 0:
-                               /* First create a new session */
-                               if (setsid() == -1)
-                                       fatal("setsid");
-
-                               /* Prepare parent socket. */
-                               if (fd != PROC_PARENT_SOCK_FILENO) {
-                                       if (dup2(fd, PROC_PARENT_SOCK_FILENO)
-                                           == -1)
-                                               fatal("dup2");
-                               } else if (fcntl(fd, F_SETFD, 0) == -1)
-                                       fatal("fcntl");
-
-                               /* Daemons detach from terminal. */
-                               if (!debug && (fd =
-                                   open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
-                                       (void)dup2(fd, STDIN_FILENO);
-                                       (void)dup2(fd, STDOUT_FILENO);
-                                       (void)dup2(fd, STDERR_FILENO);
-                                       if (fd > 2)
-                                               (void)close(fd);
-                               }
-
-                               execvp(argv[0], nargv);
-                               fatal("%s: execvp", __func__);
-                               break;
-                       default:
-                               /* Close child end. */
-                               close(fd);
-                               break;
-                       }
-               }
-       }
-       free(nargv);
-}
-
-void
-proc_connect(struct privsep *ps)
-{
-       struct imsgev           *iev;
-       unsigned int             src, dst, inst;
-
-       /* Don't distribute any sockets if we are not really going to run. */
-       if (ps->ps_noaction)
-               return;
-
-       for (dst = 0; dst < PROC_MAX; dst++) {
-               /* We don't communicate with ourselves. */
-               if (dst == PROC_PARENT)
-                       continue;
-
-               for (inst = 0; inst < ps->ps_instances[dst]; inst++) {
-                       iev = &ps->ps_ievs[dst][inst];
-                       imsg_init(&iev->ibuf, ps->ps_pp->pp_pipes[dst][inst]);
-                       event_set(&iev->ev, iev->ibuf.fd, iev->events,
-                           iev->handler, iev->data);
-                       event_add(&iev->ev, NULL);
-               }
-       }
-
-       /* Distribute the socketpair()s for everyone. */
-       for (src = 0; src < PROC_MAX; src++)
-               for (dst = src; dst < PROC_MAX; dst++) {
-                       /* Parent already distributed its fds. */
-                       if (src == PROC_PARENT || dst == PROC_PARENT)
-                               continue;
-
-                       proc_open(ps, src, dst);
-               }
-}
-
-void
-proc_init(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc,
-    int debug, int argc, char **argv, enum privsep_procid proc_id)
-{
-       struct privsep_proc     *p = NULL;
-       struct privsep_pipes    *pa, *pb;
-       unsigned int             proc;
-       unsigned int             dst;
-       int                      fds[2];
-
-       /* Don't initiate anything if we are not really going to run. */
-       if (ps->ps_noaction)
-               return;
-
-       if (proc_id == PROC_PARENT) {
-               privsep_process = PROC_PARENT;
-               proc_setup(ps, procs, nproc);
-
-               /*
-                * Create the children sockets so we can use them
-                * to distribute the rest of the socketpair()s using
-                * proc_connect() later.
-                */
-               for (dst = 0; dst < PROC_MAX; dst++) {
-                       /* Don't create socket for ourselves. */
-                       if (dst == PROC_PARENT)
-                               continue;
-
-                       for (proc = 0; proc < ps->ps_instances[dst]; proc++) {
-                               pa = &ps->ps_pipes[PROC_PARENT][0];
-                               pb = &ps->ps_pipes[dst][proc];
-                               if (socketpair(AF_UNIX,
-                                   SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
-                                   PF_UNSPEC, fds) == -1)
-                                       fatal("%s: socketpair", __func__);
-
-                               pa->pp_pipes[dst][proc] = fds[0];
-                               pb->pp_pipes[PROC_PARENT][0] = fds[1];
-                       }
-               }
-
-               /* Engage! */
-               proc_exec(ps, procs, nproc, debug, argc, argv);
-               return;
-       }
-
-       /* Initialize a child */
-       for (proc = 0; proc < nproc; proc++) {
-               if (procs[proc].p_id != proc_id)
-                       continue;
-               p = &procs[proc];
-               break;
-       }
-       if (p == NULL || p->p_init == NULL)
-               fatalx("%s: process %d missing process initialization",
-                   __func__, proc_id);
-
-       p->p_init(ps, p);
-
-       fatalx("failed to initiate child process");
-}
-
-void
-proc_accept(struct privsep *ps, int fd, enum privsep_procid dst,
-    unsigned int n)
-{
-       struct privsep_pipes    *pp = ps->ps_pp;
-       struct imsgev           *iev;
-
-       if (ps->ps_ievs[dst] == NULL) {
-#if DEBUG > 1
-               log_debug("%s: %s src %d %d to dst %d %d not connected",
-                   __func__, ps->ps_title[privsep_process],
-                   privsep_process, ps->ps_instance + 1,
-                   dst, n + 1);
-#endif
-               close(fd);
-               return;
-       }
-
-       if (pp->pp_pipes[dst][n] != -1) {
-               log_warnx("%s: duplicated descriptor", __func__);
-               close(fd);
-               return;
-       } else
-               pp->pp_pipes[dst][n] = fd;
-
-       iev = &ps->ps_ievs[dst][n];
-       imsg_init(&iev->ibuf, fd);
-       event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
-       event_add(&iev->ev, NULL);
-}
-
-void
-proc_setup(struct privsep *ps, struct privsep_proc *procs, unsigned int nproc)
-{
-       unsigned int             i, j, src, dst, id;
-       struct privsep_pipes    *pp;
-
-       /* Initialize parent title, ps_instances and procs. */
-       ps->ps_title[PROC_PARENT] = "parent";
-
-       for (src = 0; src < PROC_MAX; src++)
-               /* Default to 1 process instance */
-               if (ps->ps_instances[src] < 1)
-                       ps->ps_instances[src] = 1;
-
-       for (src = 0; src < nproc; src++) {
-               procs[src].p_ps = ps;
-               if (procs[src].p_cb == NULL)
-                       procs[src].p_cb = proc_dispatch_null;
-
-               id = procs[src].p_id;
-               ps->ps_title[id] = procs[src].p_title;
-               if ((ps->ps_ievs[id] = calloc(ps->ps_instances[id],
-                   sizeof(struct imsgev))) == NULL)
-                       fatal("%s: calloc", __func__);
-
-               /* With this set up, we are ready to call imsg_init(). */
-               for (i = 0; i < ps->ps_instances[id]; i++) {
-                       ps->ps_ievs[id][i].handler = proc_dispatch;
-                       ps->ps_ievs[id][i].events = EV_READ;
-                       ps->ps_ievs[id][i].proc = &procs[src];
-                       ps->ps_ievs[id][i].data = &ps->ps_ievs[id][i];
-               }
-       }
-
-       /*
-        * Allocate pipes for all process instances (incl. parent)
-        *
-        * - ps->ps_pipes: N:M mapping
-        * N source processes connected to M destination processes:
-        * [src][instances][dst][instances], for example
-        * [PROC_RELAY][3][PROC_CA][3]
-        *
-        * - ps->ps_pp: per-process 1:M part of ps->ps_pipes
-        * Each process instance has a destination array of socketpair fds:
-        * [dst][instances], for example
-        * [PROC_PARENT][0]
-        */
-       for (src = 0; src < PROC_MAX; src++) {
-               /* Allocate destination array for each process */
-               if ((ps->ps_pipes[src] = calloc(ps->ps_instances[src],
-                   sizeof(struct privsep_pipes))) == NULL)
-                       fatal("%s: calloc", __func__);
-
-               for (i = 0; i < ps->ps_instances[src]; i++) {
-                       pp = &ps->ps_pipes[src][i];
-
-                       for (dst = 0; dst < PROC_MAX; dst++) {
-                               /* Allocate maximum fd integers */
-                               if ((pp->pp_pipes[dst] =
-                                   calloc(ps->ps_instances[dst],
-                                   sizeof(int))) == NULL)
-                                       fatal("%s: calloc", __func__);
-
-                               /* Mark fd as unused */
-                               for (j = 0; j < ps->ps_instances[dst]; j++)
-                                       pp->pp_pipes[dst][j] = -1;
-                       }
-               }
-       }
-
-       ps->ps_pp = &ps->ps_pipes[privsep_process][ps->ps_instance];
-}
-
-void
-proc_kill(struct privsep *ps)
-{
-       char            *cause;
-       pid_t            pid;
-       int              len, status;
-
-       if (privsep_process != PROC_PARENT)
-               return;
-
-       proc_close(ps);
-
-       do {
-               pid = waitpid(WAIT_ANY, &status, 0);
-               if (pid <= 0)
-                       continue;
-
-               if (WIFSIGNALED(status)) {
-                       len = asprintf(&cause, "terminated; signal %d",
-                           WTERMSIG(status));
-               } else if (WIFEXITED(status)) {
-                       if (WEXITSTATUS(status) != 0)
-                               len = asprintf(&cause, "exited abnormally");
-                       else
-                               len = 0;
-               } else
-                       len = -1;
-
-               if (len == 0) {
-                       /* child exited OK, don't print a warning message */
-               } else if (len != -1) {
-                       log_warnx("lost child: pid %u %s", pid, cause);
-                       free(cause);
-               } else
-                       log_warnx("lost child: pid %u", pid);
-       } while (pid != -1 || (pid == -1 && errno == EINTR));
-}
-
-void
-proc_open(struct privsep *ps, int src, int dst)
-{
-       struct privsep_pipes    *pa, *pb;
-       struct privsep_fd        pf;
-       int                      fds[2];
-       unsigned int             i, j;
-
-       /* Exchange pipes between process. */
-       for (i = 0; i < ps->ps_instances[src]; i++) {
-               for (j = 0; j < ps->ps_instances[dst]; j++) {
-                       /* Don't create sockets for ourself. */
-                       if (src == dst && i == j)
-                               continue;
-
-                       pa = &ps->ps_pipes[src][i];
-                       pb = &ps->ps_pipes[dst][j];
-                       if (socketpair(AF_UNIX,
-                           SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
-                           PF_UNSPEC, fds) == -1)
-                               fatal("%s: socketpair", __func__);
-
-                       pa->pp_pipes[dst][j] = fds[0];
-                       pb->pp_pipes[src][i] = fds[1];
-
-                       pf.pf_procid = src;
-                       pf.pf_instance = i;
-                       if (proc_compose_imsg(ps, dst, j, IMSG_CTL_PROCFD,
-                           -1, pb->pp_pipes[src][i], &pf, sizeof(pf)) == -1)
-                               fatal("%s: proc_compose_imsg", __func__);
-
-                       pf.pf_procid = dst;
-                       pf.pf_instance = j;
-                       if (proc_compose_imsg(ps, src, i, IMSG_CTL_PROCFD,
-                           -1, pa->pp_pipes[dst][j], &pf, sizeof(pf)) == -1)
-                               fatal("%s: proc_compose_imsg", __func__);
-
-                       /*
-                        * We have to flush to send the descriptors and close
-                        * them to avoid the fd ramp on startup.
-                        */
-                       if (proc_flush_imsg(ps, src, i) == -1 ||
-                           proc_flush_imsg(ps, dst, j) == -1)
-                               fatal("%s: imsg_flush", __func__);
-               }
-       }
-}
-
-void
-proc_close(struct privsep *ps)
-{
-       unsigned int             dst, n;
-       struct privsep_pipes    *pp;
-
-       if (ps == NULL)
-               return;
-
-       pp = ps->ps_pp;
-
-       for (dst = 0; dst < PROC_MAX; dst++) {
-               if (ps->ps_ievs[dst] == NULL)
-                       continue;
-
-               for (n = 0; n < ps->ps_instances[dst]; n++) {
-                       if (pp->pp_pipes[dst][n] == -1)
-                               continue;
-
-                       /* Cancel the fd, close and invalidate the fd */
-                       event_del(&(ps->ps_ievs[dst][n].ev));
-                       imsg_clear(&(ps->ps_ievs[dst][n].ibuf));
-                       close(pp->pp_pipes[dst][n]);
-                       pp->pp_pipes[dst][n] = -1;
-               }
-               free(ps->ps_ievs[dst]);
-       }
-}
-
-void
-proc_shutdown(struct privsep_proc *p)
-{
-       struct privsep  *ps = p->p_ps;
-
-       if (p->p_shutdown != NULL)
-               (*p->p_shutdown)();
-
-       proc_close(ps);
-
-       log_info("%s exiting, pid %d", p->p_title, getpid());
-
-       exit(0);
-}
-
-void
-proc_sig_handler(int sig, short event, void *arg)
-{
-       struct privsep_proc     *p = arg;
-
-       switch (sig) {
-       case SIGINT:
-       case SIGTERM:
-               proc_shutdown(p);
-               break;
-       case SIGCHLD:
-       case SIGHUP:
-       case SIGPIPE:
-       case SIGUSR1:
-               /* ignore */
-               break;
-       default:
-               fatalx("%s: unexpected signal", __func__);
-               /* NOTREACHED */
-       }
-}
-
-void
-proc_run(struct privsep *ps, struct privsep_proc *p,
-    struct privsep_proc *procs, unsigned int nproc,
-    void (*run)(struct privsep *, struct privsep_proc *, void *), void *arg)
-{
-       struct passwd           *pw;
-       const char              *root;
-       struct control_sock     *rcs;
-
-       log_procinit(p->p_title);
-
-       /* Set the process group of the current process */
-       setpgid(0, 0);
-
-       if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) {
-               if (control_init(ps, &ps->ps_csock) == -1)
-                       fatalx("%s: control_init", __func__);
-               TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry)
-                       if (control_init(ps, rcs) == -1)
-                               fatalx("%s: control_init", __func__);
-       }
-
-       /* Use non-standard user */
-       if (p->p_pw != NULL)
-               pw = p->p_pw;
-       else
-               pw = ps->ps_pw;
-
-       /* Change root directory */
-       if (p->p_chroot != NULL)
-               root = p->p_chroot;
-       else
-               root = pw->pw_dir;
-
-       if (chroot(root) == -1)
-               fatal("%s: chroot", __func__);
-       if (chdir("/") == -1)
-               fatal("%s: chdir(\"/\")", __func__);
-
-       privsep_process = p->p_id;
-
-       setproctitle("%s", p->p_title);
-
-       if (setgroups(1, &pw->pw_gid) ||
-           setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
-           setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
-               fatal("%s: cannot drop privileges", __func__);
-
-       event_init();
-
-       signal_set(&ps->ps_evsigint, SIGINT, proc_sig_handler, p);
-       signal_set(&ps->ps_evsigterm, SIGTERM, proc_sig_handler, p);
-       signal_set(&ps->ps_evsigchld, SIGCHLD, proc_sig_handler, p);
-       signal_set(&ps->ps_evsighup, SIGHUP, proc_sig_handler, p);
-       signal_set(&ps->ps_evsigpipe, SIGPIPE, proc_sig_handler, p);
-       signal_set(&ps->ps_evsigusr1, SIGUSR1, proc_sig_handler, p);
-
-       signal_add(&ps->ps_evsigint, NULL);
-       signal_add(&ps->ps_evsigterm, NULL);
-       signal_add(&ps->ps_evsigchld, NULL);
-       signal_add(&ps->ps_evsighup, NULL);
-       signal_add(&ps->ps_evsigpipe, NULL);
-       signal_add(&ps->ps_evsigusr1, NULL);
-
-       proc_setup(ps, procs, nproc);
-       proc_accept(ps, PROC_PARENT_SOCK_FILENO, PROC_PARENT, 0);
-       if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) {
-               if (control_listen(&ps->ps_csock) == -1)
-                       fatalx("%s: control_listen", __func__);
-               TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry)
-                       if (control_listen(rcs) == -1)
-                               fatalx("%s: control_listen", __func__);
-       }
-
-       DPRINTF("%s: %s %d/%d, pid %d", __func__, p->p_title,
-           ps->ps_instance + 1, ps->ps_instances[p->p_id], getpid());
-
-       if (run != NULL)
-               run(ps, p, arg);
-
-       event_dispatch();
-
-       proc_shutdown(p);
-}
-
-void
-proc_dispatch(int fd, short event, void *arg)
-{
-       struct imsgev           *iev = arg;
-       struct privsep_proc     *p = iev->proc;
-       struct privsep          *ps = p->p_ps;
-       struct imsgbuf          *ibuf;
-       struct imsg              imsg;
-       ssize_t                  n;
-       int                      verbose;
-       const char              *title;
-       struct privsep_fd        pf;
-
-       title = ps->ps_title[privsep_process];
-       ibuf = &iev->ibuf;
-
-       if (event & EV_READ) {
-               if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
-                       fatal("%s: imsg_read", __func__);
-               if (n == 0) {
-                       /* this pipe is dead, so remove the event handler */
-                       event_del(&iev->ev);
-                       event_loopexit(NULL);
-                       return;
-               }
-       }
-
-       if (event & EV_WRITE) {
-               if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
-                       fatal("%s: msgbuf_write", __func__);
-               if (n == 0) {
-                       /* this pipe is dead, so remove the event handler */
-                       event_del(&iev->ev);
-                       event_loopexit(NULL);
-                       return;
-               }
-       }
-
-       for (;;) {
-               if ((n = imsg_get(ibuf, &imsg)) == -1)
-                       fatal("%s: imsg_get", __func__);
-               if (n == 0)
-                       break;
-
-#if DEBUG > 1
-               log_debug("%s: %s %d got imsg %d peerid %d from %s %d",
-                   __func__, title, ps->ps_instance + 1,
-                   imsg.hdr.type, imsg.hdr.peerid, p->p_title, imsg.hdr.pid);
-#endif
-
-               /*
-                * Check the message with the program callback
-                */
-               if ((p->p_cb)(fd, p, &imsg) == 0) {
-                       /* Message was handled by the callback, continue */
-                       imsg_free(&imsg);
-                       continue;
-               }
-
-               /*
-                * Generic message handling
-                */
-               switch (imsg.hdr.type) {
-               case IMSG_CTL_VERBOSE:
-                       IMSG_SIZE_CHECK(&imsg, &verbose);
-                       memcpy(&verbose, imsg.data, sizeof(verbose));
-                       log_setverbose(verbose);
-                       break;
-               case IMSG_CTL_PROCFD:
-                       IMSG_SIZE_CHECK(&imsg, &pf);
-                       memcpy(&pf, imsg.data, sizeof(pf));
-                       proc_accept(ps, imsg.fd, pf.pf_procid,
-                           pf.pf_instance);
-                       break;
-               default:
-                       fatalx("%s: %s %d got invalid imsg %d peerid %d "
-                           "from %s %d",
-                           __func__, title, ps->ps_instance + 1,
-                           imsg.hdr.type, imsg.hdr.peerid,
-                           p->p_title, imsg.hdr.pid);
-               }
-               imsg_free(&imsg);
-       }
-       imsg_event_add(iev);
-}
-
-int
-proc_dispatch_null(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       return (-1);
-}
-
-/*
- * imsg helper functions
- */
-
-void
-imsg_event_add(struct imsgev *iev)
-{
-       if (iev->handler == NULL) {
-               imsg_flush(&iev->ibuf);
-               return;
-       }
-
-       iev->events = EV_READ;
-       if (iev->ibuf.w.queued)
-               iev->events |= EV_WRITE;
-
-       event_del(&iev->ev);
-       event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
-       event_add(&iev->ev, NULL);
-}
-
-int
-imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
-    pid_t pid, int fd, void *data, uint16_t datalen)
-{
-       int     ret;
-
-       if ((ret = imsg_compose(&iev->ibuf, type, peerid,
-           pid, fd, data, datalen)) == -1)
-               return (ret);
-       imsg_event_add(iev);
-       return (ret);
-}
-
-int
-imsg_composev_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
-    pid_t pid, int fd, const struct iovec *iov, int iovcnt)
-{
-       int     ret;
-
-       if ((ret = imsg_composev(&iev->ibuf, type, peerid,
-           pid, fd, iov, iovcnt)) == -1)
-               return (ret);
-       imsg_event_add(iev);
-       return (ret);
-}
-
-void
-proc_range(struct privsep *ps, enum privsep_procid id, int *n, int *m)
-{
-       if (*n == -1) {
-               /* Use a range of all target instances */
-               *n = 0;
-               *m = ps->ps_instances[id];
-       } else {
-               /* Use only a single slot of the specified peer process */
-               *m = *n + 1;
-       }
-}
-
-int
-proc_compose_imsg(struct privsep *ps, enum privsep_procid id, int n,
-    uint16_t type, uint32_t peerid, int fd, void *data, uint16_t datalen)
-{
-       int      m;
-
-       proc_range(ps, id, &n, &m);
-       for (; n < m; n++) {
-               if (imsg_compose_event(&ps->ps_ievs[id][n],
-                   type, peerid, ps->ps_instance + 1, fd, data, datalen) == -1)
-                       return (-1);
-       }
-
-       return (0);
-}
-
-int
-proc_compose(struct privsep *ps, enum privsep_procid id,
-    uint16_t type, void *data, uint16_t datalen)
-{
-       return (proc_compose_imsg(ps, id, -1, type, -1, -1, data, datalen));
-}
-
-int
-proc_composev_imsg(struct privsep *ps, enum privsep_procid id, int n,
-    uint16_t type, uint32_t peerid, int fd, const struct iovec *iov, int iovcnt)
-{
-       int      m;
-
-       proc_range(ps, id, &n, &m);
-       for (; n < m; n++)
-               if (imsg_composev_event(&ps->ps_ievs[id][n],
-                   type, peerid, ps->ps_instance + 1, fd, iov, iovcnt) == -1)
-                       return (-1);
-
-       return (0);
-}
-
-int
-proc_composev(struct privsep *ps, enum privsep_procid id,
-    uint16_t type, const struct iovec *iov, int iovcnt)
-{
-       return (proc_composev_imsg(ps, id, -1, type, -1, -1, iov, iovcnt));
-}
-
-int
-proc_forward_imsg(struct privsep *ps, struct imsg *imsg,
-    enum privsep_procid id, int n)
-{
-       return (proc_compose_imsg(ps, id, n, imsg->hdr.type,
-           imsg->hdr.peerid, imsg->fd, imsg->data, IMSG_DATA_SIZE(imsg)));
-}
-
-struct imsgbuf *
-proc_ibuf(struct privsep *ps, enum privsep_procid id, int n)
-{
-       int      m;
-
-       proc_range(ps, id, &n, &m);
-       return (&ps->ps_ievs[id][n].ibuf);
-}
-
-struct imsgev *
-proc_iev(struct privsep *ps, enum privsep_procid id, int n)
-{
-       int      m;
-
-       proc_range(ps, id, &n, &m);
-       return (&ps->ps_ievs[id][n]);
-}
-
-/* This function should only be called with care as it breaks async I/O */
-int
-proc_flush_imsg(struct privsep *ps, enum privsep_procid id, int n)
-{
-       struct imsgbuf  *ibuf;
-       int              m, ret = 0;
-
-       proc_range(ps, id, &n, &m);
-       for (; n < m; n++) {
-               if ((ibuf = proc_ibuf(ps, id, n)) == NULL)
-                       return (-1);
-               do {
-                       ret = imsg_flush(ibuf);
-               } while (ret == -1 && errno == EAGAIN);
-               if (ret == -1)
-                       break;
-               imsg_event_add(&ps->ps_ievs[id][n]);
-       }
-
-       return (ret);
-}
diff --git a/usr.sbin/switchd/proc.h b/usr.sbin/switchd/proc.h
deleted file mode 100644 (file)
index b79c51e..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*     $OpenBSD: proc.h,v 1.9 2021/04/20 21:11:56 dv Exp $     */
-
-/*
- * Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <imsg.h>
-#include <event.h>
-#include "types.h"
-
-#ifndef _PROC_H
-#define _PROC_H
-
-struct control_sock {
-       const char      *cs_name;
-       struct event     cs_ev;
-       struct event     cs_evt;
-       int              cs_fd;
-       int              cs_restricted;
-       void            *cs_env;
-
-       TAILQ_ENTRY(control_sock) cs_entry;
-};
-TAILQ_HEAD(control_socks, control_sock);
-
-struct privsep_pipes {
-       int                             *pp_pipes[PROC_MAX];
-};
-
-struct privsep {
-       struct privsep_pipes            *ps_pipes[PROC_MAX];
-       struct privsep_pipes            *ps_pp;
-
-       struct imsgev                   *ps_ievs[PROC_MAX];
-       const char                      *ps_title[PROC_MAX];
-       pid_t                            ps_pid[PROC_MAX];
-       struct passwd                   *ps_pw;
-       int                              ps_noaction;
-
-       struct control_sock              ps_csock;
-       struct control_socks             ps_rcsocks;
-
-       unsigned int                     ps_instances[PROC_MAX];
-       unsigned int                     ps_instance;
-
-       /* Event and signal handlers */
-       struct event                     ps_evsigint;
-       struct event                     ps_evsigterm;
-       struct event                     ps_evsigchld;
-       struct event                     ps_evsighup;
-       struct event                     ps_evsigpipe;
-       struct event                     ps_evsigusr1;
-
-       void                            *ps_env;
-};
-
-struct privsep_proc {
-       const char              *p_title;
-       enum privsep_procid      p_id;
-       int                     (*p_cb)(int, struct privsep_proc *,
-                                   struct imsg *);
-       void                    (*p_init)(struct privsep *,
-                                   struct privsep_proc *);
-       const char              *p_chroot;
-       struct privsep          *p_ps;
-       void                    (*p_shutdown)(void);
-       struct passwd           *p_pw;
-};
-
-struct privsep_fd {
-       enum privsep_procid              pf_procid;
-       unsigned int                     pf_instance;
-};
-
-struct imsgev {
-       struct imsgbuf           ibuf;
-       void                    (*handler)(int, short, void *);
-       struct event             ev;
-       struct privsep_proc     *proc;
-       void                    *data;
-       short                    events;
-       const char              *name;
-};
-
-#ifndef IMSG_DATA_SIZE
-#define        IMSG_DATA_SIZE(_imsg)   ((_imsg)->hdr.len - IMSG_HEADER_SIZE)
-#endif
-
-#ifndef IMSG_SIZE_CHECK
-#define        IMSG_SIZE_CHECK(_imsg, _type)                           \
-       do {                                                    \
-               if (IMSG_DATA_SIZE(_imsg) < sizeof(*(_type)))   \
-                       fatal("received imsg size was wrong."); \
-       } while (0 /* CONSTCOND */)
-#endif
-
-#if DEBUG
-#define DPRINTF                log_debug
-#else
-#define DPRINTF(x...)  do {} while(0)
-#endif
-
-#define PROC_PARENT_SOCK_FILENO 3
-#define PROC_MAX_INSTANCES      32
-
-struct ctl_conn {
-       TAILQ_ENTRY(ctl_conn)            entry;
-       uint8_t                          flags;
-#define CTL_CONN_NOTIFY                         0x01
-       struct imsgev                    iev;
-       int                              restricted;
-};
-TAILQ_HEAD(ctl_connlist, ctl_conn);
-
-/* proc.c */
-void    proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
-           int, char **, enum privsep_procid);
-void    proc_kill(struct privsep *);
-void    proc_connect(struct privsep *ps);
-void    proc_dispatch(int, short event, void *);
-void    proc_run(struct privsep *, struct privsep_proc *,
-           struct privsep_proc *, unsigned int,
-           void (*)(struct privsep *, struct privsep_proc *, void *), void *);
-void    imsg_event_add(struct imsgev *);
-int     imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
-           pid_t, int, void *, uint16_t);
-int     imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
-           pid_t, int, const struct iovec *, int);
-int     proc_compose_imsg(struct privsep *, enum privsep_procid, int,
-           uint16_t, uint32_t, int, void *, uint16_t);
-int     proc_compose(struct privsep *, enum privsep_procid,
-           uint16_t, void *data, uint16_t);
-int     proc_composev_imsg(struct privsep *, enum privsep_procid, int,
-           uint16_t, uint32_t, int, const struct iovec *, int);
-int     proc_composev(struct privsep *, enum privsep_procid,
-           uint16_t, const struct iovec *, int);
-int     proc_forward_imsg(struct privsep *, struct imsg *,
-           enum privsep_procid, int);
-struct imsgbuf *
-        proc_ibuf(struct privsep *, enum privsep_procid, int);
-struct imsgev *
-        proc_iev(struct privsep *, enum privsep_procid, int);
-enum privsep_procid
-        proc_getid(struct privsep_proc *, unsigned int, const char *);
-int     proc_flush_imsg(struct privsep *, enum privsep_procid, int);
-
-/* control.c */
-int     control_init(struct privsep *, struct control_sock *);
-int     control_listen(struct control_sock *);
-struct ctl_conn
-       *control_connbyfd(int);
-void    control(struct privsep *, struct privsep_proc *);
-
-/* log.c */
-void   log_init(int, int);
-void   log_procinit(const char *);
-void   log_setverbose(int);
-int    log_getverbose(void);
-void   log_warn(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_warnx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_info(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_debug(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   logit(int, const char *, ...)
-           __attribute__((__format__ (printf, 2, 3)));
-void   vlog(int, const char *, va_list)
-           __attribute__((__format__ (printf, 2, 0)));
-__dead void fatal(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-__dead void fatalx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-
-void    socket_set_blockmode(int, enum blockmodes);
-
-#endif /* _PROC_H */
diff --git a/usr.sbin/switchd/switch.c b/usr.sbin/switchd/switch.c
deleted file mode 100644 (file)
index 285add7..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*     $OpenBSD: switch.c,v 1.3 2016/09/18 13:17:40 rzalamena Exp $    */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <imsg.h>
-#include <event.h>
-
-#include "switchd.h"
-
-void    switch_timer(struct switchd *, void *);
-
-static __inline int
-        switch_cmp(struct switch_control *, struct switch_control *);
-static __inline int
-        switch_maccmp(struct macaddr *, struct macaddr *);
-
-void
-switch_init(struct switchd *sc)
-{
-       RB_INIT(&sc->sc_switches);
-}
-
-int
-switch_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       struct privsep          *ps = p->p_ps;
-       struct switchd          *sc = ps->ps_env;
-       struct switch_control   *sw;
-       struct macaddr          *mac;
-       struct iovec             iov[2];
-
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_SUM:
-               IMSG_SIZE_CHECK(imsg, &fd);
-
-               RB_FOREACH(sw, switch_head, &sc->sc_switches) {
-                       iov[0].iov_base = imsg->data;
-                       iov[0].iov_len = IMSG_DATA_SIZE(imsg);
-                       iov[1].iov_base = sw;
-                       iov[1].iov_len = sizeof(*sw);
-
-                       proc_composev(ps, PROC_CONTROL,
-                           IMSG_CTL_SWITCH, iov, 2);
-
-                       RB_FOREACH(mac, macaddr_head, &sw->sw_addrcache) {
-                               iov[0].iov_base = imsg->data;
-                               iov[0].iov_len = IMSG_DATA_SIZE(imsg);
-                               iov[1].iov_base = mac;
-                               iov[1].iov_len = sizeof(*mac);
-
-                               proc_composev(ps, PROC_CONTROL,
-                                   IMSG_CTL_MAC, iov, 2);
-                       }
-               }
-
-               proc_compose(ps, PROC_CONTROL,
-                   IMSG_CTL_END, imsg->data, IMSG_DATA_SIZE(imsg));
-               return (0);
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-struct switch_control *
-switch_get(struct switch_connection *con)
-{
-       struct switchd          *sc = con->con_sc;
-       struct switch_control    key;
-
-       memcpy(&key.sw_addr, &con->con_peer, sizeof(key.sw_addr));
-
-       con->con_switch = RB_FIND(switch_head, &sc->sc_switches, &key);
-       return (con->con_switch);
-}
-
-struct switch_control *
-switch_add(struct switch_connection *con)
-{
-       struct switchd          *sc = con->con_sc;
-       struct switch_control   *sw, *oldsw;
-       static unsigned int      id = 0;
-
-       /* Connection already has an associated switch */
-       if (con->con_switch != NULL)
-               return (NULL);
-
-       if ((sw = calloc(1, sizeof(*sw))) == NULL)
-               return (NULL);
-
-       memcpy(&sw->sw_addr, &con->con_peer, sizeof(sw->sw_addr));
-       sw->sw_id = ++id;
-       RB_INIT(&sw->sw_addrcache);
-
-       if ((oldsw =
-           RB_INSERT(switch_head, &sc->sc_switches, sw)) != NULL) {
-               free(sw);
-               sw = oldsw;
-       } else {
-               timer_set(sc, &sw->sw_timer, switch_timer, sw);
-               timer_add(sc, &sw->sw_timer, sc->sc_cache_timeout);
-       }
-
-       con->con_switch = sw;
-       return (con->con_switch);
-}
-
-void
-switch_timer(struct switchd *sc, void *arg)
-{
-       struct switch_control   *sw = arg;
-       struct macaddr          *mac, *next;
-       struct timeval           tv;
-       unsigned int             cnt = 0;
-
-       getmonotime(&tv);
-
-       for (mac = RB_MIN(macaddr_head, &sw->sw_addrcache);
-           mac != NULL; mac = next) {
-               next = RB_NEXT(macaddr_head, &sw->sw_addrcache, mac);
-
-               /* Simple monotonic timeout */
-               if ((tv.tv_sec - mac->mac_age) >= sc->sc_cache_timeout) {
-                       RB_REMOVE(macaddr_head, &sw->sw_addrcache, mac);
-                       sw->sw_cachesize--;
-                       free(mac);
-                       cnt++;
-               }
-       }
-       if (cnt)
-               log_debug("%s: flushed %d mac from switch %u after timeout",
-                   __func__, cnt, sw->sw_id);
-
-       timer_add(sc, &sw->sw_timer, sc->sc_cache_timeout);
-}
-
-void
-switch_remove(struct switchd *sc, struct switch_control *sw)
-{
-       struct macaddr  *mac, *next;
-
-       if (sw == NULL)
-               return;
-
-       timer_del(sc, &sw->sw_timer);
-
-       for (mac = RB_MIN(macaddr_head, &sw->sw_addrcache);
-           mac != NULL; mac = next) {
-               next = RB_NEXT(macaddr_head, &sw->sw_addrcache, mac);
-               RB_REMOVE(macaddr_head, &sw->sw_addrcache, mac);
-               sw->sw_cachesize--;
-               free(mac);
-       }
-       RB_REMOVE(switch_head, &sc->sc_switches, sw);
-
-       log_debug("%s: switch %u removed", __func__, sw->sw_id);
-
-       free(sw);
-}
-
-struct macaddr *
-switch_learn(struct switchd *sc, struct switch_control *sw,
-    uint8_t *ea, uint32_t port)
-{
-       struct macaddr  *mac, *oldmac = NULL;
-       struct timeval   tv;
-
-       if ((mac = oldmac = switch_cached(sw, ea)) != NULL)
-               goto update;
-
-       if (sw->sw_cachesize >= sc->sc_cache_max)
-               return (NULL);
-
-       if ((mac = calloc(1, sizeof(*mac))) == NULL)
-               return (NULL);
-
-       memcpy(&mac->mac_addr, ea, sizeof(mac->mac_addr));
-
-       if (RB_INSERT(macaddr_head, &sw->sw_addrcache, mac) != NULL)
-               fatalx("cache corrupted");
-       sw->sw_cachesize++;
-
- update:
-       getmonotime(&tv);
-       mac->mac_port = port;
-       mac->mac_age = tv.tv_sec;
-
-       log_debug("%s: %s mac %s on switch %u port %u",
-           __func__, oldmac == NULL ? "learned new" : "updated",
-           print_ether(ea), sw->sw_id, port);
-
-       return (mac);
-}
-
-struct macaddr *
-switch_cached(struct switch_control *sw, uint8_t *ea)
-{
-       struct macaddr   key;
-       memcpy(&key.mac_addr, ea, sizeof(key.mac_addr));
-       return (RB_FIND(macaddr_head, &sw->sw_addrcache, &key));
-}
-
-static __inline int
-switch_cmp(struct switch_control *a, struct switch_control *b)
-{
-       int             diff = 0;
-
-       diff = sockaddr_cmp((struct sockaddr *)&a->sw_addr,
-           (struct sockaddr *)&b->sw_addr, 128);
-       if (!diff)
-               diff = socket_getport(&a->sw_addr) -
-                   socket_getport(&b->sw_addr);
-
-       return (diff);
-}
-
-static __inline int
-switch_maccmp(struct macaddr *a, struct macaddr *b)
-{
-       return (memcmp(a->mac_addr, b->mac_addr, sizeof(a->mac_addr)));
-}
-
-RB_GENERATE(switch_head, switch_control, sw_entry, switch_cmp);
-RB_GENERATE(macaddr_head, macaddr, mac_entry, switch_maccmp);
diff --git a/usr.sbin/switchd/switchd.8 b/usr.sbin/switchd/switchd.8
deleted file mode 100644 (file)
index c94ce86..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-.\" $OpenBSD: switchd.8,v 1.4 2016/11/29 07:18:23 jmc Exp $
-.\"
-.\" Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: November 29 2016 $
-.Dt SWITCHD 8
-.Os
-.Sh NAME
-.Nm switchd
-.Nd software-defined networking (SDN) sflow controller
-.Sh SYNOPSIS
-.Nm switchd
-.Op Fl dnv
-.Op Fl c Ar cachesize
-.Op Fl D Ar macro Ns = Ns Ar value
-.Op Fl f Ar file
-.Op Fl t Ar timeout
-.Sh DESCRIPTION
-.Nm
-is a controller for software-defined networking (SDN) and is
-compatible with the OpenFlow protocol.
-.Pp
-The options are as follows:
-.Bl -tag -width "-c cachesize"
-.It Fl c Ar cachesize
-Number of MAC addresses to cache.
-The default is 4096.
-.It Fl D Ar macro Ns = Ns Ar value
-Set a
-.Ar macro
-to a
-.Ar value .
-Macros can be referenced in the configuration files.
-.It Fl d
-Debug mode.
-Don't detach or become a daemon.
-This allows for easy monitoring of
-.Nm .
-.It Fl f Ar file
-Specifies the configuration file.
-The default is
-.Pa /etc/switchd.conf .
-.It Fl n
-Check that the configuration is valid, but don't start the daemon.
-.It Fl t Ar timeout
-Timeout in seconds for learned MAC addresses.
-The default is 240 seconds.
-.It Fl v
-Verbose mode.
-Multiple
-.Fl v
-options increase the verbosity.
-.El
-.Sh FILES
-.Bl -tag -width "/etc/switchd.conf" -compact
-.It Pa /etc/switchd.conf
-Default configuration file.
-.El
-.Sh SEE ALSO
-.Xr switchd.conf 5 ,
-.Xr switchctl 8
-.Sh STANDARDS
-.Rs
-.%A Open Networking Foundation (ONF)
-.%D December 31, 2009
-.%R Version 1.0.0 (Wire Protocol 0x01)
-.%T OpenFlow Switch Specification
-.Re
-.Pp
-.Rs
-.%A Open Networking Foundation (ONF)
-.%D March 26, 2015
-.%R Version 1.3.5 (Protocol version 0x04)
-.%T OpenFlow Switch Specification
-.Re
-.Sh HISTORY
-The
-.Nm
-program first appeared in
-.Ox 6.1 .
-.Sh AUTHORS
-The
-.Nm
-program was written by
-.An Reyk Floeter Aq Mt reyk@openbsd.org .
diff --git a/usr.sbin/switchd/switchd.c b/usr.sbin/switchd/switchd.c
deleted file mode 100644 (file)
index f1410c3..0000000
+++ /dev/null
@@ -1,617 +0,0 @@
-/*     $OpenBSD: switchd.c,v 1.20 2021/09/06 13:32:18 deraadt Exp $    */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/queue.h>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <syslog.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pwd.h>
-#include <event.h>
-
-#include "switchd.h"
-
-void    parent_shutdown(struct switchd *);
-void    parent_sig_handler(int, short, void *);
-int     parent_dispatch_ofp(int, struct privsep_proc *, struct imsg *);
-int     parent_dispatch_control(int, struct privsep_proc *, struct imsg *);
-int     parent_configure(struct switchd *);
-int     parent_reload(struct switchd *);
-void    parent_connect(struct privsep *, struct switch_client *);
-void    parent_connected(int, short, void *);
-void    parent_disconnect(struct privsep *, struct switch_client *);
-
-__dead void    usage(void);
-
-static struct privsep_proc procs[] = {
-       { "ofp",        PROC_OFP,       NULL, ofp },
-       { "control",    PROC_CONTROL,   parent_dispatch_control, control },
-       { "ofcconn",    PROC_OFCCONN,   NULL, ofcconn }
-};
-
-enum privsep_procid privsep_process;
-
-__dead void
-usage(void)
-{
-       extern const char       *__progname;
-       fprintf(stderr, "usage: %s [-dnv] [-c cachesize] [-D macro=value] "
-           "[-f file] [-t timeout]\n",
-           __progname);
-       exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
-       struct switchd          *sc = NULL;
-       struct privsep          *ps = NULL;
-       struct switch_server    *srv;
-       const char              *errstr = NULL;
-       int                      c;
-       int                      debug = 0, verbose = 0;
-       uint32_t                 opts = 0;
-       unsigned int             cache = SWITCHD_CACHE_MAX;
-       unsigned int             timeout = SWITCHD_CACHE_TIMEOUT;
-       const char              *conffile = SWITCHD_CONFIG;
-       const char              *errp, *title = NULL;
-       enum privsep_procid      proc_id = PROC_PARENT;
-       int                      argc0 = argc, proc_instance = 0;
-
-       log_init(1, LOG_DAEMON);
-
-       while ((c = getopt(argc, argv, "c:dD:f:hI:nP:t:v")) != -1) {
-               switch (c) {
-               case 'c':
-                       cache = strtonum(optarg, 1, UINT32_MAX, &errstr);
-                       if (errstr != NULL) {
-                               log_warn("max cache size: %s", errstr);
-                               usage();
-                       }
-                       break;
-               case 'd':
-                       debug++;
-                       break;
-               case 'D':
-                       if (cmdline_symset(optarg) < 0)
-                               log_warnx("could not parse macro definition %s",
-                                   optarg);
-                       break;
-               case 'f':
-                       conffile = optarg;
-                       break;
-               case 'I':
-                       proc_instance = strtonum(optarg, 0,
-                           PROC_MAX_INSTANCES, &errp);
-                       if (errp)
-                               fatalx("invalid process instance");
-                       break;
-               case 'n':
-                       opts |= SWITCHD_OPT_NOACTION;
-                       break;
-               case 'P':
-                       title = optarg;
-                       proc_id = proc_getid(procs, nitems(procs), title);
-                       if (proc_id == PROC_MAX)
-                               fatalx("invalid process name");
-                       break;
-               case 't':
-                       timeout = strtonum(optarg, 0, UINT32_MAX, &errstr);
-                       if (errstr != NULL) {
-                               log_warn("cache timeout: %s", errstr);
-                               usage();
-                       }
-                       break;
-               case 'v':
-                       verbose++;
-                       opts |= SWITCHD_OPT_VERBOSE;
-                       break;
-               default:
-                       usage();
-               }
-       }
-
-       if ((sc = calloc(1, sizeof(*sc))) == NULL)
-               fatal("calloc");
-
-       if (strlcpy(sc->sc_conffile, conffile, PATH_MAX) >= PATH_MAX)
-               fatal("config file exceeds PATH_MAX");
-
-       sc->sc_cache_max = cache;
-       sc->sc_cache_timeout = timeout;
-       sc->sc_opts = opts;
-
-       srv = &sc->sc_server;
-       srv->srv_sc = sc;
-
-       ps = &sc->sc_ps;
-       ps->ps_env = sc;
-       TAILQ_INIT(&ps->ps_rcsocks);
-       TAILQ_INIT(&sc->sc_clients);
-
-       if (parse_config(sc->sc_conffile, sc) == -1) {
-               proc_kill(&sc->sc_ps);
-               exit(1);
-       }
-
-       if (opts & SWITCHD_OPT_NOACTION) {
-               fprintf(stderr, "configuration OK\n");
-               proc_kill(&sc->sc_ps);
-               exit(0);
-       }
-
-       /* check for root privileges */
-       if (geteuid())
-               fatalx("need root privileges");
-
-       if ((ps->ps_pw =  getpwnam(SWITCHD_USER)) == NULL)
-               fatalx("unknown user " SWITCHD_USER);
-
-       log_init(debug, LOG_DAEMON);
-       log_setverbose(verbose);
-
-       /* Configure the control socket */
-       ps->ps_csock.cs_name = SWITCHD_SOCKET;
-       ps->ps_instance = proc_instance;
-       if (title)
-               ps->ps_title[proc_id] = title;
-
-       /* Only the parent returns. */
-       proc_init(ps, procs, nitems(procs), debug, argc0, argv, proc_id);
-
-       if (!debug && daemon(0, 0) == -1)
-               fatal("failed to daemonize");
-
-       log_procinit("parent");
-
-       if (unveil("/", "r") == -1)
-               fatal("unveil /");
-       if (unveil("/dev", "rw") == -1)
-               fatal("unveil");
-       /*
-        * pledge in the parent process:
-        * stdio - for malloc and basic I/O including events.
-        * rpath - for reload to open and read the configuration files.
-        * wpath - for accessing the /dev/switch device.
-        * inet - for opening OpenFlow and device sockets.
-        * dns - for resolving host in the configuration files.
-        * sendfd - send sockets to child processes on reload.
-        */
-       if (pledge("stdio rpath wpath inet dns sendfd", NULL) == -1)
-               fatal("pledge");
-
-       event_init();
-
-       signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps);
-       signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps);
-       signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps);
-       signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps);
-       signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps);
-
-       signal_add(&ps->ps_evsigint, NULL);
-       signal_add(&ps->ps_evsigterm, NULL);
-       signal_add(&ps->ps_evsighup, NULL);
-       signal_add(&ps->ps_evsigpipe, NULL);
-       signal_add(&ps->ps_evsigusr1, NULL);
-
-       proc_connect(ps);
-
-       if (parent_configure(sc) == -1)
-               fatalx("configuration failed");
-
-       event_dispatch();
-
-       log_debug("%d parent exiting", getpid());
-
-       return (0);
-}
-
-int
-switchd_socket(struct sockaddr *sock, int reuseport)
-{
-       int s = -1, val;
-       struct linger lng;
-
-       if ((s = socket(sock->sa_family, SOCK_STREAM | SOCK_NONBLOCK,
-           IPPROTO_TCP)) == -1)
-               goto bad;
-
-       /*
-        * Socket options
-        */
-       bzero(&lng, sizeof(lng));
-       if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
-               goto bad;
-       if (reuseport) {
-               val = 1;
-               if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
-                   sizeof(int)) == -1)
-                       goto bad;
-       }
-
-       /*
-        * TCP options
-        */
-       val = 1;
-       if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
-           &val, sizeof(val)) == -1)
-               goto bad;
-
-       return (s);
-
- bad:
-       if (s != -1)
-               close(s);
-       return (-1);
-}
-
-int
-switchd_listen(struct sockaddr *sock)
-{
-       int s;
-
-       if ((s = switchd_socket(sock, 1)) == -1)
-               return (-1);
-
-       if (bind(s, sock, sock->sa_len) == -1)
-               goto bad;
-       if (listen(s, 10) == -1)
-               goto bad;
-
-       return (s);
-
- bad:
-       close(s);
-       return (-1);
-}
-
-int
-switchd_tap(void)
-{
-       char     path[PATH_MAX];
-       int      i, fd;
-
-       for (i = 0; i < SWITCHD_MAX_TAP; i++) {
-               snprintf(path, PATH_MAX, "/dev/tap%d", i);
-               fd = open(path, O_RDWR | O_NONBLOCK);
-               if (fd != -1)
-                       return (fd);
-       }
-
-       return (-1);
-}
-
-struct switch_connection *
-switchd_connbyid(struct switchd *sc, unsigned int id, unsigned int instance)
-{
-       struct switch_connection        *con;
-
-       TAILQ_FOREACH(con, &sc->sc_conns, con_entry) {
-               if (con->con_id == id && con->con_instance == instance)
-                       return (con);
-       }
-
-       return (NULL);
-}
-
-struct switch_connection *
-switchd_connbyaddr(struct switchd *sc, struct sockaddr *sa)
-{
-       struct switch_connection        *con;
-
-       TAILQ_FOREACH(con, &sc->sc_conns, con_entry) {
-               if (sockaddr_cmp((struct sockaddr *)
-                   &con->con_peer, sa, -1) == 0)
-                       return (con);
-       }
-
-       return (NULL);
-}
-
-void
-parent_sig_handler(int sig, short event, void *arg)
-{
-       struct privsep  *ps = arg;
-
-       switch (sig) {
-       case SIGHUP:
-               log_info("%s: reload requested with SIGHUP", __func__);
-
-               /*
-                * This is safe because libevent uses async signal handlers
-                * that run in the event loop and not in signal context.
-                */
-               parent_reload(ps->ps_env);
-               break;
-       case SIGPIPE:
-               log_info("%s: ignoring SIGPIPE", __func__);
-               break;
-       case SIGUSR1:
-               log_info("%s: ignoring SIGUSR1", __func__);
-               break;
-       case SIGTERM:
-       case SIGINT:
-               parent_shutdown(ps->ps_env);
-               break;
-       default:
-               fatalx("unexpected signal");
-       }
-}
-
-int
-parent_configure(struct switchd *sc)
-{
-       struct switch_client    *swc, *swcn;
-       int                      fd;
-
-       if ((fd = switchd_tap()) == -1)
-               fatal("%s: tap", __func__);
-       proc_compose_imsg(&sc->sc_ps, PROC_OFP, -1,
-           IMSG_TAPFD, -1, fd, NULL, 0);
-
-       TAILQ_FOREACH_SAFE(swc, &sc->sc_clients, swc_next, swcn) {
-               parent_connect(&sc->sc_ps, swc);
-       }
-
-       return (0);
-}
-
-int
-parent_reload(struct switchd *sc)
-{
-       struct switchd                   newconf;
-       struct switch_client            *swc, *oswc, *swcn;
-
-       memset(&newconf, 0, sizeof(newconf));
-       TAILQ_INIT(&newconf.sc_clients);
-       TAILQ_INIT(&newconf.sc_conns);
-
-       if (parse_config(sc->sc_conffile, &newconf) != -1) {
-               TAILQ_FOREACH_SAFE(swc, &sc->sc_clients, swc_next, swcn) {
-                       TAILQ_FOREACH(oswc, &newconf.sc_clients, swc_next) {
-                               if (sockaddr_cmp((struct sockaddr *)
-                                   &oswc->swc_addr.swa_addr,
-                                   (struct sockaddr *)
-                                   &swc->swc_addr.swa_addr, -1) == 0) {
-                                       TAILQ_REMOVE(&newconf.sc_clients,
-                                           oswc, swc_next);
-                                       break;
-                               }
-                       }
-                       if (oswc == NULL) {
-                               /* Removed */
-                               parent_disconnect(&sc->sc_ps, swc);
-                       } else {
-                               /* Keep the existing one */
-                               TAILQ_REMOVE(&newconf.sc_clients,
-                                   oswc, swc_next);
-                               free(oswc);
-                       }
-               }
-               TAILQ_FOREACH_SAFE(swc, &newconf.sc_clients, swc_next, swcn) {
-                       TAILQ_REMOVE(&newconf.sc_clients, swc, swc_next);
-                       TAILQ_INSERT_TAIL(&sc->sc_clients, swc, swc_next);
-
-                       parent_connect(&sc->sc_ps, swc);
-               }
-       }
-
-       return (0);
-}
-
-int
-parent_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-       struct switch_client    *swc, *oswc;
-       struct privsep          *ps = p->p_ps;
-       struct switchd          *sc = ps->ps_env;
-
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_CONNECT:
-       case IMSG_CTL_DISCONNECT:
-               IMSG_SIZE_CHECK(imsg, swc);
-
-               /* Need to allocate it in case it is reused */
-               if ((swc = calloc(1, sizeof(*swc))) == NULL) {
-                       log_warnx("%s: calloc", __func__);
-                       return (0);
-               }
-               memcpy(swc, imsg->data, sizeof(*swc));
-               memset(&swc->swc_ev, 0, sizeof(swc->swc_ev));
-
-               if (imsg->hdr.type == IMSG_CTL_CONNECT) {
-                       TAILQ_INSERT_TAIL(&sc->sc_clients, swc, swc_next);
-                       parent_connect(p->p_ps, swc);
-               } else {
-                       TAILQ_FOREACH(oswc, &sc->sc_clients, swc_next) {
-                               if (sockaddr_cmp((struct sockaddr *)
-                                   &oswc->swc_addr.swa_addr,
-                                   (struct sockaddr *)
-                                   &swc->swc_addr.swa_addr, -1) == 0) {
-                                       parent_disconnect(ps, oswc);
-                                       break;
-                               }
-                       }
-                       if (oswc == NULL)
-                               log_warnx("client %s is not connected",
-                                   print_host(&swc->swc_addr.swa_addr,
-                                   NULL, 0));
-                       free(swc);
-               }
-               return (0);
-       default:
-               break;
-       }
-
-       return (-1);
-}
-
-void
-parent_shutdown(struct switchd *sc)
-{
-       proc_kill(&sc->sc_ps);
-
-       free(sc);
-
-       log_warnx("parent terminating");
-       exit(0);
-}
-
-void
-parent_connect(struct privsep *ps, struct switch_client *swc)
-{
-       struct switchd          *sc = ps->ps_env;
-       struct sockaddr_storage *ss;
-       struct sockaddr_un      *un;
-       struct sockaddr_in      *sin4;
-       struct sockaddr_in6     *sin6;
-       int                      fd = -1;
-       struct timeval           tv;
-
-       ss = &swc->swc_addr.swa_addr;
-
-       if (ss->ss_len == 0) {
-               log_warnx("%s: invalid address", __func__);
-               goto fail;
-       }
-       swc->swc_arg = ps;
-       memset(&swc->swc_ev, 0, sizeof(swc->swc_ev));
-
-       switch (ss->ss_family) {
-       case AF_LOCAL:
-               un = (struct sockaddr_un *)ss;
-
-               /* restrict the opening path to /dev/switch* */
-               if (strncmp(un->sun_path, "/dev/switch",
-                   strlen("/dev/switch")) != 0) {
-                       log_warnx("%s: device path is wrong: %s", __func__,
-                           un->sun_path);
-                       goto fail;
-               }
-
-               if ((fd = open(un->sun_path, O_RDWR | O_NONBLOCK)) == -1) {
-                       log_warn("%s: failed to open %s",
-                           __func__, un->sun_path);
-                       goto fail;
-               }
-               break;
-       case AF_INET:
-       case AF_INET6:
-               if (ss->ss_family == AF_INET) {
-                       sin4 = (struct sockaddr_in *)ss;
-                       if (sin4->sin_port == 0)
-                               sin4->sin_port = htons(SWITCHD_CTLR_PORT);
-               } else if (ss->ss_family == AF_INET6) {
-                       sin6 = (struct sockaddr_in6 *)ss;
-                       if (sin6->sin6_port == 0)
-                               sin6->sin6_port = htons(SWITCHD_CTLR_PORT);
-               }
-
-               if ((fd = switchd_socket((struct sockaddr *)ss, 0)) == -1) {
-                       log_debug("%s: failed to get socket for %s", __func__,
-                           print_host(ss, NULL, 0));
-                       goto fail;
-               }
-
- retry:
-               if (connect(fd, (struct sockaddr *)ss, ss->ss_len) == -1) {
-                       if (errno == EINTR)
-                               goto retry;
-                       if (errno == EINPROGRESS) {
-                               tv.tv_sec = SWITCHD_CONNECT_TIMEOUT;
-                               tv.tv_usec = 0;
-                               event_set(&swc->swc_ev, fd, EV_WRITE|EV_TIMEOUT,
-                                   parent_connected, swc);
-                               event_add(&swc->swc_ev, &tv);
-                               return;
-                       }
-
-                       log_warn("%s: failed to connect to %s, fd %d", __func__,
-                           print_host(ss, NULL, 0), fd);
-                       goto fail;
-               }
-
-               break;
-       }
-
-       parent_connected(fd, 0, swc);
-       return;
-
- fail:
-       TAILQ_REMOVE(&sc->sc_clients, swc, swc_next);
-       free(swc);
-}
-
-void
-parent_connected(int fd, short event, void *arg)
-{
-       struct switch_client    *swc = arg;
-       struct privsep          *ps = swc->swc_arg;
-       struct switchd          *sc = ps->ps_env;
-
-       if (event & EV_TIMEOUT) {
-               log_debug("%s: failed to connect to %s", __func__,
-                   print_host(&swc->swc_addr.swa_addr, NULL, 0));
-               TAILQ_REMOVE(&sc->sc_clients, swc, swc_next);
-               free(swc);
-               return;
-       }
-
-       switch (swc->swc_target.swa_type) {
-       case SWITCH_CONN_LOCAL:
-               proc_compose_imsg(ps, PROC_OFP, -1, IMSG_CTL_CONNECT,
-                   -1, fd, swc, sizeof(*swc));
-               break;
-       case SWITCH_CONN_TLS:
-       case SWITCH_CONN_TCP:
-               proc_compose_imsg(ps, PROC_OFCCONN, -1, IMSG_CTL_CONNECT,
-                   -1, fd, swc, sizeof(*swc));
-               break;
-       default:
-               fatalx("not implemented");
-       }
-}
-
-void
-parent_disconnect(struct privsep *ps, struct switch_client *swc)
-{
-       struct switchd          *sc = ps->ps_env;
-       enum privsep_procid      target;
-
-       TAILQ_REMOVE(&sc->sc_clients, swc, swc_next);
-
-       target = swc->swc_target.swa_type == SWITCH_CONN_LOCAL ?
-           PROC_OFP : PROC_OFCCONN;
-       proc_compose(ps, target, IMSG_CTL_DISCONNECT, swc, sizeof(*swc));
-
-       free(swc);
-}
diff --git a/usr.sbin/switchd/switchd.conf.5 b/usr.sbin/switchd/switchd.conf.5
deleted file mode 100644 (file)
index dcf7467..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-.\"    $OpenBSD: switchd.conf.5,v 1.10 2019/07/11 09:28:54 sthen Exp $
-.\"
-.\" Copyright (c) 2014, 2015, 2016 Reyk Floeter <reyk@openbsd.org>
-.\" Copyright (c) 2016 YASUOKA Masahiko <yasuoka@openbsd.org>
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.\" The following requests are required for all man pages.
-.\"
-.Dd $Mdocdate: July 11 2019 $
-.Dt SWITCHD.CONF 5
-.Os
-.Sh NAME
-.Nm switchd.conf
-.Nd switch daemon configuration file
-.Sh DESCRIPTION
-.Nm
-is the configuration file for the switch daemon,
-.Xr switchd 8 .
-.Pp
-.Nm
-files is divided into the following main sections:
-.Bl -tag -width xxxx
-.It Sy Macros
-User-defined variables may be defined and used later, simplifying the
-configuration file.
-.It Sy Global Configuration
-Global runtime settings for
-.Xr switchd 8 .
-.El
-.Pp
-The current line can be extended over multiple lines using a backslash
-.Pq Sq \e .
-Comments can be put anywhere in the file using a hash mark
-.Pq Sq # ,
-and extend to the end of the current line.
-Care should be taken when commenting out multi-line text:
-the comment is effective until the end of the entire block.
-.Pp
-Argument names not beginning with a letter, digit, or underscore
-must be quoted.
-.Pp
-Additional configuration files can be included with the
-.Ic include
-keyword, for example:
-.Bd -literal -offset indent
-include "/etc/switchd.conf.local"
-.Ed
-.Sh MACROS
-Macros can be defined that will later be expanded in context.
-Macro names must start with a letter, digit, or underscore,
-and may contain any of those characters.
-Macro names may not be reserved words (for example,
-.Ic directory ,
-.Ic log ,
-or
-.Ic root ) .
-Macros are not expanded inside quotes.
-.Pp
-For example:
-.Bd -literal -offset indent
-ext_ip="10.0.0.1"
-listen on $ext_ip
-.Ed
-.Sh GLOBAL CONFIGURATION
-The following options can be set globally:
-.Bl -tag -width Ds
-.It Ic listen on Ar address Oo Ic tls Oc Op Ic port Ar port
-Set the listen address and port to accept connections from remote
-OpenFlow switches.
-Secure connections can be enabled with the optional
-.Ic tls
-keyword.
-By default,
-.Xr switchd 8
-uses port 6653 and listen address 0.0.0.0.
-.\".It Ic device on Ar device-name Oo Ic forward to Ar uri Oc
-.\"Attach to a
-.\".Xr switch 4
-.\"device.
-.\"When attached,
-.\".Xr switchd 8
-.\"will accept OpenFlow messages from the connected kernel interface.
-.\"The daemon either handles the requests locally or sends them to a remote
-.\"controller if the
-.\".Ic forward to
-.\"directive is set.
-.\"The
-.\".Ar uri
-.\"is the method and address to connect to the remote controller,
-.\"with the format
-.\".Ar protocol:address:port
-.\"where the
-.\".Ar protocol
-.\"can be either
-.\".Dq tcp
-.\"or
-.\".Dq tls .
-.El
-.Sh EXAMPLES
-The following example is a typical one.
-.Bd -literal -offset indent
-listen on 0.0.0.0 port 6653
-.\"device "/dev/switch0"
-.\"device "/dev/switch1" forward to tcp:192.168.0.1:6653
-.Ed
-.Sh SEE ALSO
-.Xr switchctl 8 ,
-.Xr switchd 8
diff --git a/usr.sbin/switchd/switchd.h b/usr.sbin/switchd/switchd.h
deleted file mode 100644 (file)
index 9dfa9d0..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/*     $OpenBSD: switchd.h,v 1.30 2019/11/21 06:22:57 akoshibe Exp $   */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef SWITCHD_H
-#define SWITCHD_H
-
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/uio.h>
-
-#include <net/ofp.h>
-
-#include <limits.h>
-#include <imsg.h>
-
-#include "ofp10.h"
-#include "types.h"
-#include "proc.h"
-#include "ofp_map.h"
-
-struct switchd;
-
-struct timer {
-       struct event     tmr_ev;
-       struct switchd  *tmr_sc;
-       void            (*tmr_cb)(struct switchd *, void *);
-       void            *tmr_cbarg;
-};
-
-struct packet {
-       union {
-               struct ether_header     *pkt_eh;
-               uint8_t                 *pkt_buf;
-       };
-       size_t                           pkt_len;
-};
-
-struct macaddr {
-       uint8_t                  mac_addr[ETHER_ADDR_LEN];
-       uint32_t                         mac_port;
-       time_t                   mac_age;
-       RB_ENTRY(macaddr)        mac_entry;
-};
-RB_HEAD(macaddr_head, macaddr);
-
-struct switch_control {
-       unsigned int             sw_id;
-       struct sockaddr_storage  sw_addr;
-       struct macaddr_head      sw_addrcache;
-       struct timer             sw_timer;
-       unsigned int             sw_cachesize;
-       RB_ENTRY(switch_control) sw_entry;
-};
-RB_HEAD(switch_head, switch_control);
-
-struct switch_table {
-       TAILQ_ENTRY(switch_table)        st_entry;
-
-       int                              st_table;
-       unsigned int                     st_entries;
-       unsigned int                     st_maxentries;
-
-       uint32_t                         st_actions;
-       uint32_t                         st_actionsmiss;
-
-       uint32_t                         st_instructions;
-       uint32_t                         st_instructionsmiss;
-
-       uint64_t                         st_setfield;
-       uint64_t                         st_setfieldmiss;
-       uint64_t                         st_match;
-       uint64_t                         st_wildcard;
-
-       /* Maximum of 256 tables (64 * 4). */
-       uint64_t                         st_nexttable[4];
-       uint64_t                         st_nexttablemiss[4];
-};
-TAILQ_HEAD(switch_table_list, switch_table);
-
-struct multipart_message {
-       SLIST_ENTRY(multipart_message)
-                                mm_entry;
-
-       uint32_t                 mm_xid;
-       uint8_t                  mm_type;
-};
-SLIST_HEAD(multipart_list, multipart_message);
-
-struct switch_address {
-       enum switch_conn_type    swa_type;
-       struct sockaddr_storage  swa_addr;
-};
-
-struct switch_connection {
-       unsigned int             con_id;
-       unsigned int             con_instance;
-
-       int                      con_fd;
-       int                      con_inflight;
-
-       struct sockaddr_storage  con_peer;
-       struct sockaddr_storage  con_local;
-       in_port_t                con_port;
-       uint32_t                 con_xidnxt;
-       int                      con_version;
-       enum ofp_state           con_state;
-
-       struct event             con_ev;
-       struct ibuf             *con_rbuf;
-       struct msgbuf            con_wbuf;
-
-       struct switch_control   *con_switch;
-       struct switchd          *con_sc;
-       struct switch_server    *con_srv;
-
-       struct multipart_list    con_mmlist;
-       struct switch_table_list
-                                con_stlist;
-
-       TAILQ_ENTRY(switch_connection)
-                                con_entry;
-};
-TAILQ_HEAD(switch_connections, switch_connection);
-
-struct switch_server {
-       int                      srv_fd;
-       int                      srv_tls;
-       struct sockaddr_storage  srv_addr;
-       struct event             srv_ev;
-       struct event             srv_evt;
-       struct switchd          *srv_sc;
-};
-
-struct switch_client {
-       struct switch_address    swc_addr;
-       struct switch_address    swc_target;
-       struct event             swc_ev;
-       void                    *swc_arg;
-       TAILQ_ENTRY(switch_client)
-                                swc_next;
-};
-TAILQ_HEAD(switch_clients, switch_client);
-
-struct switchd {
-       struct privsep           sc_ps;
-       struct switch_server     sc_server;
-       int                      sc_tap;
-       struct switch_head       sc_switches;
-       uint32_t                 sc_swid;
-       unsigned int             sc_cache_max;
-       unsigned int             sc_cache_timeout;
-       char                     sc_conffile[PATH_MAX];
-       uint8_t                  sc_opts;
-       struct switch_clients    sc_clients;
-       struct switch_connections
-                                sc_conns;
-};
-
-struct ofp_callback {
-       uint8_t          cb_type;
-       int             (*cb)(struct switchd *, struct switch_connection *,
-                           struct ofp_header *, struct ibuf *);
-       int             (*validate)(struct switchd *, struct sockaddr_storage *,
-                           struct sockaddr_storage *, struct ofp_header *,
-                           struct ibuf *);
-};
-
-#define SWITCHD_OPT_VERBOSE            0x01
-#define SWITCHD_OPT_NOACTION           0x04
-
-struct oflowmod_ctx {
-       uint8_t                          ctx_flags;
-#define OFMCTX_IBUF                     0x01
-       enum oflowmod_state              ctx_state;
-
-       struct ibuf                     *ctx_ibuf;
-       struct ofp_flow_mod             *ctx_fm;
-       size_t                           ctx_start;
-       size_t                           ctx_ostart;
-       size_t                           ctx_oend;
-       size_t                           ctx_istart;
-       size_t                           ctx_iend;
-       size_t                           ctx_oioff;
-       struct ofp_instruction          *ctx_oi;
-};
-
-/* switchd.c */
-int             switchd_socket(struct sockaddr *, int);
-int             switchd_listen(struct sockaddr *);
-int             switchd_sockaddr(const char *, in_port_t, struct sockaddr_storage *);
-int             switchd_tap(void);
-int             switchd_open_device(struct privsep *, const char *, size_t);
-struct switch_connection *
-                switchd_connbyid(struct switchd *, unsigned int, unsigned int);
-struct switch_connection *
-                switchd_connbyaddr(struct switchd *, struct sockaddr *);
-
-/* packet.c */
-int             packet_ether_input(struct ibuf *, size_t, struct packet *);
-int             packet_input(struct switchd *, struct switch_control *,
-                   uint32_t, uint32_t *, struct packet *);
-
-/* switch.c */
-void            switch_init(struct switchd *);
-int             switch_dispatch_control(int, struct privsep_proc *,
-                   struct imsg *);
-struct switch_control
-               *switch_add(struct switch_connection *);
-void            switch_remove(struct switchd *, struct switch_control *);
-struct switch_control
-               *switch_get(struct switch_connection *);
-struct macaddr *switch_learn(struct switchd *, struct switch_control *,
-                   uint8_t *, uint32_t);
-struct macaddr *switch_cached(struct switch_control *, uint8_t *);
-RB_PROTOTYPE(switch_head, switch_control, sw_entry, switch_cmp);
-RB_PROTOTYPE(macaddr_head, macaddr, mac_entry, switch_maccmp);
-
-/* timer.c */
-void            timer_set(struct switchd *, struct timer *,
-                   void (*)(struct switchd *, void *), void *);
-void            timer_add(struct switchd *, struct timer *, int);
-void            timer_del(struct switchd *, struct timer *);
-
-/* util.c */
-void            socket_set_blockmode(int, enum blockmodes);
-int             accept4_reserve(int, struct sockaddr *, socklen_t *,
-                   int, int, volatile int *);
-in_port_t       socket_getport(struct sockaddr_storage *);
-int             socket_setport(struct sockaddr_storage *, in_port_t);
-int             sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
-struct in6_addr *prefixlen2mask6(uint8_t, uint32_t *);
-uint32_t        prefixlen2mask(uint8_t);
-const char     *print_host(struct sockaddr_storage *, char *, size_t);
-const char     *print_ether(const uint8_t *)
-                   __attribute__ ((__bounded__(__minbytes__,1,ETHER_ADDR_LEN)));
-const char     *print_map(unsigned int, struct constmap *);
-void            print_verbose(const char *emsg, ...)
-                   __attribute__((__format__ (printf, 1, 2)));
-void            print_debug(const char *emsg, ...)
-                   __attribute__((__format__ (printf, 1, 2)));
-void            print_hex(uint8_t *, off_t, size_t);
-void            getmonotime(struct timeval *);
-int             parsehostport(const char *, struct sockaddr *, socklen_t);
-
-/* ofrelay.c */
-void            ofrelay(struct privsep *, struct privsep_proc *);
-void            ofrelay_run(struct privsep *, struct privsep_proc *, void *);
-int             ofrelay_attach(struct switch_server *, int,
-                   struct sockaddr *);
-void            ofrelay_close(struct switch_connection *);
-void            ofrelay_write(struct switch_connection *, struct ibuf *);
-
-/* ofp.c */
-void            ofp(struct privsep *, struct privsep_proc *);
-void            ofp_close(struct switch_connection *);
-int             ofp_open(struct privsep *, struct switch_connection *);
-void            ofp_accept(int, short, void *);
-int             ofp_input(struct switch_connection *, struct ibuf *);
-int             ofp_nextstate(struct switchd *, struct switch_connection *,
-                   enum ofp_state);
-struct switch_table *
-                switch_tablelookup(struct switch_connection *, int);
-struct switch_table *
-                switch_newtable(struct switch_connection *, int);
-void            switch_deltable(struct switch_connection *,
-                   struct switch_table *);
-void            switch_freetables(struct switch_connection *);
-
-/* ofp10.c */
-int             ofp10_hello(struct switchd *, struct switch_connection *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp10_validate(struct switchd *,
-                   struct sockaddr_storage *, struct sockaddr_storage *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp10_input(struct switchd *, struct switch_connection *,
-                   struct ofp_header *, struct ibuf *);
-
-/* ofp13.c */
-int             ofp13_input(struct switchd *, struct switch_connection *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp13_hello(struct switchd *, struct switch_connection *,
-                   struct ofp_header *oh, struct ibuf *);
-int             ofp13_validate(struct switchd *,
-                   struct sockaddr_storage *, struct sockaddr_storage *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp13_desc(struct switchd *, struct switch_connection *);
-int             ofp13_flow_stats(struct switchd *, struct switch_connection *,
-                   uint32_t, uint32_t, uint8_t);
-int             ofp13_table_features(struct switchd *,
-                   struct switch_connection *, uint8_t);
-int             ofp13_featuresrequest(struct switchd *,
-                   struct switch_connection *);
-struct ofp_flow_mod *
-                ofp13_flowmod(struct switch_connection *, struct ibuf *,
-                   uint8_t);
-int             ofp13_setconfig(struct switchd *, struct switch_connection *,
-                   uint16_t, uint16_t);
-int             ofp13_tablemiss_sendctrl(struct switchd *,
-                   struct switch_connection *, uint8_t);
-
-/* ofp_common.c */
-int             ofp_validate_header(struct switchd *,
-                   struct sockaddr_storage *, struct sockaddr_storage *,
-                   struct ofp_header *, uint8_t);
-int             ofp_validate(struct switchd *,
-                   struct sockaddr_storage *, struct sockaddr_storage *,
-                   struct ofp_header *, struct ibuf *, uint8_t);
-int             ofp_output(struct switch_connection *, struct ofp_header *,
-                   struct ibuf *);
-struct multipart_message *
-                   ofp_multipart_lookup(struct switch_connection *, uint32_t);
-int             ofp_multipart_add(struct switch_connection *, uint32_t,
-                   uint8_t);
-void            ofp_multipart_del(struct switch_connection *, uint32_t);
-void            ofp_multipart_free(struct switch_connection *,
-                   struct multipart_message *);
-void            ofp_multipart_clear(struct switch_connection *);
-int             action_new(struct ibuf *, uint16_t);
-int             action_group(struct ibuf *, uint32_t);
-int             action_output(struct ibuf *, uint32_t, uint16_t);
-int             action_push(struct ibuf *, uint16_t, uint16_t);
-int             action_pop_vlan(struct ibuf *);
-int             action_pop_mpls(struct ibuf *, uint16_t);
-int             action_copyttlout(struct ibuf *);
-int             action_copyttlin(struct ibuf *);
-int             action_decnwttl(struct ibuf *);
-struct ofp_action_set_field *
-                action_setfield(struct ibuf *ibuf);
-struct ofp_ox_match *
-                oxm_get(struct ibuf *, uint16_t, int, uint8_t);
-int             oxm_inport(struct ibuf *, uint32_t);
-int             oxm_inphyport(struct ibuf *, uint32_t);
-int             oxm_metadata(struct ibuf *, int, uint64_t, uint64_t);
-int             oxm_etheraddr(struct ibuf *, int, uint8_t *, uint8_t *);
-int             oxm_ethertype(struct ibuf *, uint16_t);
-int             oxm_vlanvid(struct ibuf *, int, uint16_t, uint16_t);
-int             oxm_vlanpcp(struct ibuf *, uint8_t);
-int             oxm_ipdscp(struct ibuf *, uint8_t);
-int             oxm_ipecn(struct ibuf *, uint8_t);
-int             oxm_ipproto(struct ibuf *, uint8_t);
-int             oxm_ipaddr(struct ibuf *, int, int, uint32_t, uint32_t);
-int             oxm_tcpport(struct ibuf *, int, uint16_t);
-int             oxm_udpport(struct ibuf *, int, uint16_t);
-int             oxm_sctpport(struct ibuf *, int, uint16_t);
-int             oxm_icmpv4type(struct ibuf *, uint8_t);
-int             oxm_icmpv4code(struct ibuf *, uint8_t);
-int             oxm_arpop(struct ibuf *, uint16_t);
-int             oxm_arpaddr(struct ibuf *, int, int, uint32_t, uint32_t);
-int             oxm_arphaddr(struct ibuf *, int, uint8_t *, uint8_t *);
-int             oxm_ipv6addr(struct ibuf *, int, struct in6_addr *,
-                   struct in6_addr *);
-int             oxm_ipv6flowlabel(struct ibuf *, int, uint32_t, uint32_t);
-int             oxm_icmpv6type(struct ibuf *, uint8_t);
-int             oxm_icmpv6code(struct ibuf *, uint8_t);
-int             oxm_ipv6ndtarget(struct ibuf *, struct in6_addr *);
-int             oxm_ipv6ndlinkaddr(struct ibuf *, int, uint8_t *);
-int             oxm_mplslabel(struct ibuf *, uint32_t);
-int             oxm_mplstc(struct ibuf *, uint8_t);
-int             oxm_mplsbos(struct ibuf *, uint8_t);
-int             oxm_tunnelid(struct ibuf *, int, uint64_t, uint64_t);
-int             oxm_ipv6exthdr(struct ibuf *, int, uint16_t, uint16_t);
-struct ofp_instruction *
-                ofp_instruction(struct ibuf *, uint16_t, uint16_t);
-struct ibuf *
-                oflowmod_open(struct oflowmod_ctx *,
-                   struct switch_connection *, struct ibuf *, uint8_t);
-int             oflowmod_close(struct oflowmod_ctx *);
-int             oflowmod_mopen(struct oflowmod_ctx *);
-int             oflowmod_mclose(struct oflowmod_ctx *);
-int             oflowmod_iopen(struct oflowmod_ctx *);
-int             oflowmod_iclose(struct oflowmod_ctx *);
-int             oflowmod_instruction(struct oflowmod_ctx *, unsigned int);
-
-int             oflowmod_instructionclose(struct oflowmod_ctx *);
-int             oflowmod_state(struct oflowmod_ctx *,
-                   unsigned int, unsigned int);
-int             oflowmod_err(struct oflowmod_ctx *, const char *, int);
-int             ofp_validate_hello(struct switchd *,
-                   struct sockaddr_storage *, struct sockaddr_storage *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp_recv_hello(struct switchd *, struct switch_connection *,
-                   struct ofp_header *, struct ibuf *);
-int             ofp_send_hello(struct switchd *, struct switch_connection *,
-                   int);
-int             ofp_send_featuresrequest(struct switchd *,
-                   struct switch_connection *);
-/* ofcconn.c */
-void            ofcconn(struct privsep *, struct privsep_proc *);
-void            ofcconn_shutdown(void);
-
-/* imsg_util.c */
-struct ibuf    *ibuf_new(void *, size_t);
-struct ibuf    *ibuf_static(void);
-int             ibuf_cat(struct ibuf *, struct ibuf *);
-void            ibuf_release(struct ibuf *);
-size_t          ibuf_length(struct ibuf *);
-int             ibuf_setsize(struct ibuf *, size_t);
-int             ibuf_setmax(struct ibuf *, size_t);
-uint8_t                *ibuf_data(struct ibuf *);
-void           *ibuf_getdata(struct ibuf *, size_t);
-ssize_t                 ibuf_dataleft(struct ibuf *);
-size_t          ibuf_dataoffset(struct ibuf *);
-struct ibuf    *ibuf_get(struct ibuf *, size_t);
-struct ibuf    *ibuf_dup(struct ibuf *);
-struct ibuf    *ibuf_random(size_t);
-int             ibuf_prepend(struct ibuf *, void *, size_t);
-void           *ibuf_advance(struct ibuf *, size_t);
-void            ibuf_zero(struct ibuf *);
-void            ibuf_reset(struct ibuf *);
-
-/* parse.y */
-int             cmdline_symset(char *);
-int             parse_config(const char *, struct switchd *);
-
-#endif /* SWITCHD_H */
diff --git a/usr.sbin/switchd/timer.c b/usr.sbin/switchd/timer.c
deleted file mode 100644 (file)
index a217260..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*     $OpenBSD: timer.c,v 1.1 2016/07/19 16:54:26 reyk Exp $  */
-
-/*
- * Copyright (c) 2010-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <event.h>
-
-#include "switchd.h"
-
-void    timer_callback(int, short, void *);
-
-void
-timer_set(struct switchd *sc, struct timer *tmr,
-    void (*cb)(struct switchd *, void *), void *arg)
-{
-       tmr->tmr_sc = sc;
-       tmr->tmr_cb = cb;
-       tmr->tmr_cbarg = arg;
-       evtimer_set(&tmr->tmr_ev, timer_callback, tmr);
-}
-
-void
-timer_add(struct switchd *sc, struct timer *tmr, int timeout)
-{
-       struct timeval           tv = { timeout };
-
-       if (evtimer_initialized(&tmr->tmr_ev) &&
-           evtimer_pending(&tmr->tmr_ev, NULL))
-               evtimer_del(&tmr->tmr_ev);
-
-       evtimer_add(&tmr->tmr_ev, &tv);
-}
-
-void
-timer_del(struct switchd *sc, struct timer *tmr)
-{
-       if (tmr->tmr_sc == sc && tmr->tmr_cb &&
-           evtimer_initialized(&tmr->tmr_ev))
-               evtimer_del(&tmr->tmr_ev);
-}
-
-void
-timer_callback(int fd, short event, void *arg)
-{
-       struct timer    *tmr = arg;
-
-       if (tmr->tmr_cb)
-               tmr->tmr_cb(tmr->tmr_sc, tmr->tmr_cbarg);
-}
diff --git a/usr.sbin/switchd/types.h b/usr.sbin/switchd/types.h
deleted file mode 100644 (file)
index 569c070..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*     $OpenBSD: types.h,v 1.12 2021/01/27 07:21:54 deraadt Exp $      */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef SWITCHD_TYPES_H
-#define SWITCHD_TYPES_H
-
-#ifndef SWITCHD_USER
-#define SWITCHD_USER   "_switchd"
-#endif
-
-#define SWITCHD_NAME   "switch"
-
-#ifndef SWITCHD_CONFIG
-#define SWITCHD_CONFIG "/etc/" SWITCHD_NAME "d.conf"
-#endif
-#define SWITCHD_SOCKET "/var/run/" SWITCHD_NAME "d.sock"
-
-#define        SWITCHD_FD_RESERVE      5
-#define SWITCHD_CYCLE_BUFFERS  8       /* # of static buffers for mapping */
-#define SWITCHD_READ_BUFFER    0xffff
-#define SWITCHD_MSGBUF_MAX     0xffff
-#define SWITCHD_MAX_TAP                256
-#define SWITCHD_MAX_SESSIONS   0xffff
-
-#define SWITCHD_CTLR_PORT      6653    /* Assigned by IANA for OpenFlow */
-
-#define SWITCHD_CACHE_MAX      4096    /* Default MAC address cache limit */
-#define SWITCHD_CACHE_TIMEOUT  240     /* t/o in seconds for learned MACs */
-
-#define SWITCHD_CONNECT_TIMEOUT        5
-
-#ifndef ETHER_ADDR_LEN
-#define ETHER_ADDR_LEN         6
-#endif
-
-enum imsg_type {
-       IMSG_NONE       = 0,
-       IMSG_CTL_VERBOSE,
-       IMSG_CTL_PROCFD,
-       IMSG_CTL_NOTIFY,
-       IMSG_CTL_OK,
-       IMSG_CTL_FAIL,
-       IMSG_CTL_END,
-       IMSG_CTL_RELOAD,
-       IMSG_CTL_RESET,
-       IMSG_CTL_SWITCH,
-       IMSG_CTL_MAC,
-       IMSG_CTL_SHOW_SUM,
-       IMSG_CTL_CONNECT,
-       IMSG_CTL_DISCONNECT,
-       IMSG_TAPFD
-};
-
-enum privsep_procid {
-       PROC_PARENT     = 0,
-       PROC_OFP,
-       PROC_CONTROL,
-       PROC_OFCCONN,
-       PROC_MAX
-};
-extern enum privsep_procid privsep_process;
-
-enum blockmodes {
-       BM_NORMAL,
-       BM_NONBLOCK
-};
-
-enum flushmode {
-       RESET_RELOAD    = 0,
-       RESET_ALL
-};
-
-enum switch_conn_type {
-       SWITCH_CONN_LOCAL,
-       SWITCH_CONN_TCP,
-       SWITCH_CONN_TLS
-};
-
-enum oflowmod_state {
-       OFMCTX_INIT,
-       OFMCTX_OPEN,
-       OFMCTX_MOPEN,
-       OFMCTX_MCLOSE,
-       OFMCTX_IOPEN,
-       OFMCTX_ICLOSE,
-       OFMCTX_CLOSE,
-       OFMCTX_ERR
-};
-
-#ifndef nitems
-#define nitems(_a)   (sizeof((_a)) / sizeof((_a)[0]))
-#endif
-
-#endif /* SWITCHD_TYPES_H */
diff --git a/usr.sbin/switchd/util.c b/usr.sbin/switchd/util.c
deleted file mode 100644 (file)
index d53e674..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*     $OpenBSD: util.c,v 1.6 2017/01/09 14:49:22 reyk Exp $   */
-
-/*
- * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-
-#include <unistd.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <event.h>
-
-#include "switchd.h"
-
-void
-socket_set_blockmode(int fd, enum blockmodes bm)
-{
-       int     flags;
-
-       if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
-               fatal("fcntl F_GETFL");
-
-       if (bm == BM_NONBLOCK)
-               flags |= O_NONBLOCK;
-       else
-               flags &= ~O_NONBLOCK;
-
-       if ((flags = fcntl(fd, F_SETFL, flags)) == -1)
-               fatal("fcntl F_SETFL");
-}
-
-int
-accept4_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
-    int flags, int reserve, volatile int *counter)
-{
-       int      fd;
-
-       if (getdtablecount() + reserve + *counter >= getdtablesize()) {
-               errno = EMFILE;
-               return (-1);
-       }
-
-       if ((fd = accept4(sockfd, addr, addrlen, flags)) != -1) {
-               (*counter)++;
-               DPRINTF("%s: inflight incremented, now %d",__func__, *counter);
-       }
-
-       return (fd);
-}
-
-in_port_t
-socket_getport(struct sockaddr_storage *ss)
-{
-       switch (ss->ss_family) {
-       case AF_INET:
-               return (ntohs(((struct sockaddr_in *)ss)->sin_port));
-       case AF_INET6:
-               return (ntohs(((struct sockaddr_in6 *)ss)->sin6_port));
-       default:
-               return (0);
-       }
-
-       /* NOTREACHED */
-       return (0);
-}
-
-int
-socket_setport(struct sockaddr_storage *ss, in_port_t port)
-{
-       switch (ss->ss_family) {
-       case AF_INET:
-               ((struct sockaddr_in *)ss)->sin_port = ntohs(port);
-               return (0);
-       case AF_INET6:
-               ((struct sockaddr_in6 *)ss)->sin6_port = ntohs(port);
-               return (0);
-       default:
-               return (-1);
-       }
-
-       /* NOTREACHED */
-       return (-1);
-}
-
-int
-sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
-{
-       struct sockaddr_in      *a4, *b4;
-       struct sockaddr_in6     *a6, *b6;
-       struct sockaddr_un      *au, *bu;
-       uint32_t                 av[4], bv[4], mv[4];
-
-       if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
-               return (0);
-       else if (a->sa_family > b->sa_family)
-               return (1);
-       else if (a->sa_family < b->sa_family)
-               return (-1);
-
-       if (prefixlen == -1)
-               memset(&mv, 0xff, sizeof(mv));
-
-       switch (a->sa_family) {
-       case AF_INET:
-               a4 = (struct sockaddr_in *)a;
-               b4 = (struct sockaddr_in *)b;
-
-               av[0] = a4->sin_addr.s_addr;
-               bv[0] = b4->sin_addr.s_addr;
-               if (prefixlen != -1)
-                       mv[0] = prefixlen2mask(prefixlen);
-
-               if ((av[0] & mv[0]) > (bv[0] & mv[0]))
-                       return (1);
-               if ((av[0] & mv[0]) < (bv[0] & mv[0]))
-                       return (-1);
-               break;
-       case AF_INET6:
-               a6 = (struct sockaddr_in6 *)a;
-               b6 = (struct sockaddr_in6 *)b;
-
-               memcpy(&av, &a6->sin6_addr.s6_addr, 16);
-               memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
-               if (prefixlen != -1)
-                       prefixlen2mask6(prefixlen, mv);
-
-               if ((av[3] & mv[3]) > (bv[3] & mv[3]))
-                       return (1);
-               if ((av[3] & mv[3]) < (bv[3] & mv[3]))
-                       return (-1);
-               if ((av[2] & mv[2]) > (bv[2] & mv[2]))
-                       return (1);
-               if ((av[2] & mv[2]) < (bv[2] & mv[2]))
-                       return (-1);
-               if ((av[1] & mv[1]) > (bv[1] & mv[1]))
-                       return (1);
-               if ((av[1] & mv[1]) < (bv[1] & mv[1]))
-                       return (-1);
-               if ((av[0] & mv[0]) > (bv[0] & mv[0]))
-                       return (1);
-               if ((av[0] & mv[0]) < (bv[0] & mv[0]))
-                       return (-1);
-               break;
-       case AF_UNIX:
-               au = (struct sockaddr_un *)a;
-               bu = (struct sockaddr_un *)b;
-               return (strcmp(au->sun_path, bu->sun_path));
-       }
-
-       return (0);
-}
-
-uint32_t
-prefixlen2mask(uint8_t prefixlen)
-{
-       if (prefixlen == 0)
-               return (0);
-
-       if (prefixlen > 32)
-               prefixlen = 32;
-
-       return (htonl(0xffffffff << (32 - prefixlen)));
-}
-
-struct in6_addr *
-prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
-{
-       static struct in6_addr  s6;
-       int                     i;
-
-       if (prefixlen > 128)
-               prefixlen = 128;
-
-       bzero(&s6, sizeof(s6));
-       for (i = 0; i < prefixlen / 8; i++)
-               s6.s6_addr[i] = 0xff;
-       i = prefixlen % 8;
-       if (i)
-               s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
-
-       memcpy(mask, &s6, sizeof(s6));
-
-       return (&s6);
-}
-
-const char *
-print_ether(const uint8_t *ea)
-{
-       static char      sbuf[SWITCHD_CYCLE_BUFFERS]
-                           [ETHER_ADDR_LEN * 2 + 5 + 1];
-       static int       idx = 0;
-       size_t           len;
-       char            *buf;
-
-       buf = sbuf[idx];
-       len = sizeof(sbuf[idx]);
-       if (++idx >= SWITCHD_CYCLE_BUFFERS)
-               idx = 0;
-
-       snprintf(buf, len, "%02x:%02x:%02x:%02x:%02x:%02x",
-           ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
-
-       return (buf);
-}
-
-const char *
-print_host(struct sockaddr_storage *ss, char *buf, size_t len)
-{
-       static char     sbuf[SWITCHD_CYCLE_BUFFERS][NI_MAXHOST + 7];
-       struct sockaddr_un *un;
-       static int      idx = 0;
-       char            pbuf[7];
-       in_port_t       port;
-
-       if (buf == NULL) {
-               buf = sbuf[idx];
-               len = sizeof(sbuf[idx]);
-               if (++idx >= SWITCHD_CYCLE_BUFFERS)
-                       idx = 0;
-       }
-
-       if (ss->ss_family == AF_UNSPEC) {
-               strlcpy(buf, "any", len);
-               return (buf);
-       } else if (ss->ss_family == AF_UNIX) {
-               un = (struct sockaddr_un *)ss;
-               strlcpy(buf, un->sun_path, len);
-               return (buf);
-       }
-
-       if (getnameinfo((struct sockaddr *)ss, ss->ss_len,
-           buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
-               buf[0] = '\0';
-               return (NULL);
-       }
-
-       if ((port = socket_getport(ss)) != 0) {
-               snprintf(pbuf, sizeof(pbuf), ":%d", port);
-               (void)strlcat(buf, pbuf, len);
-       }
-
-       return (buf);
-}
-
-const char *
-print_map(unsigned int type, struct constmap *map)
-{
-       unsigned int             i;
-       static char              buf[SWITCHD_CYCLE_BUFFERS][32];
-       static int               idx = 0;
-       const char              *name = NULL;
-
-       if (idx >= SWITCHD_CYCLE_BUFFERS)
-               idx = 0;
-       bzero(buf[idx], sizeof(buf[idx]));
-
-       for (i = 0; map[i].cm_name != NULL; i++) {
-               if (map[i].cm_type == type) {
-                       name = map[i].cm_name;
-                       break;
-               }
-       }
-
-       if (name == NULL)
-               snprintf(buf[idx], sizeof(buf[idx]), "<%u>", type);
-       else
-               strlcpy(buf[idx], name, sizeof(buf[idx]));
-
-       return (buf[idx++]);
-}
-
-void
-getmonotime(struct timeval *tv)
-{
-       struct timespec  ts;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &ts))
-               fatal("clock_gettime");
-
-       TIMESPEC_TO_TIMEVAL(tv, &ts);
-}
-
-void
-print_debug(const char *emsg, ...)
-{
-       va_list  ap;
-
-       if (log_getverbose() > 2) {
-               va_start(ap, emsg);
-               vfprintf(stderr, emsg, ap);
-               va_end(ap);
-       }
-}
-
-void
-print_verbose(const char *emsg, ...)
-{
-       va_list  ap;
-
-       if (log_getverbose()) {
-               va_start(ap, emsg);
-               vfprintf(stderr, emsg, ap);
-               va_end(ap);
-       }
-}
-
-void
-print_hex(uint8_t *buf, off_t offset, size_t length)
-{
-       unsigned int     i;
-
-       if (log_getverbose() < 3 || !length)
-               return;
-
-       for (i = 0; i < length; i++) {
-               if (i && (i % 4) == 0) {
-                       if ((i % 32) == 0)
-                               print_debug("\n");
-                       else
-                               print_debug(" ");
-               }
-               print_debug("%02x", buf[offset + i]);
-       }
-       print_debug("\n");
-}
-
-int
-parsehostport(const char *str, struct sockaddr *sa, socklen_t salen)
-{
-       char             buf[NI_MAXHOST + NI_MAXSERV + 8], *servp, *nodep;
-       struct addrinfo  hints, *ai;
-
-       if (strlcpy(buf, str, sizeof(buf)) >= sizeof(buf))
-               return (-1);
-
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_flags = 0;
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_protocol = IPPROTO_TCP;
-
-       if (buf[0] == '[' &&
-           (servp = strchr(buf, ']')) != NULL &&
-           (*(servp + 1) == '\0' || *(servp + 1) == ':')) {
-               hints.ai_family = AF_INET6;
-               hints.ai_flags = AI_NUMERICHOST;
-               nodep = buf + 1;
-               *servp++ = '\0';
-       } else {
-               nodep = buf;
-               servp = strrchr(nodep, ':');
-       }
-       if (servp != NULL) {
-               *servp = '\0';
-               servp++;
-       } else
-               servp = NULL;
-
-       if (getaddrinfo(nodep, servp, &hints, &ai) != 0)
-               return (-1);
-
-       if (salen < ai->ai_addrlen) {
-               freeaddrinfo(ai);
-               return (-1);
-       }
-       memset(sa, 0, salen);
-       memcpy(sa, ai->ai_addr, ai->ai_addrlen);
-
-       return (0);
-}