The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=d9ab8999313845e87c67532437a0441d9cd57e72

commit d9ab8999313845e87c67532437a0441d9cd57e72
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2024-06-07 01:08:50 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2024-06-07 18:59:02 +0000

    pf: migrate DIOCGETLIMIT/DIOCSETLIMIT to netlink
    
    Event:          Kitchener-Waterloo Hackathon 202406
---
 lib/libpfctl/libpfctl.c                   | 88 +++++++++++++++++++++++++++++--
 lib/libpfctl/libpfctl.h                   |  2 +
 sbin/pfctl/parse.y                        |  2 +-
 sbin/pfctl/pfctl.c                        | 19 +++----
 sbin/pfctl/pfctl_parser.h                 |  2 +-
 sys/net/pfvar.h                           |  2 +
 sys/netpfil/pf/pf_ioctl.c                 | 56 +++++++++++++-------
 sys/netpfil/pf/pf_nl.c                    | 76 ++++++++++++++++++++++++++
 sys/netpfil/pf/pf_nl.h                    |  8 +++
 tests/sys/netpfil/pf/Makefile             |  1 +
 tests/sys/netpfil/pf/limits.sh            | 66 +++++++++++++++++++++++
 usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c | 14 +++--
 12 files changed, 291 insertions(+), 45 deletions(-)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index a31fe6f0aff4..ebe52e7a415f 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2213,7 +2213,7 @@ pfctl_clear_eth_rules(int dev, const char *anchorname)
 }
 
 static int
-pfctl_get_limit(int dev, const int index, uint *limit)
+_pfctl_get_limit(int dev, const int index, uint *limit)
 {
        struct pfioc_limit pl;
 
@@ -2237,7 +2237,7 @@ pfctl_set_syncookies(int dev, const struct 
pfctl_syncookies *s)
        uint             state_limit;
        uint64_t         lim, hi, lo;
 
-       ret = pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit);
+       ret = _pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit);
        if (ret != 0)
                return (ret);
 
@@ -2274,7 +2274,7 @@ pfctl_get_syncookies(int dev, struct pfctl_syncookies *s)
        uint             state_limit;
        bool             enabled, adaptive;
 
-       ret = pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit);
+       ret = _pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit);
        if (ret != 0)
                return (ret);
 
@@ -2606,3 +2606,85 @@ pfctl_get_timeout(struct pfctl_handle *h, uint32_t 
timeout, uint32_t *seconds)
        return (e.error);
 }
 
