On Wed, Jun 29, 2022 at 01:35:37PM +0200, Martijn van Duren wrote:
> On Tue, 2022-06-28 at 12:33 +0200, Martijn van Duren wrote:
> > On Tue, 2022-06-28 at 12:21 +0200, Martijn van Duren wrote:
> > > On Tue, 2022-06-28 at 10:21 +0200, Martijn van Duren wrote:
> > > > Back in 2020 florian@ added the filter-pf-addresses keyword.
> > > > Although useful, I always felt it was a bit too case-specific. The diff
> > > > below adds a new blocklist feature/backend, which takes hold of an
> > > > entire subtree, effectively removing it from the tree.
> > > >
> > > > With this I've deprecated the filter-pf-address case and should
> > > > probably be removed somewhere after 7.4. The filter-routes case can't
> > > > be removed unfortunately, since its behaviour is not identical, and
> > > > instead adds filters to the routing socket, preventing updates being
> > > > pushed to snmpd(8).
> > > >
> > > > Feedback/OK?
> > > >
> > > > martijn@
> > > >
> > > Also clean up after ourselves if appl_exception fails.
> > >
> > *sigh* Missed a return.
> >
> And also some cleanup during shutdown.
Can't spot anything wrong in this one and works fine in some basic
testing.
ok tb
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/Makefile,v
> retrieving revision 1.18
> diff -u -p -r1.18 Makefile
> --- Makefile 19 Jan 2022 11:00:56 -0000 1.18
> +++ Makefile 29 Jun 2022 11:35:23 -0000
> @@ -3,6 +3,7 @@
> PROG= snmpd
> MAN= snmpd.8 snmpd.conf.5
> SRCS= parse.y log.c snmpe.c application.c
> application_legacy.c \
> + application_blocklist.c \
> mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \
> pf.c proc.c usm.c traphandler.c util.c
>
> Index: application.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
> retrieving revision 1.5
> diff -u -p -r1.5 application.c
> --- application.c 27 Jun 2022 10:31:17 -0000 1.5
> +++ application.c 29 Jun 2022 11:35:23 -0000
> @@ -148,6 +148,7 @@ RB_PROTOTYPE_STATIC(appl_requests, appl_
> void
> appl_init(void)
> {
> + appl_blocklist_init();
> appl_legacy_init();
> }
>
> @@ -156,6 +157,7 @@ appl_shutdown(void)
> {
> struct appl_context *ctx, *tctx;
>
> + appl_blocklist_shutdown();
> appl_legacy_shutdown();
>
> TAILQ_FOREACH_SAFE(ctx, &contexts, ac_entries, tctx) {
> Index: application.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/application.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 application.h
> --- application.h 19 Jan 2022 10:59:35 -0000 1.1
> +++ application.h 29 Jun 2022 11:35:23 -0000
> @@ -133,3 +133,7 @@ struct ber_element *appl_exception(enum
> /* application_legacy.c */
> void appl_legacy_init(void);
> void appl_legacy_shutdown(void);
> +
> +/* application_blocklist.c */
> +void appl_blocklist_init(void);
> +void appl_blocklist_shutdown(void);
> Index: application_blocklist.c
> ===================================================================
> RCS file: application_blocklist.c
> diff -N application_blocklist.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ application_blocklist.c 29 Jun 2022 11:35:23 -0000
> @@ -0,0 +1,141 @@
> +/* $OpenBSD: application.c,v 1.5 2022/06/27 10:31:17 martijn Exp $ */
> +
> +/*
> + * Copyright (c) 2022 Martijn van Duren <[email protected]>
> + *
> + * 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 <event.h>
> +#include <stdlib.h>
> +
> +#include "application.h"
> +#include "snmpd.h"
> +
> +struct appl_varbind *appl_blocklist_response(size_t);
> +void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char
> *,
> + struct appl_varbind *);
> +void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
> + const char *, struct appl_varbind *);
> +
> +struct appl_backend_functions appl_blocklist_functions = {
> + .ab_get = appl_blocklist_get,
> + .ab_getnext = appl_blocklist_getnext,
> + .ab_getbulk = NULL,
> +};
> +
> +struct appl_backend appl_blocklist = {
> + .ab_name = "blocklist",
> + .ab_cookie = NULL,
> + .ab_retries = 0,
> + .ab_fn = &appl_blocklist_functions
> +};
> +
> +static struct appl_varbind *response = NULL;
> +static size_t responsesz = 0;
> +
> +struct appl_varbind *
> +appl_blocklist_response(size_t nvarbind)
> +{
> + struct appl_varbind *tmp;
> + size_t i;
> +
> + if (responsesz < nvarbind) {
> + if ((tmp = recallocarray(response, responsesz, nvarbind,
> + sizeof(*response))) == NULL) {
> + log_warn(NULL);
> + return NULL;
> + }
> + responsesz = nvarbind;
> + response = tmp;
> + }
> + for (i = 0; i < nvarbind; i++)
> + response[i].av_next = i + 1 == nvarbind ?
> + NULL : &(response[i + 1]);
> + return response;
> +}
> +
> +void
> +appl_blocklist_init(void)
> +{
> + extern struct snmpd *snmpd_env;
> + size_t i;
> +
> + for (i = 0; i < snmpd_env->sc_nblocklist; i++)
> + appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]),
> + 0, 1, 0, 0, &appl_blocklist);
> +}
> +
> +void
> +appl_blocklist_shutdown(void)
> +{
> + appl_close(&appl_blocklist);
> + free(response);
> +}
> +
> +void
> +appl_blocklist_get(struct appl_backend *backend, __unused int32_t
> transactionid,
> + int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist)
> +{
> + struct appl_varbind *vb, *rvb, *rvblist;
> + size_t i;
> +
> + for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
> + i++;
> + if ((rvblist = appl_blocklist_response(i)) == NULL)
> + goto fail;
> + rvb = rvblist;
> + for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
> + rvb->av_oid = vb->av_oid;
> + rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT);
> + if (rvb->av_value == NULL)
> + goto fail;
> + }
> +
> + appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
> + return;
> + fail:
> + for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
> + rvb = rvb->av_next)
> + ober_free_elements(rvb->av_value);
> + appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
> +}
> +
> +void
> +appl_blocklist_getnext(struct appl_backend *backend,
> + __unused int32_t transactionid, int32_t requestid, __unused const char
> *ctx,
> + struct appl_varbind *vblist)
> +{
> + struct appl_varbind *vb, *rvb, *rvblist;
> + size_t i;
> +
> + for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
> + i++;
> + if ((rvblist = appl_blocklist_response(i)) == NULL)
> + goto fail;
> + rvb = rvblist;
> + for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
> + rvb->av_oid = vb->av_oid;
> + rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW);
> + if (rvb->av_value == NULL)
> + goto fail;
> + }
> +
> + appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
> + return;
> + fail:
> + for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
> + rvb = rvb->av_next)
> + ober_free_elements(rvb->av_value);
> + appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
> +}
> Index: mib.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
> retrieving revision 1.102
> diff -u -p -r1.102 mib.c
> --- mib.c 1 Sep 2021 15:54:40 -0000 1.102
> +++ mib.c 29 Jun 2022 11:35:23 -0000
> @@ -2223,9 +2223,6 @@ mib_pftableaddrs(struct oid *oid, struct
> struct pfr_astats as;
> int tblidx;
>
> - if (snmpd_env->sc_pfaddrfilter)
> - return (-1);
> -
> tblidx = o->bo_id[OIDIDX_pfTblAddr + 1];
> mps_decodeinaddr(o, &as.pfras_a.pfra_ip4addr, OIDIDX_pfTblAddr + 2);
> as.pfras_a.pfra_net = o->bo_id[OIDIDX_pfTblAddr + 6];
> @@ -2313,9 +2310,6 @@ mib_pftableaddrstable(struct oid *oid, s
> struct pfr_astats as;
> struct oid a, b;
> u_int32_t id, tblidx;
> -
> - if (snmpd_env->sc_pfaddrfilter)
> - return (NULL);
>
> bcopy(&oid->o_id, no, sizeof(*no));
> id = oid->o_oidlen - 1;
> Index: parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
> retrieving revision 1.74
> diff -u -p -r1.74 parse.y
> --- parse.y 28 Jun 2022 09:11:33 -0000 1.74
> +++ parse.y 29 Jun 2022 11:35:23 -0000
> @@ -130,7 +130,7 @@ typedef struct {
> %token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER
> %token READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER
> %token SECLEVEL NONE AUTH ENC USER AUTHKEY ENCKEY ERROR
> -%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER PORT
> +%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER BLOCKLIST PORT
> %token <v.string> STRING
> %token <v.number> NUMBER
> %type <v.string> usmuser community optcommunity
> @@ -255,6 +255,20 @@ main : LISTEN ON listen_udptcp
> }
> conf->sc_traphandler = 1;
> }
> + | BLOCKLIST oid {
> + struct ber_oid *blocklist;
> +
> + blocklist = recallocarray(conf->sc_blocklist,
> + conf->sc_nblocklist, conf->sc_nblocklist + 1,
> + sizeof(*blocklist));
> + if (blocklist == NULL) {
> + yyerror("malloc");
> + YYERROR;
> + }
> + conf->sc_blocklist = blocklist;
> + blocklist[conf->sc_nblocklist++] = *$2;
> + free($2);
> + }
> | RTFILTER yesno {
> if ($2 == 1)
> conf->sc_rtfilter = ROUTE_FILTER(RTM_NEWADDR) |
> @@ -264,8 +278,25 @@ main : LISTEN ON listen_udptcp
> else
> conf->sc_rtfilter = 0;
> }
> + /* XXX Remove after 7.4 */
> | PFADDRFILTER yesno {
> - conf->sc_pfaddrfilter = $2;
> + struct ber_oid *blocklist;
> +
> + log_warnx("filter-pf-addresses is deprecated. "
> + "Please use blocklist instead.");
> + if ($2) {
> + blocklist = recallocarray(conf->sc_blocklist,
> + conf->sc_nblocklist,
> + conf->sc_nblocklist + 1,
> + sizeof(*blocklist));
> + if (blocklist == NULL) {
> + yyerror("malloc");
> + YYERROR;
> + }
> + conf->sc_blocklist = blocklist;
> + smi_string2oid("pfTblAddrTable",
> + &(blocklist[conf->sc_nblocklist++]));
> + }
> }
> | seclevel {
> conf->sc_min_seclevel = $1;
> @@ -995,6 +1026,7 @@ lookup(char *s)
> { "agentid", AGENTID },
> { "auth", AUTH },
> { "authkey", AUTHKEY },
> + { "blocklist", BLOCKLIST },
> { "community", COMMUNITY },
> { "contact", CONTACT },
> { "default", DEFAULT },
> Index: snmpd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/snmpd.conf.5,v
> retrieving revision 1.59
> diff -u -p -r1.59 snmpd.conf.5
> --- snmpd.conf.5 31 Mar 2022 17:27:31 -0000 1.59
> +++ snmpd.conf.5 29 Jun 2022 11:35:23 -0000
> @@ -78,15 +78,13 @@ listen on $ext_addr
> .Sh GLOBAL CONFIGURATION
> The following options can be set globally:
> .Bl -tag -width Ds
> -.It Ic filter-pf-addresses Pq Ic yes | no
> -If set to
> -.Ic yes ,
> -.Xr snmpd 8
> -will filter out the OPENBSD-PF-MIB::pfTblAddrTable tree.
> -Addresses stored in PF tables will not be available, but CPU use will be
> -reduced during bulk walks.
> -The default is
> -.Ic no .
> +.It Ic blocklist Ar oid
> +Remove the
> +.Ar oid
> +subtree from view.
> +Multiple
> +.Ic blocklist
> +statements are supported.
> .It Ic filter-routes Pq Ic yes | no
> If set to
> .Ic yes ,
> Index: snmpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
> retrieving revision 1.102
> diff -u -p -r1.102 snmpd.h
> --- snmpd.h 19 Jan 2022 10:25:04 -0000 1.102
> +++ snmpd.h 29 Jun 2022 11:35:23 -0000
> @@ -591,8 +591,9 @@ struct snmpd {
>
> int sc_ncpu;
> int64_t *sc_cpustates;
> + struct ber_oid *sc_blocklist;
> + size_t sc_nblocklist;
> int sc_rtfilter;
> - int sc_pfaddrfilter;
>
> int sc_min_seclevel;
> int sc_traphandler;
>