git: 53714a586133 - main - pfctl: Start using DIOCCLRSTATESNV

Kristof Provost kp at FreeBSD.org
Fri May 7 20:13:57 UTC 2021


The branch main has been updated by kp:

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

commit 53714a586133fd8ae662427007f84ec663cd83ef
Author:     Kristof Provost <kp at FreeBSD.org>
AuthorDate: 2021-04-29 13:10:50 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
CommitDate: 2021-05-07 20:13:30 +0000

    pfctl: Start using DIOCCLRSTATESNV
    
    MFC after:      1 week
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D30053
---
 lib/libpfctl/libpfctl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/libpfctl/libpfctl.h | 18 +++++++++++++++
 sbin/pfctl/pfctl.c      | 21 +++++++++---------
 3 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index b07fcda9bd5a..8c8b21d22a46 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -608,3 +608,62 @@ pfctl_set_keepcounters(int dev, bool keep)
 	free(nv.data);
 	return (ret);
 }
+
+static void
+pfctl_nv_add_state_cmp(nvlist_t *nvl, const char *name,
+    const struct pfctl_state_cmp *cmp)
+{
+	nvlist_t	*nv;
+
+	nv = nvlist_create(0);
+
+	nvlist_add_number(nv, "id", cmp->id);
+	nvlist_add_number(nv, "creatorid", cmp->creatorid);
+	nvlist_add_number(nv, "direction", cmp->direction);
+
+	nvlist_add_nvlist(nvl, name, nv);
+}
+
+int
+pfctl_clear_states(int dev, const struct pfctl_kill *kill,
+    unsigned int *killed)
+{
+	struct pfioc_nv	 nv;
+	nvlist_t	*nvl;
+	int		 ret;
+
+	nvl = nvlist_create(0);
+
+	pfctl_nv_add_state_cmp(nvl, "cmp", &kill->cmp);
+	nvlist_add_number(nvl, "af", kill->af);
+	nvlist_add_number(nvl, "proto", kill->proto);
+	pfctl_nv_add_rule_addr(nvl, "src", &kill->src);
+	pfctl_nv_add_rule_addr(nvl, "dst", &kill->dst);
+	nvlist_add_string(nvl, "ifname", kill->ifname);
+	nvlist_add_string(nvl, "label", kill->label);
+
+	nv.data = nvlist_pack(nvl, &nv.len);
+	nv.size = nv.len;
+	nvlist_destroy(nvl);
+	nvl = NULL;
+
+	ret = ioctl(dev, DIOCCLRSTATESNV, &nv);
+	if (ret != 0) {
+		free(nv.data);
+		return (ret);
+	}
+
+	nvl = nvlist_unpack(nv.data, nv.len, 0);
+	if (nvl == NULL) {
+		free(nv.data);
+		return (EIO);
+	}
+
+	if (killed)
+		*killed = nvlist_get_number(nvl, "killed");
+
+	nvlist_destroy(nvl);
+	free(nv.data);
+
+	return (ret);
+}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index e19187fc2526..3ec2a7fa535f 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -179,6 +179,22 @@ RB_PROTOTYPE(pfctl_anchor_global, pfctl_anchor, entry_global,
 RB_PROTOTYPE(pfctl_anchor_node, pfctl_anchor, entry_node,
     pf_anchor_compare);
 
+struct pfctl_state_cmp {
+	uint64_t	id;
+	uint32_t	creatorid;
+	uint8_t		direction;
+};
+
+struct pfctl_kill {
+	struct pfctl_state_cmp	cmp;
+	sa_family_t		af;
+	int			proto;
+	struct pf_rule_addr	src;
+	struct pf_rule_addr	dst;
+	char			ifname[IFNAMSIZ];
+	char			label[PF_RULE_LABEL_SIZE];
+};
+
 int	pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket,
 	    const char *anchor, u_int32_t ruleset, struct pfctl_rule *rule,
 	    char *anchor_call);
@@ -189,5 +205,7 @@ int	pfctl_add_rule(int dev, const struct pfctl_rule *r,
 	    const char *anchor, const char *anchor_call, u_int32_t ticket,
 	    u_int32_t pool_ticket);
 int	pfctl_set_keepcounters(int dev, bool keep);
+int	pfctl_clear_states(int dev, const struct pfctl_kill *kill,
+	    unsigned int *killed);
 
 #endif
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index af2ae6fe3bf0..2cfca24c0cfa 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -79,7 +79,7 @@ int	 pfctl_clear_rules(int, int, char *);
 int	 pfctl_clear_nat(int, int, char *);
 int	 pfctl_clear_altq(int, int);
 int	 pfctl_clear_src_nodes(int, int);
-int	 pfctl_clear_states(int, const char *, int);
+int	 pfctl_clear_iface_states(int, const char *, int);
 void	 pfctl_addrprefix(char *, struct pf_addr *);
 int	 pfctl_kill_src_nodes(int, const char *, int);
 int	 pfctl_net_kill_states(int, const char *, int);
@@ -467,19 +467,20 @@ pfctl_clear_src_nodes(int dev, int opts)
 }
 
 int
-pfctl_clear_states(int dev, const char *iface, int opts)
+pfctl_clear_iface_states(int dev, const char *iface, int opts)
 {
-	struct pfioc_state_kill psk;
+	struct pfctl_kill kill;
+	unsigned int killed;
 
-	memset(&psk, 0, sizeof(psk));
-	if (iface != NULL && strlcpy(psk.psk_ifname, iface,
-	    sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
+	memset(&kill, 0, sizeof(kill));
+	if (iface != NULL && strlcpy(kill.ifname, iface,
+	    sizeof(kill.ifname)) >= sizeof(kill.ifname))
 		errx(1, "invalid interface: %s", iface);
 
-	if (ioctl(dev, DIOCCLRSTATES, &psk))
+	if (pfctl_clear_states(dev, &kill, &killed))
 		err(1, "DIOCCLRSTATES");
 	if ((opts & PF_OPT_QUIET) == 0)
-		fprintf(stderr, "%d states cleared\n", psk.psk_killed);
+		fprintf(stderr, "%d states cleared\n", killed);
 	return (0);
 }
 
@@ -2417,7 +2418,7 @@ main(int argc, char *argv[])
 			pfctl_clear_altq(dev, opts);
 			break;
 		case 's':
-			pfctl_clear_states(dev, ifaceopt, opts);
+			pfctl_clear_iface_states(dev, ifaceopt, opts);
 			break;
 		case 'S':
 			pfctl_clear_src_nodes(dev, opts);
@@ -2431,7 +2432,7 @@ main(int argc, char *argv[])
 			pfctl_clear_tables(anchorname, opts);
 			if (!*anchorname) {
 				pfctl_clear_altq(dev, opts);
-				pfctl_clear_states(dev, ifaceopt, opts);
+				pfctl_clear_iface_states(dev, ifaceopt, opts);
 				pfctl_clear_src_nodes(dev, opts);
 				pfctl_clear_stats(dev, opts);
 				pfctl_clear_fingerprints(dev, opts);


More information about the dev-commits-src-main mailing list