+int
+pfctl_set_limit(struct pfctl_handle *h, const int index, const uint limit)
+{
+       struct snl_writer nw;
+       struct snl_errmsg_data e = {};
+       struct nlmsghdr *hdr;
+       uint32_t seq_id;
+       int family_id;
+
+       family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+       if (family_id == 0)
+               return (ENOTSUP);
+
+       snl_init_writer(&h->ss, &nw);
+       hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_SET_LIMIT);
+
+       snl_add_msg_attr_u32(&nw, PF_LI_INDEX, index);
+       snl_add_msg_attr_u32(&nw, PF_LI_LIMIT, limit);
+
+       if ((hdr = snl_finalize_msg(&nw)) == NULL)
+               return (ENXIO);
+
+       seq_id = hdr->nlmsg_seq;
+
+       if (! snl_send_message(&h->ss, hdr))
+               return (ENXIO);
+
+       while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+       }
+
+       return (e.error);
+}
+
+struct pfctl_nl_limit {
+       unsigned int limit;
+};
+#define        _OUT(_field)    offsetof(struct pfctl_nl_limit, _field)
+static struct snl_attr_parser ap_get_limit[] = {
+       { .type = PF_LI_LIMIT, .off = _OUT(limit), .cb = snl_attr_get_uint32 },
+};
+static struct snl_field_parser fp_get_limit[] = {};
+#undef _OUT
+SNL_DECLARE_PARSER(get_limit_parser, struct genlmsghdr, fp_get_limit, 
ap_get_limit);
+
+int
+pfctl_get_limit(struct pfctl_handle *h, const int index, uint *limit)
+{
+       struct snl_writer nw;
+       struct pfctl_nl_limit li = {};
+       struct snl_errmsg_data e = {};
+       struct nlmsghdr *hdr;
+       uint32_t seq_id;
+       int family_id;
+
+       family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+       if (family_id == 0)
+               return (ENOTSUP);
+
+       snl_init_writer(&h->ss, &nw);
+       hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GET_LIMIT);
+       hdr->nlmsg_flags |= NLM_F_DUMP;
+
+       snl_add_msg_attr_u32(&nw, PF_LI_INDEX, index);
+
+       if ((hdr = snl_finalize_msg(&nw)) == NULL)
+               return (ENXIO);
+
+       seq_id = hdr->nlmsg_seq;
+
+       if (! snl_send_message(&h->ss, hdr))
+               return (ENXIO);
+
+       while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+               if (! snl_parse_nlmsg(&h->ss, hdr, &get_limit_parser, &li))
+                       continue;
+       }
+
+       if (limit != NULL)
+               *limit = li.limit;
+
+       return (e.error);
+}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 6d59d66a924a..44c7fa47e88d 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -495,5 +495,7 @@ int pfctl_natlook(struct pfctl_handle *h,
 int    pfctl_set_debug(struct pfctl_handle *h, uint32_t level);
 int    pfctl_set_timeout(struct pfctl_handle *h, uint32_t timeout, uint32_t 
seconds);
 int    pfctl_get_timeout(struct pfctl_handle *h, uint32_t timeout, uint32_t 
*seconds);
+int    pfctl_set_limit(struct pfctl_handle *h, const int index, const uint 
limit);
+int    pfctl_get_limit(struct pfctl_handle *h, const int index, uint *limit);
 
 #endif
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 2876eb6e89dc..d07a3fdc188e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -5198,7 +5198,7 @@ limit_spec        : STRING NUMBER
                                yyerror("only positive values permitted");
                                YYERROR;
                        }
