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)