From nobody Mon Apr 29 14:36:50 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4VSm9t42lzz5JS20; Mon, 29 Apr 2024 14:36:50 +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 4VSm9t3PT9z4KPx; Mon, 29 Apr 2024 14:36:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1714401410; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rTnTtzHZagH82wUOAk5lGaVGnDJaZYIXKqV+AD6ZpCs=; b=UAbAuNoEyXn/CfVlrJw8wA9a5Ywkj/6ygtfA13QzpxAhl+v63B1MJ9Ay2LKSC03bGUw+CA icF+8SAyzqrd/cOJIqC0R4Cnxd19jtN5H3tesIBXkDbnibbhY+WRSataGuJJVUjhX9sujp YUQERZN4MuE7zazfbumPs0o9vy8SueMpoOjjQf+FsvAfaoBUAOTiEPjsXJ916xwREyDSSR GiU8llYu9V3zWEf3HjPDTRG9qe0wM0aMhXX8wjIyTDjl6o6ayJwW2MiTtwNAYGz4Iks8nN c5061xR+XHvQwXVLJwcVf33kO5wWYquuXG3PsoCkBrQX/jGHkQBn7GGO6T/xcA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1714401410; a=rsa-sha256; cv=none; b=KG1nkgDsIVozy7Nzrk2ryO/P/T8YPFT80qsBjXbazM0iPKdBqZOFsc8JryCHCm9DKHoI8+ xSbhMrP7vmV2zTd+rej1KSTKpL7vcIxJ9HxeKBG8WxdbHg9UzFFWl2RAmJWZ2X58JQwEv2 xofPeei/zLLZYu+J8DU/inM6LKiKm8C58KgsrjIc9B1xr/3x5Rgd1Baw1il+4CbOr3NDFZ SoNx9Rfmjf2Ck45AUstmYeBRbAz14vT1nkBJxkOqONVcVxJHXCmIfVK3GkFscnGbG7JjFU 0sqR6icRBkA+vdrI8OPl45YXvyu1gjkaFVgUm1vuIi7MXNWEQS6C0bu7HvzXkg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1714401410; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=rTnTtzHZagH82wUOAk5lGaVGnDJaZYIXKqV+AD6ZpCs=; b=sJ1L4e89hXiF9Ki0DbuzCWDrhnTMxlXNEmEUNXod+02kJyQhvXlrQzBopN/ruAfGGLATRG AgYbPSWy6mQtf7HTpjTw8QCs7sp++ffW9AwBYCQSYgJxhLHLV+fL4JaWszmNYqejnyjf3S d9yvSPp5HIVlB/KCkIBuB6v+6RZntMuvvEp50QShtqcqO+/p6JnhFg0dSuLAE23YdFLtKf W66pUWitG7dCcM0sIvFaetv45Mw5XV2IzprePA7Ih+xBiPHdY8GVZzm9/JYvzpRSubULxi sAe+SrvZBrEvZUaKdSMNarNTh29LIcekBA6r1kYxr3hVsesaZ3NhBso3WIP9uA== 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 4VSm9t2W3Xz1Bkb; Mon, 29 Apr 2024 14:36:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 43TEao29080649; Mon, 29 Apr 2024 14:36:50 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 43TEaoh6080646; Mon, 29 Apr 2024 14:36:50 GMT (envelope-from git) Date: Mon, 29 Apr 2024 14:36:50 GMT Message-Id: <202404291436.43TEaoh6080646@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 5824df8d991c - main - pf: convert DIOCGETSTATUS to netlink List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org 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/main X-Git-Reftype: branch X-Git-Commit: 5824df8d991c32def616c51994161e60e5b78948 Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=5824df8d991c32def616c51994161e60e5b78948 commit 5824df8d991c32def616c51994161e60e5b78948 Author: Kristof Provost AuthorDate: 2024-03-23 06:31:51 +0000 Commit: Kristof Provost CommitDate: 2024-04-29 14:32:23 +0000 pf: convert DIOCGETSTATUS to netlink Introduce pfctl_get_status_h() because we need the pfctl_handle. In this variant use netlink to obtain the information. Sponsored by: Rubicon Communications, LLC ("Netgate") --- contrib/pf/ftp-proxy/filter.c | 2 +- contrib/pf/tftp-proxy/filter.c | 2 +- lib/libpfctl/libpfctl.c | 147 ++++++++++++++++++++++++++++++ lib/libpfctl/libpfctl.h | 1 + sbin/pfctl/pfctl.c | 4 +- sys/netlink/netlink_message_writer.h | 6 ++ sys/netlink/netlink_snl.h | 11 +++ sys/netpfil/pf/pf_nl.c | 114 ++++++++++++++++++++++- sys/netpfil/pf/pf_nl.h | 29 ++++++ usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c | 35 +++---- 10 files changed, 329 insertions(+), 22 deletions(-) diff --git a/contrib/pf/ftp-proxy/filter.c b/contrib/pf/ftp-proxy/filter.c index 3bad5feb4be4..7893be97f9b2 100644 --- a/contrib/pf/ftp-proxy/filter.c +++ b/contrib/pf/ftp-proxy/filter.c @@ -183,7 +183,7 @@ init_filter(const char *opt_qname, const char *opt_tagname, int opt_verbose) pfh = pfctl_open(PF_DEVICE); if (pfh == NULL) err(1, "pfctl_open"); - status = pfctl_get_status(pfctl_fd(pfh)); + status = pfctl_get_status_h(pfh); if (status == NULL) err(1, "DIOCGETSTATUS"); if (!status->running) diff --git a/contrib/pf/tftp-proxy/filter.c b/contrib/pf/tftp-proxy/filter.c index b69247caf04f..1e6d54303996 100644 --- a/contrib/pf/tftp-proxy/filter.c +++ b/contrib/pf/tftp-proxy/filter.c @@ -188,7 +188,7 @@ init_filter(char *opt_qname, int opt_verbose) syslog(LOG_ERR, "can't pfctl_open()"); exit(1); } - status = pfctl_get_status(pfctl_fd(pfh)); + status = pfctl_get_status_h(pfh); if (status == NULL) { syslog(LOG_ERR, "DIOCGETSTATUS"); exit(1); diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 5b9500980996..6da3b6969107 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -287,6 +287,153 @@ _pfctl_get_status_counters(const nvlist_t *nvl, } } +#define _OUT(_field) offsetof(struct pfctl_status_counter, _field) +static const struct snl_attr_parser ap_counter[] = { + { .type = PF_C_COUNTER, .off = _OUT(counter), .cb = snl_attr_get_uint64 }, + { .type = PF_C_NAME, .off = _OUT(name), .cb = snl_attr_get_string }, + { .type = PF_C_ID, .off = _OUT(id), .cb = snl_attr_get_uint32 }, +}; +SNL_DECLARE_ATTR_PARSER(counter_parser, ap_counter); +#undef _OUT + +static bool +snl_attr_get_counters(struct snl_state *ss, struct nlattr *nla, + const void *arg __unused, void *target) +{ + struct pfctl_status_counter counter = {}; + struct pfctl_status_counter *c; + bool error; + + error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &counter_parser, &counter); + if (! error) + return (error); + + c = malloc(sizeof(*c)); + if (c == NULL) + return (false); + + c->id = counter.id; + c->counter = counter.counter; + c->name = strdup(counter.name); + + TAILQ_INSERT_TAIL((struct pfctl_status_counters *)target, c, entry); + + return (error); +} + +struct snl_uint64_array { + uint64_t *array; + size_t count; + size_t max; +}; +static bool +snl_attr_get_uint64_element(struct snl_state *ss, struct nlattr *nla, + const void *arg, void *target) +{ + bool error; + uint64_t value; + struct snl_uint64_array *t = (struct snl_uint64_array *)target; + + if (t->count >= t->max) + return (false); + + error = snl_attr_get_uint64(ss, nla, arg, &value); + if (! error) + return (error); + + t->array[t->count++] = value; + + return (true); +} + +static const struct snl_attr_parser ap_array[] = { + { .cb = snl_attr_get_uint64_element }, +}; +SNL_DECLARE_ATTR_PARSER(array_parser, ap_array); +static bool +snl_attr_get_uint64_array(struct snl_state *ss, struct nlattr *nla, + const void *arg, void *target) +{ + struct snl_uint64_array a = { + .array = target, + .count = 0, + .max = (size_t)arg, + }; + bool error; + + error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &array_parser, &a); + if (! error) + return (error); + + return (true); +} + +#define _OUT(_field) offsetof(struct pfctl_status, _field) +static const struct snl_attr_parser ap_getstatus[] = { + { .type = PF_GS_IFNAME, .off = _OUT(ifname), .arg_u32 = IFNAMSIZ, .cb = snl_attr_copy_string }, + { .type = PF_GS_RUNNING, .off = _OUT(running), .cb = snl_attr_get_bool }, + { .type = PF_GS_SINCE, .off = _OUT(since), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_DEBUG, .off = _OUT(debug), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_HOSTID, .off = _OUT(hostid), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_STATES, .off = _OUT(states), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_SRC_NODES, .off = _OUT(src_nodes), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_REASSEMBLE, .off = _OUT(reass), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_SYNCOOKIES_ACTIVE, .off = _OUT(syncookies_active), .cb = snl_attr_get_uint32 }, + { .type = PF_GS_COUNTERS, .off = _OUT(counters), .cb = snl_attr_get_counters }, + { .type = PF_GS_LCOUNTERS, .off = _OUT(lcounters), .cb = snl_attr_get_counters }, + { .type = PF_GS_FCOUNTERS, .off = _OUT(fcounters), .cb = snl_attr_get_counters }, + { .type = PF_GS_SCOUNTERS, .off = _OUT(scounters), .cb = snl_attr_get_counters }, + { .type = PF_GS_CHKSUM, .off = _OUT(pf_chksum), .arg_u32 = PF_MD5_DIGEST_LENGTH, .cb = snl_attr_get_bytes }, + { .type = PF_GS_BCOUNTERS, .off = _OUT(bcounters), .arg_u32 = 2 * 2, .cb = snl_attr_get_uint64_array }, + { .type = PF_GS_PCOUNTERS, .off = _OUT(pcounters), .arg_u32 = 2 * 2 * 2, .cb = snl_attr_get_uint64_array }, +}; +static struct snl_field_parser fp_getstatus[] = {}; +SNL_DECLARE_PARSER(getstatus_parser, struct genlmsghdr, fp_getstatus, ap_getstatus); +#undef _OUT + +struct pfctl_status * +pfctl_get_status_h(struct pfctl_handle *h __unused) +{ + struct pfctl_status *status; + struct snl_errmsg_data e = {}; + struct nlmsghdr *hdr; + struct snl_writer nw; + uint32_t seq_id; + int family_id; + + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); + if (family_id == 0) + return (NULL); + + snl_init_writer(&h->ss, &nw); + hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GET_STATUS); + hdr->nlmsg_flags |= NLM_F_DUMP; + + hdr = snl_finalize_msg(&nw); + if (hdr == NULL) { + return (NULL); + } + + seq_id = hdr->nlmsg_seq; + if (! snl_send_message(&h->ss, hdr)) + return (NULL); + + status = calloc(1, sizeof(*status)); + if (status == NULL) + return (NULL); + TAILQ_INIT(&status->counters); + TAILQ_INIT(&status->lcounters); + TAILQ_INIT(&status->fcounters); + TAILQ_INIT(&status->scounters); + + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { + if (! snl_parse_nlmsg(&h->ss, hdr, &getstatus_parser, status)) + continue; + } + + return (status); +} + struct pfctl_status * pfctl_get_status(int dev) { diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index a290fa45501a..2937a36a8a47 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -393,6 +393,7 @@ void pfctl_close(struct pfctl_handle *); int pfctl_fd(struct pfctl_handle *); int pfctl_startstop(struct pfctl_handle *h, int start); +struct pfctl_status* pfctl_get_status_h(struct pfctl_handle *h); struct pfctl_status* pfctl_get_status(int dev); uint64_t pfctl_status_counter(struct pfctl_status *status, int id); uint64_t pfctl_status_lcounter(struct pfctl_status *status, int id); diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 8d59871701f8..17901b04a130 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1578,7 +1578,7 @@ pfctl_show_status(int dev, int opts) struct pfctl_status *status; struct pfctl_syncookies cookies; - if ((status = pfctl_get_status(dev)) == NULL) { + if ((status = pfctl_get_status_h(pfh)) == NULL) { warn("DIOCGETSTATUS"); return (-1); } @@ -1600,7 +1600,7 @@ pfctl_show_running(int dev) struct pfctl_status *status; int running; - if ((status = pfctl_get_status(dev)) == NULL) { + if ((status = pfctl_get_status_h(pfh)) == NULL) { warn("DIOCGETSTATUS"); return (-1); } diff --git a/sys/netlink/netlink_message_writer.h b/sys/netlink/netlink_message_writer.h index 28f3fb78018c..cb771cf93e53 100644 --- a/sys/netlink/netlink_message_writer.h +++ b/sys/netlink/netlink_message_writer.h @@ -225,6 +225,12 @@ nlattr_add_raw(struct nl_writer *nw, const struct nlattr *nla_src) return (nlattr_add(nw, nla_src->nla_type, attr_len, (const void *)(nla_src + 1))); } +static inline bool +nlattr_add_bool(struct nl_writer *nw, int attrtype, bool value) +{ + return (nlattr_add(nw, attrtype, sizeof(bool), &value)); +} + static inline bool nlattr_add_u8(struct nl_writer *nw, int attrtype, uint8_t value) { diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h index 6553a391a8f5..7550800bb0f7 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -537,6 +537,17 @@ snl_attr_get_bytes(struct snl_state *ss __unused, struct nlattr *nla, const void return (true); } +static inline bool +snl_attr_get_bool(struct snl_state *ss __unused, struct nlattr *nla, + const void *arg __unused, void *target) +{ + if (NLA_DATA_LEN(nla) == sizeof(bool)) { + *((bool *)target) = *((const bool *)NLA_DATA_CONST(nla)); + return (true); + } + return (false); +} + static inline bool snl_attr_get_uint8(struct snl_state *ss __unused, struct nlattr *nla, const void *arg __unused, void *target) diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index 5f33e49b4a2e..307e1ca1689d 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -1109,6 +1109,111 @@ pf_handle_set_statusif(struct nlmsghdr *hdr, struct nl_pstate *npt) return (0); } +static bool +nlattr_add_counters(struct nl_writer *nw, int attr, size_t number, char **names, + counter_u64_t *counters) +{ + for (int i = 0; i < number; i++) { + int off = nlattr_add_nested(nw, attr); + nlattr_add_u32(nw, PF_C_ID, i); + nlattr_add_string(nw, PF_C_NAME, names[i]); + nlattr_add_u64(nw, PF_C_COUNTER, counter_u64_fetch(counters[i])); + nlattr_set_len(nw, off); + } + + return (true); +} + +static bool +nlattr_add_fcounters(struct nl_writer *nw, int attr, size_t number, char **names, + struct pf_counter_u64 *counters) +{ + for (int i = 0; i < number; i++) { + int off = nlattr_add_nested(nw, attr); + nlattr_add_u32(nw, PF_C_ID, i); + nlattr_add_string(nw, PF_C_NAME, names[i]); + nlattr_add_u64(nw, PF_C_COUNTER, pf_counter_u64_fetch(&counters[i])); + nlattr_set_len(nw, off); + } + + return (true); +} + +static bool +nlattr_add_u64_array(struct nl_writer *nw, int attr, size_t number, uint64_t *array) +{ + int off = nlattr_add_nested(nw, attr); + + for (size_t i = 0; i < number; i++) + nlattr_add_u64(nw, 0, array[i]); + + nlattr_set_len(nw, off); + + return (true); +} + +static int +pf_handle_get_status(struct nlmsghdr *hdr, struct nl_pstate *npt) +{ + struct pf_status s; + struct nl_writer *nw = npt->nw; + struct genlmsghdr *ghdr_new; + char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; + char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES; + char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES; + int error; + + PF_RULES_RLOCK_TRACKER; + + if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) + return (ENOMEM); + + ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr); + ghdr_new->cmd = PFNL_CMD_GET_STATUS; + ghdr_new->version = 0; + ghdr_new->reserved = 0; + + PF_RULES_RLOCK(); + + nlattr_add_string(nw, PF_GS_IFNAME, V_pf_status.ifname); + nlattr_add_bool(nw, PF_GS_RUNNING, V_pf_status.running); + nlattr_add_u32(nw, PF_GS_SINCE, V_pf_status.since); + nlattr_add_u32(nw, PF_GS_DEBUG, V_pf_status.debug); + nlattr_add_u32(nw, PF_GS_HOSTID, ntohl(V_pf_status.hostid)); + nlattr_add_u32(nw, PF_GS_STATES, V_pf_status.states); + nlattr_add_u32(nw, PF_GS_SRC_NODES, V_pf_status.src_nodes); + nlattr_add_u32(nw, PF_GS_REASSEMBLE, V_pf_status.reass); + nlattr_add_u32(nw, PF_GS_SYNCOOKIES_ACTIVE, V_pf_status.syncookies_active); + + nlattr_add_counters(nw, PF_GS_COUNTERS, PFRES_MAX, pf_reasons, + V_pf_status.counters); + nlattr_add_counters(nw, PF_GS_LCOUNTERS, KLCNT_MAX, pf_lcounter, + V_pf_status.lcounters); + nlattr_add_fcounters(nw, PF_GS_FCOUNTERS, FCNT_MAX, pf_fcounter, + V_pf_status.fcounters); + nlattr_add_counters(nw, PF_GS_SCOUNTERS, SCNT_MAX, pf_fcounter, + V_pf_status.scounters); + + pfi_update_status(V_pf_status.ifname, &s); + nlattr_add_u64_array(nw, PF_GS_BCOUNTERS, 2 * 2, (uint64_t *)s.bcounters); + nlattr_add_u64_array(nw, PF_GS_PCOUNTERS, 2 * 2 * 2, (uint64_t *)s.pcounters); + + nlattr_add(nw, PF_GS_CHKSUM, PF_MD5_DIGEST_LENGTH, V_pf_status.pf_chksum); + + PF_RULES_RUNLOCK(); + + if (!nlmsg_end(nw)) { + error = ENOMEM; + goto out; + } + + return (0); + +out: + nlmsg_abort(nw); + return (error); +} + static const struct nlhdr_parser *all_parsers[] = { &state_parser, &addrule_parser, @@ -1189,7 +1294,14 @@ static const struct genl_cmd pf_cmds[] = { .cmd_cb = pf_handle_set_statusif, .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL, .cmd_priv = PRIV_NETINET_PF, - } + }, + { + .cmd_num = PFNL_CMD_GET_STATUS, + .cmd_name = "GETSTATUS", + .cmd_cb = pf_handle_get_status, + .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL, + .cmd_priv = PRIV_NETINET_PF, + }, }; void diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h index c44e331722b7..e486e9781b2e 100644 --- a/sys/netpfil/pf/pf_nl.h +++ b/sys/netpfil/pf/pf_nl.h @@ -46,6 +46,7 @@ enum { PFNL_CMD_CLRSTATES = 8, PFNL_CMD_KILLSTATES = 9, PFNL_CMD_SET_STATUSIF = 10, + PFNL_CMD_GET_STATUS = 11, __PFNL_CMD_MAX, }; #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1) @@ -286,6 +287,34 @@ enum pf_set_statusif_types_t { PF_SS_UNSPEC, PF_SS_IFNAME = 1, /* string */ }; + +enum pf_counter_types_t { + PF_C_UNSPEC, + PF_C_COUNTER = 1, /* u64 */ + PF_C_NAME = 2, /* string */ + PF_C_ID = 3, /* u32 */ +}; + +enum pf_get_status_types_t { + PF_GS_UNSPEC, + PF_GS_IFNAME = 1, /* string */ + PF_GS_RUNNING = 2, /* bool */ + PF_GS_SINCE = 3, /* u32 */ + PF_GS_DEBUG = 4, /* u32 */ + PF_GS_HOSTID = 5, /* u32 */ + PF_GS_STATES = 6, /* u32 */ + PF_GS_SRC_NODES = 7, /* u32 */ + PF_GS_REASSEMBLE = 8, /* u32 */ + PF_GS_SYNCOOKIES_ACTIVE = 9, /* bool */ + PF_GS_COUNTERS = 10, /* nested, */ + PF_GS_LCOUNTERS = 11, /* nested, */ + PF_GS_FCOUNTERS = 12, /* nested, */ + PF_GS_SCOUNTERS = 13, /* nested, */ + PF_GS_CHKSUM = 14, /* byte array */ + PF_GS_PCOUNTERS = 15, /* u64 array */ + PF_GS_BCOUNTERS = 16, /* u64 array */ +}; + #ifdef _KERNEL void pf_nl_register(void); diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c index bb064dd549d2..e618683845be 100644 --- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c +++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c @@ -50,7 +50,7 @@ struct lmodule *module; -static int dev = -1; +static struct pfctl_handle *pfh; static int started; static uint64_t pf_tick; @@ -341,7 +341,7 @@ pf_limits(struct snmp_context __unused *ctx, struct snmp_value *val, return (SNMP_ERR_NOSUCHNAME); } - if (ioctl(dev, DIOCGETLIMIT, &pl)) { + if (ioctl(pfctl_fd(pfh), DIOCGETLIMIT, &pl)) { syslog(LOG_ERR, "pf_limits(): ioctl(): %s", strerror(errno)); return (SNMP_ERR_GENERR); @@ -431,7 +431,7 @@ pf_timeouts(struct snmp_context __unused *ctx, struct snmp_value *val, return (SNMP_ERR_NOSUCHNAME); } - if (ioctl(dev, DIOCGETTIMEOUT, &pt)) { + if (ioctl(pfctl_fd(pfh), DIOCGETTIMEOUT, &pt)) { syslog(LOG_ERR, "pf_timeouts(): ioctl(): %s", strerror(errno)); return (SNMP_ERR_GENERR); @@ -1174,7 +1174,7 @@ pfi_refresh(void) io.pfiio_size = numifs; io.pfiio_buffer = p; - if (ioctl(dev, DIOCIGETIFACES, &io)) { + if (ioctl(pfctl_fd(pfh), DIOCIGETIFACES, &io)) { syslog(LOG_ERR, "pfi_refresh(): ioctl(): %s", strerror(errno)); goto err2; @@ -1231,7 +1231,7 @@ pfq_refresh(void) bzero(&pa, sizeof(pa)); pa.version = PFIOC_ALTQ_VERSION; - if (ioctl(dev, DIOCGETALTQS, &pa)) { + if (ioctl(pfctl_fd(pfh), DIOCGETALTQS, &pa)) { syslog(LOG_ERR, "pfq_refresh: ioctl(DIOCGETALTQS): %s", strerror(errno)); return (-1); @@ -1251,7 +1251,7 @@ pfq_refresh(void) pa.ticket = ticket; pa.nr = i; - if (ioctl(dev, DIOCGETALTQ, &pa)) { + if (ioctl(pfctl_fd(pfh), DIOCGETALTQ, &pa)) { syslog(LOG_ERR, "pfq_refresh(): " "ioctl(DIOCGETALTQ): %s", strerror(errno)); @@ -1287,7 +1287,7 @@ pfs_refresh(void) return (0); pfctl_free_status(pfs); - pfs = pfctl_get_status(dev); + pfs = pfctl_get_status_h(pfh); if (pfs == NULL) { syslog(LOG_ERR, "pfs_refresh(): ioctl(): %s", @@ -1329,7 +1329,7 @@ pft_refresh(void) io.pfrio_size = numtbls; io.pfrio_buffer = t; - if (ioctl(dev, DIOCRGETTSTATS, &io)) { + if (ioctl(pfctl_fd(pfh), DIOCRGETTSTATS, &io)) { syslog(LOG_ERR, "pft_refresh(): ioctl(): %s", strerror(errno)); goto err2; @@ -1396,7 +1396,7 @@ pfa_table_addrs(u_int sidx, struct pfr_table *pt) io.pfrio_buffer = t; io.pfrio_esize = sizeof(struct pfr_astats); - if (ioctl(dev, DIOCRGETASTATS, &io)) { + if (ioctl(pfctl_fd(pfh), DIOCRGETASTATS, &io)) { syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s", pt->pfrt_name, strerror(errno)); numaddrs = -1; @@ -1464,7 +1464,7 @@ pfa_refresh(void) io.pfrio_size = numtbls; io.pfrio_buffer = pt; - if (ioctl(dev, DIOCRGETTABLES, &io)) { + if (ioctl(pfctl_fd(pfh), DIOCRGETTABLES, &io)) { syslog(LOG_ERR, "pfa_refresh(): ioctl(): %s", strerror(errno)); goto err2; @@ -1519,14 +1519,14 @@ pfl_scan_ruleset(const char *path) struct pfl_entry *e; u_int32_t nr, i; - if (pfctl_get_rules_info(dev, &rules, PF_PASS, path)) { + if (pfctl_get_rules_info(pfctl_fd(pfh), &rules, PF_PASS, path)) { syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULES): %s", strerror(errno)); goto err; } for (nr = rules.nr, i = 0; i < nr; i++) { - if (pfctl_get_rule(dev, i, rules.ticket, path, + if (pfctl_get_rule(pfctl_fd(pfh), i, rules.ticket, path, PF_PASS, &rule, anchor_call)) { syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULE):" " %s", strerror(errno)); @@ -1572,7 +1572,7 @@ pfl_walk_rulesets(const char *path) bzero(&prs, sizeof(prs)); strlcpy(prs.path, path, sizeof(prs.path)); - if (ioctl(dev, DIOCGETRULESETS, &prs)) { + if (ioctl(pfctl_fd(pfh), DIOCGETRULESETS, &prs)) { syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESETS): %s", strerror(errno)); goto err; @@ -1580,7 +1580,7 @@ pfl_walk_rulesets(const char *path) for (nr = prs.nr, i = 0; i < nr; i++) { prs.nr = i; - if (ioctl(dev, DIOCGETRULESET, &prs)) { + if (ioctl(pfctl_fd(pfh), DIOCGETRULESET, &prs)) { syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESET):" " %s", strerror(errno)); goto err; @@ -1671,13 +1671,13 @@ pf_init(struct lmodule *mod, int __unused argc, char __unused *argv[]) { module = mod; - if ((dev = open("/dev/pf", O_RDONLY)) == -1) { + if ((pfh = pfctl_open(PF_DEVICE)) == NULL) { syslog(LOG_ERR, "pf_init(): open(): %s\n", strerror(errno)); return (-1); } - if ((altq_enabled = altq_is_enabled(dev)) == -1) { + if ((altq_enabled = altq_is_enabled(pfctl_fd(pfh))) == -1) { syslog(LOG_ERR, "pf_init(): altq test failed"); return (-1); } @@ -1756,7 +1756,8 @@ pf_fini(void) pfctl_free_status(pfs); pfs = NULL; - close(dev); + pfctl_close(pfh); + return (0); }