This uses the just imported snmpd_metrics as a new (agentx-based) backend.
Snmpd(8) executes all files in /usr/libexec/snmpd and treats regions
registered by these binaries as authorative, so that no other agentx
backends can overwrite them. The snmpe process is now pledged
"stdio recvfd inet unix".
This removes quite a few entries from the sysORTable, but the current
entries are non-compliant anyway and should be completely revisisted at a
later time.
Reduces the time for a full walk by about a factor of 4, bringing us close
to the original speed before application.c was introduced.
General design discussed with claudio@
Tested by and OK sthen
Release build test and OK tb@
-/* $OpenBSD: application.h,v 1.4 2022/08/29 13:19:05 martijn Exp $ */
+/* $OpenBSD: application.h,v 1.5 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2021 Martijn van Duren <martijn@openbsd.org>
void appl_agentx(void);
void appl_agentx_init(void);
void appl_agentx_shutdown(void);
+void appl_agentx_backend(int);
/* application_blocklist.c */
void appl_blocklist_init(void);
-/* $OpenBSD: application_agentx.c,v 1.3 2022/08/30 14:54:18 martijn Exp $ */
+/* $OpenBSD: application_agentx.c,v 1.4 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
*
struct appl_agentx_connection {
uint32_t conn_id;
+ /*
+ * A backend has several overruling properties:
+ * - If it exits, snmpd crashes
+ * - All registrations are priority 1
+ * - All registrations own the subtree.
+ */
+ int conn_backend;
struct ax *conn_ax;
struct event conn_rev;
struct event conn_wev;
goto fail;
}
+ conn->conn_backend = 0;
TAILQ_INIT(&(conn->conn_sessions));
if ((conn->conn_ax = ax_new(fd)) == NULL) {
log_warn(NULL);
free(conn);
}
+void
+appl_agentx_backend(int fd)
+{
+ struct appl_agentx_connection *conn;
+
+ if ((conn = malloc(sizeof(*conn))) == NULL)
+ fatal(NULL);
+
+ conn->conn_backend = 1;
+ TAILQ_INIT(&(conn->conn_sessions));
+ if ((conn->conn_ax = ax_new(fd)) == NULL)
+ fatal("ax_new");
+
+ do {
+ conn->conn_id = arc4random();
+ } while (RB_INSERT(appl_agentx_conns,
+ &appl_agentx_conns, conn) != NULL);
+
+ event_set(&(conn->conn_rev), fd, EV_READ | EV_PERSIST,
+ appl_agentx_recv, conn);
+ event_add(&(conn->conn_rev), NULL);
+ event_set(&(conn->conn_wev), fd, EV_WRITE, appl_agentx_send, conn);
+}
+
void
appl_agentx_free(struct appl_agentx_connection *conn)
{
RB_REMOVE(appl_agentx_conns, &appl_agentx_conns, conn);
ax_free(conn->conn_ax);
+ if (conn->conn_backend)
+ fatalx("AgentX(%"PRIu32"): disappeared unexpected",
+ conn->conn_id);
free(conn);
}
uint32_t timeout;
struct ber_oid oid;
enum appl_error error;
+ int subtree = 0;
timeout = pdu->ap_payload.ap_register.ap_timeout;
timeout = timeout != 0 ? timeout : session->sess_timeout != 0 ?
session->sess_timeout : AGENTX_DEFAULTTIMEOUT;
timeout *= 100;
+ if (session->sess_conn->conn_backend) {
+ pdu->ap_payload.ap_register.ap_priority = 1;
+ subtree = 1;
+ }
if (appl_agentx_oid2ber_oid(
&(pdu->ap_payload.ap_register.ap_subtree), &oid) == NULL) {
log_warnx("%s: Failed to register: oid too small",
error = appl_register(pdu->ap_context.aos_string, timeout,
pdu->ap_payload.ap_register.ap_priority, &oid,
- pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION, 0,
- pdu->ap_payload.ap_register.ap_range_subid,
+ pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION,
+ subtree, pdu->ap_payload.ap_register.ap_range_subid,
pdu->ap_payload.ap_register.ap_upper_bound,
&(session->sess_backend));
-/* $OpenBSD: mib.c,v 1.103 2022/06/30 11:28:36 martijn Exp $ */
+/* $OpenBSD: mib.c,v 1.104 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2012 Joel Knight <joel@openbsd.org>
/* SNMP-USER-BASED-SM-MIB */
smi_mibtree(usm_mib);
+#if 0
/* HOST-RESOURCES-MIB */
smi_mibtree(hr_mib);
/* OPENBSD-MIB */
smi_mibtree(openbsd_mib);
+#endif
}
-/* $OpenBSD: snmpd.c,v 1.46 2021/08/10 06:52:03 martijn Exp $ */
+/* $OpenBSD: snmpd.c,v 1.47 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
#include <net/if.h>
+#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void snmpd_sig_handler(int, short, void *);
int snmpd_dispatch_snmpe(int, struct privsep_proc *, struct imsg *);
int check_child(pid_t, const char *);
+void snmpd_backend(struct snmpd *);
struct snmpd *snmpd_env;
gettimeofday(&env->sc_starttime, NULL);
env->sc_engine_boots = 0;
+/* Remove after 7.2 */
+#if 0
pf_init();
+#endif
proc_init(ps, procs, nitems(procs), debug, argc0, argv0, proc_id);
if (!debug && daemon(0, 0) == -1)
signal_add(&ps->ps_evsigusr1, NULL);
proc_connect(ps);
+ snmpd_backend(env);
if (pledge("stdio dns sendfd proc exec id", NULL) == -1)
fatal("pledge");
gettimeofday(&now, NULL);
return now.tv_sec;
}
+
+void
+snmpd_backend(struct snmpd *env)
+{
+ DIR *dir;
+ struct dirent *file;
+ int pair[2];
+ char *argv[8];
+ char execpath[PATH_MAX];
+ size_t i = 0;
+
+ if ((dir = opendir(SNMPD_BACKEND)) == NULL)
+ fatal("opendir \"%s\"", SNMPD_BACKEND);
+
+ argv[i++] = execpath;
+ if (env->sc_rtfilter) {
+ argv[i++] = "-C";
+ argv[i++] = "filter-routes";
+ }
+ if (env->sc_flags & SNMPD_F_VERBOSE)
+ argv[i++] = "-vv";
+ if (env->sc_flags & SNMPD_F_DEBUG) {
+ argv[i++] = "-d";
+ argv[i++] = "-x";
+ argv[i++] = "3";
+ } else {
+ argv[i++] = "-x";
+ argv[i++] = "0";
+ }
+ argv[i] = NULL;
+ while ((file = readdir(dir)) != NULL) {
+ if (file->d_name[0] == '.')
+ continue;
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
+ fatal("socketpair");
+ switch (fork()) {
+ case -1:
+ fatal("fork");
+ case 0:
+ close(pair[1]);
+ if (dup2(pair[0],
+ env->sc_flags & SNMPD_F_DEBUG ? 3 : 0) == -1)
+ fatal("dup2");
+ if (closefrom(env->sc_flags & SNMPD_F_DEBUG ? 4 : 1) == -1)
+ fatal("closefrom");
+ (void)snprintf(execpath, sizeof(execpath), "%s/%s",
+ SNMPD_BACKEND, file->d_name);
+ execv(argv[0], argv);
+ fatal("execv");
+ default:
+ close(pair[0]);
+ if (proc_compose_imsg(&env->sc_ps, PROC_SNMPE, -1,
+ IMSG_AX_FD, -1, pair[1], NULL, 0) == -1)
+ fatal("proc_compose_imsg");
+ continue;
+ }
+ }
+}
-/* $OpenBSD: snmpd.h,v 1.104 2022/08/23 08:56:21 martijn Exp $ */
+/* $OpenBSD: snmpd.h,v 1.105 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
#define CONF_FILE "/etc/snmpd.conf"
#define SNMPD_SOCKET "/var/run/snmpd.sock"
+#define SNMPD_BACKEND "/usr/libexec/snmpd"
#define SNMPD_USER "_snmpd"
#define SNMP_PORT "161"
#define SNMPTRAP_PORT "162"
IMSG_CTL_VERBOSE,
IMSG_CTL_RELOAD,
IMSG_CTL_PROCFD,
- IMSG_TRAP_EXEC
+ IMSG_TRAP_EXEC,
+ IMSG_AX_FD
};
struct imsgev {
-/* $OpenBSD: snmpe.c,v 1.83 2022/08/23 08:56:21 martijn Exp $ */
+/* $OpenBSD: snmpe.c,v 1.84 2022/09/01 14:34:17 martijn Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
#include "mib.h"
void snmpe_init(struct privsep *, struct privsep_proc *, void *);
+int snmpe_dispatch_parent(int, struct privsep_proc *, struct imsg *);
int snmpe_parse(struct snmp_message *);
void snmpe_tryparse(int, struct snmp_message *);
int snmpe_parsevarbinds(struct snmp_message *);
struct snmp_messages snmp_messages = RB_INITIALIZER(&snmp_messages);
static struct privsep_proc procs[] = {
- { "parent", PROC_PARENT }
+ { "parent", PROC_PARENT, snmpe_dispatch_parent }
};
void
struct snmpd *env = ps->ps_env;
struct address *h;
+/* Remove after 7.2 */
+#if 0
kr_init();
timer_init();
+#endif
usm_generate_keys();
appl_init();
/* no filesystem visibility */
if (unveil("/", "") == -1)
fatal("unveil /");
- if (unveil(NULL, NULL) == -1)
- fatal("unveil");
+ if (pledge("stdio recvfd inet unix", NULL) == -1)
+ fatal("pledge");
log_info("snmpe %s: ready",
tohexstr(env->sc_engineid, env->sc_engineid_len));
event_del(&h->evt);
close(h->fd);
}
+/* Remove after 7.2 */
+#if 0
kr_shutdown();
+#endif
appl_shutdown();
}
+int
+snmpe_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+ switch (imsg->hdr.type) {
+ case IMSG_AX_FD:
+ appl_agentx_backend(imsg->fd);
+ return 0;
+ default:
+ return -1;
+ }
+}
+
int
snmpe_bind(struct address *addr)
{