The branch main has been updated by kp:

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

commit 9dbbe68bc5f25e238125f4c6b329b922eaf8d5eb
Author:     Kristof Provost <[email protected]>
AuthorDate: 2024-05-30 17:31:26 +0000
Commit:     Kristof Provost <[email protected]>
CommitDate: 2024-06-04 12:59:58 +0000

    pf: convert DIOCCLRSTATUS to netlink
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 lib/libpfctl/libpfctl.c   | 60 +++++++++++++++++++++++++++--------------------
 lib/libpfctl/libpfctl.h   |  1 +
 sbin/pfctl/pfctl.c        | 10 ++++----
 sys/net/pfvar.h           |  1 +
 sys/netpfil/pf/pf_ioctl.c | 32 +++++++++++++++----------
 sys/netpfil/pf/pf_nl.c    | 15 ++++++++++++
 sys/netpfil/pf/pf_nl.h    |  1 +
 7 files changed, 77 insertions(+), 43 deletions(-)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index e833a23b269a..771097a33dab 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -108,6 +108,35 @@ pfctl_fd(struct pfctl_handle *h)
        return (h->fd);
 }
 
+static int
+pfctl_do_netlink_cmd(struct pfctl_handle *h, uint cmd)
+{
+       struct snl_errmsg_data e = {};
+       struct snl_writer nw;
+       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, cmd);
+
+       hdr = snl_finalize_msg(&nw);
+       if (hdr == NULL)
+               return (ENOMEM);
+       seq_id = hdr->nlmsg_seq;
+
+       snl_send_message(&h->ss, hdr);
+
+       while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+       }
+
+       return (e.error);
+}
+
 static int
 pfctl_do_ioctl(int dev, uint cmd, size_t size, nvlist_t **nvl)
 {
@@ -229,31 +258,7 @@ pf_nvuint_64_array(const nvlist_t *nvl, const char *name, 
size_t maxelems,
 int
 pfctl_startstop(struct pfctl_handle *h, int start)
 {
-       struct snl_errmsg_data e = {};
-       struct snl_writer nw;
-       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,
-           start ? PFNL_CMD_START : PFNL_CMD_STOP);
-
-       hdr = snl_finalize_msg(&nw);
-       if (hdr == NULL)
-               return (ENOMEM);
-       seq_id = hdr->nlmsg_seq;
-
-       snl_send_message(&h->ss, hdr);
-
-       while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
-       }
-
-       return (e.error);
+       return (pfctl_do_netlink_cmd(h, start ? PFNL_CMD_START : 
PFNL_CMD_STOP));
 }
 
 static void
@@ -487,6 +492,11 @@ pfctl_get_status(int dev)
 
        return (status);
 }
+int
+pfctl_clear_status(struct pfctl_handle *h)
+{
+       return (pfctl_do_netlink_cmd(h, PFNL_CMD_CLEAR_STATUS));
+}
 
 static uint64_t
 _pfctl_status_counter(struct pfctl_status_counters *counters, uint64_t id)
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 391e73b61e02..e130fe0fe842 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -395,6 +395,7 @@ 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);
+int    pfctl_clear_status(struct pfctl_handle *h);
 uint64_t pfctl_status_counter(struct pfctl_status *status, int id);
 uint64_t pfctl_status_lcounter(struct pfctl_status *status, int id);
 uint64_t pfctl_status_fcounter(struct pfctl_status *status, int id);
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index c43d9e88dcbe..08c3d5c98321 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -66,7 +66,7 @@
 void    usage(void);
 int     pfctl_enable(int, int);
 int     pfctl_disable(int, int);
-int     pfctl_clear_stats(int, int);
+int     pfctl_clear_stats(struct pfctl_handle *, int);
 int     pfctl_get_skip_ifaces(void);
 int     pfctl_check_skip_ifaces(char *);
 int     pfctl_adjust_skip_ifaces(struct pfctl *);
@@ -353,9 +353,9 @@ pfctl_disable(int dev, int opts)
 }
 
 int