-                       if (pfctl_set_limit(pf, $1, $2) != 0) {
+                       if (pfctl_apply_limit(pf, $1, $2) != 0) {
                                yyerror("unable to set limit %s %u", $1, $2);
                                free($1);
                                YYERROR;
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index d97043fc5c66..ec718f6b0a99 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1679,21 +1679,19 @@ pfctl_show_timeouts(int dev, int opts)
 int
 pfctl_show_limits(int dev, int opts)
 {
-       struct pfioc_limit pl;
+       unsigned int limit;
        int i;
 
        if (opts & PF_OPT_SHOWALL)
                pfctl_print_title("LIMITS:");
-       memset(&pl, 0, sizeof(pl));
        for (i = 0; pf_limits[i].name; i++) {
-               pl.index = pf_limits[i].index;
-               if (ioctl(dev, DIOCGETLIMIT, &pl))
+               if (pfctl_get_limit(pfh, pf_limits[i].index, &limit))
                        err(1, "DIOCGETLIMIT");
                printf("%-13s ", pf_limits[i].name);
-               if (pl.limit == UINT_MAX)
+               if (limit == UINT_MAX)
                        printf("unlimited\n");
                else
-                       printf("hard limit %8u\n", pl.limit);
+                       printf("hard limit %8u\n", limit);
        }
        return (0);
 }
@@ -2425,7 +2423,7 @@ pfctl_load_options(struct pfctl *pf)
 }
 
 int
-pfctl_set_limit(struct pfctl *pf, const char *opt, unsigned int limit)
+pfctl_apply_limit(struct pfctl *pf, const char *opt, unsigned int limit)
 {
        int i;
 
@@ -2451,12 +2449,7 @@ pfctl_set_limit(struct pfctl *pf, const char *opt, 
unsigned int limit)
 int
 pfctl_load_limit(struct pfctl *pf, unsigned int index, unsigned int limit)
 {
-       struct pfioc_limit pl;
-
-       memset(&pl, 0, sizeof(pl));
-       pl.index = index;
-       pl.limit = limit;
-       if (ioctl(pf->dev, DIOCSETLIMIT, &pl)) {
+       if (pfctl_set_limit(pf->h, index, limit)) {
                if (errno == EBUSY)
                        warnx("Current pool size exceeds requested hard limit");
                else
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 06ab5d052631..6de998b34e52 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -288,7 +288,7 @@ void        pfctl_clear_pool(struct pfctl_pool *);
 int    pfctl_apply_timeout(struct pfctl *, const char *, int, int);
 int    pfctl_set_reassembly(struct pfctl *, int, int);
 int    pfctl_set_optimization(struct pfctl *, const char *);
-int    pfctl_set_limit(struct pfctl *, const char *, unsigned int);
+int    pfctl_apply_limit(struct pfctl *, const char *, unsigned int);
 int    pfctl_set_logif(struct pfctl *, char *);
 int    pfctl_set_hostid(struct pfctl *, u_int32_t);
 int    pfctl_do_set_debug(struct pfctl *, char *);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 16d3d90f4862..eb36c0aee4d1 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2505,6 +2505,8 @@ int                        pf_ioctl_addrule(struct 
pf_krule *, uint32_t,
 void                    pf_ioctl_clear_status(void);
 int                     pf_ioctl_get_timeout(int, int *);
 int                     pf_ioctl_set_timeout(int, int, int *);
+int                     pf_ioctl_get_limit(int, unsigned int *);
+int                     pf_ioctl_set_limit(int, unsigned int, unsigned int *);
 
 void                    pf_krule_free(struct pf_krule *);
 void                    pf_krule_clear_counters(struct pf_krule *);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index cef50c00283b..af3f914982ec 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2483,6 +2483,40 @@ pf_ioctl_get_timeout(int timeout, int *seconds)
        return (0);
 }
 
+int
+pf_ioctl_set_limit(int index, unsigned int limit, unsigned int *old_limit)
+{
+
+       PF_RULES_WLOCK();
+       if (index < 0 || index >= PF_LIMIT_MAX ||
+           V_pf_limits[index].zone == NULL) {
+               PF_RULES_WUNLOCK();
+               return (EINVAL);
+       }
+       uma_zone_set_max(V_pf_limits[index].zone, limit);
+       if (old_limit != NULL)
+               *old_limit = V_pf_limits[index].limit;
+       V_pf_limits[index].limit = limit;
+       PF_RULES_WUNLOCK();
+
+       return (0);
+}
+
+int
+pf_ioctl_get_limit(int index, unsigned int *limit)
+{
+       PF_RULES_RLOCK_TRACKER;
+
+       if (index < 0 || index >= PF_LIMIT_MAX)
+               return (EINVAL);
+
+       PF_RULES_RLOCK();
+       *limit = V_pf_limits[index].limit;
+       PF_RULES_RUNLOCK();
+
+       return (0);
+}
+
 static int
 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread 
*td)
 {
@@ -3894,32 +3928,16 @@ DIOCGETSTATESV2_full:
        case DIOCGETLIMIT: {
                struct pfioc_limit      *pl = (struct pfioc_limit *)addr;
 
-               if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
-                       error = EINVAL;
-                       break;
-               }
-               PF_RULES_RLOCK();
-               pl->limit = V_pf_limits[pl->index].limit;
-               PF_RULES_RUNLOCK();
+               error = pf_ioctl_get_limit(pl->index, &pl->limit);
                break;
        }
 
        case DIOCSETLIMIT: {
                struct pfioc_limit      *pl = (struct pfioc_limit *)addr;
-               int                      old_limit;
+               unsigned int old_limit;
 
-               PF_RULES_WLOCK();
-               if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
-                   V_pf_limits[pl->index].zone == NULL) {
-                       PF_RULES_WUNLOCK();
-                       error = EINVAL;
-                       break;
-               }
-               uma_zone_set_max(V_pf_limits[pl->index].zone, pl->limit);
-               old_limit = V_pf_limits[pl->index].limit;
-               V_pf_limits[pl->index].limit = pl->limit;
+               error = pf_ioctl_set_limit(pl->index, pl->limit, &old_limit);
                pl->limit = old_limit;
-               PF_RULES_WUNLOCK();
                break;
        }
 
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 026f8caab535..57b1a4a6b5b3 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1410,6 +1410,67 @@ pf_handle_get_timeout(struct nlmsghdr *hdr, struct 
nl_pstate *npt)
        return (0);
 }
 
+struct pf_nl_set_limit
+{
+       uint32_t index;
+       uint32_t limit;
+};
+#define        _OUT(_field)    offsetof(struct pf_nl_set_limit, _field)
+static const struct nlattr_parser nla_p_set_limit[] = {
+       { .type = PF_LI_INDEX, .off = _OUT(index), .cb = nlattr_get_uint32 },
+       { .type = PF_LI_LIMIT, .off = _OUT(limit), .cb = nlattr_get_uint32 },
+};
+static const struct nlfield_parser nlf_p_set_limit[] = {};
+#undef _OUT
+NL_DECLARE_PARSER(set_limit_parser, struct genlmsghdr, nlf_p_set_limit, 
nla_p_set_limit);
+
+static int
+pf_handle_set_limit(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+       struct pf_nl_set_limit attrs = {};
+       int error;
+
+       error = nl_parse_nlmsg(hdr, &set_limit_parser, npt, &attrs);
+       if (error != 0)
+               return (error);
+
+       return (pf_ioctl_set_limit(attrs.index, attrs.limit, NULL));
+}
+
+static int
+pf_handle_get_limit(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+       struct pf_nl_set_limit attrs = {};
+       struct nl_writer *nw = npt->nw;
+       struct genlmsghdr *ghdr_new;
+       int error;
+
+       error = nl_parse_nlmsg(hdr, &set_limit_parser, npt, &attrs);
+       if (error != 0)
+               return (error);
+
+       error = pf_ioctl_get_limit(attrs.index, &attrs.limit);
+       if (error != 0)
+               return (error);
+
+       if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+               return (ENOMEM);
+
+       ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+       ghdr_new->cmd = PFNL_CMD_GET_LIMIT;
+       ghdr_new->version = 0;
+       ghdr_new->reserved = 0;
+
+       nlattr_add_u32(nw, PF_LI_LIMIT, attrs.limit);
+
+       if (!nlmsg_end(nw)) {
+               nlmsg_abort(nw);
+               return (ENOMEM);
+       }
+
+       return (0);
+}
+
 static const struct nlhdr_parser *all_parsers[] = {
        &state_parser,
        &addrule_parser,
@@ -1419,6 +1480,7 @@ static const struct nlhdr_parser *all_parsers[] = {
        &natlook_parser,
        &set_debug_parser,
        &set_timeout_parser,
+       &set_limit_parser,
 };
 
 static int family_id;
@@ -1536,6 +1598,20 @@ static const struct genl_cmd pf_cmds[] = {
                .cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
                .cmd_priv = PRIV_NETINET_PF,
        },
+       {
+               .cmd_num = PFNL_CMD_SET_LIMIT,
+               .cmd_name = "SET_LIMIT",
+               .cmd_cb = pf_handle_set_limit,
+               .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
+               .cmd_priv = PRIV_NETINET_PF,
+       },
+       {
+               .cmd_num = PFNL_CMD_GET_LIMIT,
+               .cmd_name = "GET_LIMIT",
+               .cmd_cb = pf_handle_get_limit,
+               .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 5f9d8166ca50..437cc6482dbb 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -52,6 +52,8 @@ enum {
        PFNL_CMD_SET_DEBUG = 14,
        PFNL_CMD_SET_TIMEOUT = 15,
        PFNL_CMD_GET_TIMEOUT = 16,
+       PFNL_CMD_SET_LIMIT = 17,
+       PFNL_CMD_GET_LIMIT = 18,
        __PFNL_CMD_MAX,
 };
 #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -342,6 +344,12 @@ enum pf_timeout_types_t {
        PF_TO_SECONDS           = 2, /* u32 */
 };
 
+enum pf_limit_types_t {
+       PF_LI_UNSPEC,
+       PF_LI_INDEX             = 1, /* u32 */
+       PF_LI_LIMIT             = 2, /* u32 */
+};
+
 #ifdef _KERNEL
 
 void   pf_nl_register(void);
diff --git a/tests/sys/netpfil/pf/Makefile b/tests/sys/netpfil/pf/Makefile
index 089db2f19766..2840dc92f2fa 100644
--- a/tests/sys/netpfil/pf/Makefile
+++ b/tests/sys/netpfil/pf/Makefile
@@ -17,6 +17,7 @@ ATF_TESTS_SH+=        altq \
                fragmentation_no_reassembly \
                get_state \
                icmp \
+               limits \
                loginterface \
                killstate \
                macro \
diff --git a/tests/sys/netpfil/pf/limits.sh b/tests/sys/netpfil/pf/limits.sh
new file mode 100644
index 000000000000..474684bef660
--- /dev/null
+++ b/tests/sys/netpfil/pf/limits.sh
@@ -0,0 +1,66 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 Kristof Provost <k...@freebsd.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+. $(atf_get_srcdir)/utils.subr
+
+atf_test_case "basic" "cleanup"
+basic_head()
+{
+       atf_set descr 'Test setting and retrieving limits'
+       atf_set require.user root
+}
+
+basic_body()
+{
+       pft_init
+
+       vnet_mkjail alcatraz
+
+       pft_set_rules alcatraz \
+               "set limit states 200" \
+               "set limit frags 100" \
+               "set limit src-nodes 50" \
+               "set limit table-entries 25"
+
+       atf_check -s exit:0 -o match:'states.*200' \
+           jexec alcatraz pfctl -sm
+       atf_check -s exit:0 -o match:'frags.*100' \
+           jexec alcatraz pfctl -sm
+       atf_check -s exit:0 -o match:'src-nodes.*50' \
+           jexec alcatraz pfctl -sm
+       atf_check -s exit:0 -o match:'table-entries.*25' \
+           jexec alcatraz pfctl -sm
+}
+
+basic_cleanup()
+{
+       pft_cleanup
+}
+
+atf_init_test_cases()
+{
+       atf_add_test_case "basic"
+}
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c 
b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index f02329901f69..9f7e6d4f31cb 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -318,36 +318,34 @@ pf_limits(struct snmp_context __unused *ctx, struct 
snmp_value *val,
        u_int sub, u_int __unused vindex, enum snmp_op op)
 {
        asn_subid_t             which = val->var.subs[sub - 1];
-       struct pfioc_limit      pl;
+       unsigned int            index, limit;
 
        if (op == SNMP_OP_SET)
                return (SNMP_ERR_NOT_WRITEABLE);
 
        if (op == SNMP_OP_GET) {
-               bzero(&pl, sizeof(struct pfioc_limit));
-
                switch (which) {
                        case LEAF_pfLimitsStates:
-                               pl.index = PF_LIMIT_STATES;
+                               index = PF_LIMIT_STATES;
                                break;
                        case LEAF_pfLimitsSrcNodes:
-                               pl.index = PF_LIMIT_SRC_NODES;
+                               index = PF_LIMIT_SRC_NODES;
                                break;
                        case LEAF_pfLimitsFrags:
-                               pl.index = PF_LIMIT_FRAGS;
+                               index = PF_LIMIT_FRAGS;
                                break;
 
                        default:
                                return (SNMP_ERR_NOSUCHNAME);
                }
 
-               if (ioctl(pfctl_fd(pfh), DIOCGETLIMIT, &pl)) {
+               if (pfctl_get_limit(pfh, index, &limit)) {
                        syslog(LOG_ERR, "pf_limits(): ioctl(): %s",
                            strerror(errno));
                        return (SNMP_ERR_GENERR);
                }
 
-               val->v.uint32 = pl.limit;
+               val->v.uint32 = limit;
 
                return (SNMP_ERR_NOERROR);
        }

Reply via email to