From owner-dev-commits-src-branches@freebsd.org Mon Sep 6 10:39:21 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A96CF67258C; Mon, 6 Sep 2021 10:39:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4H34dj47bDz3KM4; Mon, 6 Sep 2021 10:39:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6A0911D620; Mon, 6 Sep 2021 10:39:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 186AdLPQ039482; Mon, 6 Sep 2021 10:39:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 186AdLCw039481; Mon, 6 Sep 2021 10:39:21 GMT (envelope-from git) Date: Mon, 6 Sep 2021 10:39:21 GMT Message-Id: <202109061039.186AdLCw039481@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: ff54f3762f0d - stable/12 - pf: Introduce nvlist variant of DIOCGETSTATUS MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: ff54f3762f0dfc40b079075a0dd44a84e5d9225e Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Sep 2021 10:39:21 -0000 The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=ff54f3762f0dfc40b079075a0dd44a84e5d9225e commit ff54f3762f0dfc40b079075a0dd44a84e5d9225e Author: Kristof Provost AuthorDate: 2021-08-16 19:55:27 +0000 Commit: Kristof Provost CommitDate: 2021-09-06 08:06:34 +0000 pf: Introduce nvlist variant of DIOCGETSTATUS Make it possible to extend the GETSTATUS call (e.g. when we want to add new counters, such as for syncookie support) by introducing an nvlist-based alternative. MFC after: 1 week Sponsored by: Modirum MDPay Differential Revision: https://reviews.freebsd.org/D31694 (cherry picked from commit 2b10cf85f8684f822511d7b9377e256ab623abbc) --- sys/net/pfvar.h | 1 + sys/netpfil/pf/pf.h | 9 ++++ sys/netpfil/pf/pf_ioctl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 624456149162..0b1e3f3a27a2 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1665,6 +1665,7 @@ struct pfioc_iface { #define DIOCGETSTATENV _IOWR('D', 19, struct pfioc_nv) #define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if) #define DIOCGETSTATUS _IOWR('D', 21, struct pf_status) +#define DIOCGETSTATUSNV _IOWR('D', 21, struct pfioc_nv) #define DIOCCLRSTATUS _IO ('D', 22) #define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook) #define DIOCSETDEBUG _IOWR('D', 24, u_int32_t) diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index e030f1e59de0..319cd8164d8d 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -179,6 +179,15 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL, #define FCNT_STATE_REMOVALS 2 #define FCNT_MAX 3 +#ifdef _KERNEL +#define FCNT_NAMES { \ + "searches", \ + "inserts", \ + "removals", \ + NULL \ +} +#endif + /* src_node operation counters */ #define SCNT_SRC_NODE_SEARCH 0 #define SCNT_SRC_NODE_INSERT 1 diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 4f1786b36a30..c1cb8e0435de 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -209,6 +209,7 @@ static int pf_killstates_row(struct pf_kstate_kill *, static int pf_killstates_nv(struct pfioc_nv *); static int pf_clearstates_nv(struct pfioc_nv *); static int pf_getstate(struct pfioc_nv *); +static int pf_getstatus(struct pfioc_nv *); static int pf_clear_tables(void); static void pf_clear_srcnodes(struct pf_ksrc_node *); static void pf_kill_srcnodes(struct pfioc_src_node_kill *); @@ -2149,6 +2150,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCGETSTATENV: case DIOCSETSTATUSIF: case DIOCGETSTATUS: + case DIOCGETSTATUSNV: case DIOCCLRSTATUS: case DIOCNATLOOK: case DIOCSETDEBUG: @@ -2206,6 +2208,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCGETSTATE: case DIOCGETSTATENV: case DIOCGETSTATUS: + case DIOCGETSTATUSNV: case DIOCGETSTATES: case DIOCGETSTATESV2: case DIOCGETTIMEOUT: @@ -3074,6 +3077,11 @@ DIOCGETSTATESV2_full: break; } + case DIOCGETSTATUSNV: { + error = pf_getstatus((struct pfioc_nv *)addr); + break; + } + case DIOCSETSTATUSIF: { struct pfioc_if *pi = (struct pfioc_if *)addr; @@ -4902,6 +4910,131 @@ pf_tbladdr_copyout(struct pf_addr_wrap *aw) kt->pfrkt_cnt : -1; } +static int +pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t *counters, + size_t number, char **names) +{ + nvlist_t *nvc; + + nvc = nvlist_create(0); + if (nvc == NULL) + return (ENOMEM); + + for (int i = 0; i < number; i++) { + nvlist_append_number_array(nvc, "counters", + counter_u64_fetch(counters[i])); + nvlist_append_string_array(nvc, "names", + names[i]); + nvlist_append_number_array(nvc, "ids", + i); + } + nvlist_add_nvlist(nvl, name, nvc); + nvlist_destroy(nvc); + + return (0); +} + +static int +pf_getstatus(struct pfioc_nv *nv) +{ + nvlist_t *nvl = NULL, *nvc = NULL; + void *nvlpacked = NULL; + int error; + struct pf_status s; + char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; + char *pf_lcounter[LCNT_MAX+1] = LCNT_NAMES; + char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES; + PF_RULES_RLOCK_TRACKER; + +#define ERROUT(x) ERROUT_FUNCTION(errout, x) + + PF_RULES_RLOCK(); + + nvl = nvlist_create(0); + if (nvl == NULL) + ERROUT(ENOMEM); + + nvlist_add_bool(nvl, "running", V_pf_status.running); + nvlist_add_number(nvl, "since", V_pf_status.since); + nvlist_add_number(nvl, "debug", V_pf_status.debug); + nvlist_add_number(nvl, "hostid", V_pf_status.hostid); + nvlist_add_number(nvl, "states", V_pf_status.states); + nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes); + + /* counters */ + error = pf_add_status_counters(nvl, "counters", V_pf_status.counters, + PFRES_MAX, pf_reasons); + if (error != 0) + ERROUT(error); + + /* lcounters */ + error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters, + LCNT_MAX, pf_lcounter); + if (error != 0) + ERROUT(error); + + /* fcounters */ + nvc = nvlist_create(0); + if (nvc == NULL) + ERROUT(ENOMEM); + + for (int i = 0; i < FCNT_MAX; i++) { + nvlist_append_number_array(nvc, "counters", + pf_counter_u64_fetch(&V_pf_status.fcounters[i])); + nvlist_append_string_array(nvc, "names", + pf_fcounter[i]); + nvlist_append_number_array(nvc, "ids", + i); + } + nvlist_add_nvlist(nvl, "fcounters", nvc); + nvlist_destroy(nvc); + nvc = NULL; + + /* scounters */ + error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters, + SCNT_MAX, pf_fcounter); + if (error != 0) + ERROUT(error); + + nvlist_add_string(nvl, "ifname", V_pf_status.ifname); + nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum, + PF_MD5_DIGEST_LENGTH); + + pfi_update_status(V_pf_status.ifname, &s); + + /* pcounters / bcounters */ + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + for (int k = 0; k < 2; k++) { + nvlist_append_number_array(nvl, "pcounters", + s.pcounters[i][j][k]); + } + nvlist_append_number_array(nvl, "bcounters", + s.bcounters[i][j]); + } + } + + nvlpacked = nvlist_pack(nvl, &nv->len); + if (nvlpacked == NULL) + ERROUT(ENOMEM); + + if (nv->size == 0) + ERROUT(0); + else if (nv->size < nv->len) + ERROUT(ENOSPC); + + error = copyout(nvlpacked, nv->data, nv->len); + +#undef ERROUT +errout: + PF_RULES_RUNLOCK(); + free(nvlpacked, M_NVLIST); + nvlist_destroy(nvc); + nvlist_destroy(nvl); + + return (error); +} + /* * XXX - Check for version missmatch!!! */