-pfctl_clear_stats(int dev, int opts)
+pfctl_clear_stats(struct pfctl_handle *h, int opts)
 {
-       if (ioctl(dev, DIOCCLRSTATUS))
+       if (pfctl_clear_status(h))
                err(1, "DIOCCLRSTATUS");
        if ((opts & PF_OPT_QUIET) == 0)
                fprintf(stderr, "pf: statistics cleared\n");
@@ -3237,7 +3237,7 @@ main(int argc, char *argv[])
                        pfctl_clear_src_nodes(dev, opts);
                        break;
                case 'i':
-                       pfctl_clear_stats(dev, opts);
+                       pfctl_clear_stats(pfh, opts);
                        break;
                case 'a':
                        pfctl_flush_eth_rules(dev, opts, anchorname);
@@ -3248,7 +3248,7 @@ main(int argc, char *argv[])
                                pfctl_clear_altq(dev, opts);
                                pfctl_clear_iface_states(dev, ifaceopt, opts);
                                pfctl_clear_src_nodes(dev, opts);
-                               pfctl_clear_stats(dev, opts);
+                               pfctl_clear_stats(pfh, opts);
                                pfctl_clear_fingerprints(dev, opts);
                                pfctl_clear_interface_flags(dev, opts);
                        }
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index d1aa57a941cc..0ea4741f8937 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2502,6 +2502,7 @@ int                        pf_ioctl_getrules(struct 
pfioc_rule *);
 int                     pf_ioctl_addrule(struct pf_krule *, uint32_t,
                            uint32_t, const char *, const char *, uid_t uid,
                            pid_t);
+void                    pf_ioctl_clear_status(void);
 
 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 1b22d49a6255..be5e38664a76 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2424,6 +2424,24 @@ pf_stop(void)
        return (error);
 }
 
+void
+pf_ioctl_clear_status(void)
+{
+       PF_RULES_WLOCK();
+       for (int i = 0; i < PFRES_MAX; i++)
+               counter_u64_zero(V_pf_status.counters[i]);
+       for (int i = 0; i < FCNT_MAX; i++)
+               pf_counter_u64_zero(&V_pf_status.fcounters[i]);
+       for (int i = 0; i < SCNT_MAX; i++)
+               counter_u64_zero(V_pf_status.scounters[i]);
+       for (int i = 0; i < KLCNT_MAX; i++)
+               counter_u64_zero(V_pf_status.lcounters[i]);
+       V_pf_status.since = time_second;
+       if (*V_pf_status.ifname)
+               pfi_update_status(V_pf_status.ifname, NULL);
+       PF_RULES_WUNLOCK();
+}
+
 static int
 pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread 
*td)
 {
@@ -3765,19 +3783,7 @@ DIOCGETSTATESV2_full:
        }
 
        case DIOCCLRSTATUS: {
-               PF_RULES_WLOCK();
-               for (int i = 0; i < PFRES_MAX; i++)
-                       counter_u64_zero(V_pf_status.counters[i]);
-               for (int i = 0; i < FCNT_MAX; i++)
-                       pf_counter_u64_zero(&V_pf_status.fcounters[i]);
-               for (int i = 0; i < SCNT_MAX; i++)
-                       counter_u64_zero(V_pf_status.scounters[i]);
-               for (int i = 0; i < KLCNT_MAX; i++)
-                       counter_u64_zero(V_pf_status.lcounters[i]);
-               V_pf_status.since = time_second;
-               if (*V_pf_status.ifname)
-                       pfi_update_status(V_pf_status.ifname, NULL);
-               PF_RULES_WUNLOCK();
+               pf_ioctl_clear_status();
                break;
        }
 
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 8f0349d6f121..67a785e54d6f 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1214,6 +1214,14 @@ out:
        return (error);
 }
 
+static int
+pf_handle_clear_status(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+       pf_ioctl_clear_status();
+
+       return (0);
+}
+
 static const struct nlhdr_parser *all_parsers[] = {
        &state_parser,
        &addrule_parser,
@@ -1302,6 +1310,13 @@ 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_CLEAR_STATUS,
+               .cmd_name = "CLEARSTATUS",
+               .cmd_cb = pf_handle_clear_status,
+               .cmd_flags = GENL_CMD_CAP_DO | 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 e486e9781b2e..10440eaf6366 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -47,6 +47,7 @@ enum {
        PFNL_CMD_KILLSTATES = 9,
        PFNL_CMD_SET_STATUSIF = 10,
        PFNL_CMD_GET_STATUS = 11,
+       PFNL_CMD_CLEAR_STATUS = 12,
        __PFNL_CMD_MAX,
 };
 #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)

Reply via email to