git: 9dbbe68bc5f2 - main - pf: convert DIOCCLRSTATUS to netlink
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 04 Jun 2024 14:59:32 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=9dbbe68bc5f25e238125f4c6b329b922eaf8d5eb
commit 9dbbe68bc5f25e238125f4c6b329b922eaf8d5eb
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-05-30 17:31:26 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
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)