aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-04-29 19:24:56 +0000
committerKristof Provost <kp@FreeBSD.org>2021-05-14 08:21:11 +0000
commit5d5936ea20a70a704fd51be184797e5423bb1aab (patch)
tree5794bddc9f4781a51e0315305712970a1d887c0a
parentf756e230f5e68ce589d3cca81726d5c01db0d0cf (diff)
downloadsrc-5d5936ea20a70a704fd51be184797e5423bb1aab.tar.gz
src-5d5936ea20a70a704fd51be184797e5423bb1aab.zip
pfctl: Start using DIOCKILLSTATESNV
MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D30055 (cherry picked from commit 2a00c4db93b8db0c326a57363ca8a690ef6ab082)
-rw-r--r--lib/libpfctl/libpfctl.c24
-rw-r--r--lib/libpfctl/libpfctl.h2
-rw-r--r--sbin/pfctl/pfctl.c91
3 files changed, 69 insertions, 48 deletions
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 8c8b21d22a46..9f504237b4ee 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -50,6 +50,9 @@
#include "libpfctl.h"
+static int _pfctl_clear_states(int , const struct pfctl_kill *,
+ unsigned int *, uint64_t);
+
static void
pf_nvuint_8_array(const nvlist_t *nvl, const char *name, size_t maxelems,
u_int8_t *numbers, size_t *nelems)
@@ -624,9 +627,9 @@ pfctl_nv_add_state_cmp(nvlist_t *nvl, const char *name,
nvlist_add_nvlist(nvl, name, nv);
}
-int
-pfctl_clear_states(int dev, const struct pfctl_kill *kill,
- unsigned int *killed)
+static int
+_pfctl_clear_states(int dev, const struct pfctl_kill *kill,
+ unsigned int *killed, uint64_t ioctlval)
{
struct pfioc_nv nv;
nvlist_t *nvl;
@@ -647,7 +650,7 @@ pfctl_clear_states(int dev, const struct pfctl_kill *kill,
nvlist_destroy(nvl);
nvl = NULL;
- ret = ioctl(dev, DIOCCLRSTATESNV, &nv);
+ ret = ioctl(dev, ioctlval, &nv);
if (ret != 0) {
free(nv.data);
return (ret);
@@ -667,3 +670,16 @@ pfctl_clear_states(int dev, const struct pfctl_kill *kill,
return (ret);
}
+
+int
+pfctl_clear_states(int dev, const struct pfctl_kill *kill,
+ unsigned int *killed)
+{
+ return (_pfctl_clear_states(dev, kill, killed, DIOCCLRSTATESNV));
+}
+
+int
+pfctl_kill_states(int dev, const struct pfctl_kill *kill, unsigned int *killed)
+{
+ return (_pfctl_clear_states(dev, kill, killed, DIOCKILLSTATESNV));
+}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 3ec2a7fa535f..aa7f0ffd8fad 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -207,5 +207,7 @@ int pfctl_add_rule(int dev, const struct pfctl_rule *r,
int pfctl_set_keepcounters(int dev, bool keep);
int pfctl_clear_states(int dev, const struct pfctl_kill *kill,
unsigned int *killed);
+int pfctl_kill_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 2cfca24c0cfa..487dfb480cdc 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -640,24 +640,25 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts)
int
pfctl_net_kill_states(int dev, const char *iface, int opts)
{
- struct pfioc_state_kill psk;
+ struct pfctl_kill kill;
struct addrinfo *res[2], *resp[2];
struct sockaddr last_src, last_dst;
+ unsigned int newkilled;
int killed, sources, dests;
int ret_ga;
killed = sources = dests = 0;
- memset(&psk, 0, sizeof(psk));
- memset(&psk.psk_src.addr.v.a.mask, 0xff,
- sizeof(psk.psk_src.addr.v.a.mask));
+ memset(&kill, 0, sizeof(kill));
+ memset(&kill.src.addr.v.a.mask, 0xff,
+ sizeof(kill.src.addr.v.a.mask));
memset(&last_src, 0xff, sizeof(last_src));
memset(&last_dst, 0xff, sizeof(last_dst));
- if (iface != NULL && strlcpy(psk.psk_ifname, iface,
- sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
+ if (iface != NULL && strlcpy(kill.ifname, iface,
+ sizeof(kill.ifname)) >= sizeof(kill.ifname))
errx(1, "invalid interface: %s", iface);
- pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask);
+ pfctl_addrprefix(state_kill[0], &kill.src.addr.v.a.mask);
if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) {
errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
@@ -671,26 +672,26 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
continue;
last_src = *(struct sockaddr *)resp[0]->ai_addr;
- psk.psk_af = resp[0]->ai_family;
+ kill.af = resp[0]->ai_family;
sources++;
- if (psk.psk_af == AF_INET)
- psk.psk_src.addr.v.a.addr.v4 =
+ if (kill.af == AF_INET)
+ kill.src.addr.v.a.addr.v4 =
((struct sockaddr_in *)resp[0]->ai_addr)->sin_addr;
- else if (psk.psk_af == AF_INET6)
- psk.psk_src.addr.v.a.addr.v6 =
+ else if (kill.af == AF_INET6)
+ kill.src.addr.v.a.addr.v6 =
((struct sockaddr_in6 *)resp[0]->ai_addr)->
sin6_addr;
else
- errx(1, "Unknown address family %d", psk.psk_af);
+ errx(1, "Unknown address family %d", kill.af);
if (state_killers > 1) {
dests = 0;
- memset(&psk.psk_dst.addr.v.a.mask, 0xff,
- sizeof(psk.psk_dst.addr.v.a.mask));
+ memset(&kill.dst.addr.v.a.mask, 0xff,
+ sizeof(kill.dst.addr.v.a.mask));
memset(&last_dst, 0xff, sizeof(last_dst));
pfctl_addrprefix(state_kill[1],
- &psk.psk_dst.addr.v.a.mask);
+ &kill.dst.addr.v.a.mask);
if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL,
&res[1]))) {
errx(1, "getaddrinfo: %s",
@@ -701,7 +702,7 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
resp[1] = resp[1]->ai_next) {
if (resp[1]->ai_addr == NULL)
continue;
- if (psk.psk_af != resp[1]->ai_family)
+ if (kill.af != resp[1]->ai_family)
continue;
if (memcmp(&last_dst, resp[1]->ai_addr,
@@ -711,27 +712,27 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
dests++;
- if (psk.psk_af == AF_INET)
- psk.psk_dst.addr.v.a.addr.v4 =
+ if (kill.af == AF_INET)
+ kill.dst.addr.v.a.addr.v4 =
((struct sockaddr_in *)resp[1]->
ai_addr)->sin_addr;
- else if (psk.psk_af == AF_INET6)
- psk.psk_dst.addr.v.a.addr.v6 =
+ else if (kill.af == AF_INET6)
+ kill.dst.addr.v.a.addr.v6 =
((struct sockaddr_in6 *)resp[1]->
ai_addr)->sin6_addr;
else
errx(1, "Unknown address family %d",
- psk.psk_af);
+ kill.af);
- if (ioctl(dev, DIOCKILLSTATES, &psk))
+ if (pfctl_kill_states(dev, &kill, &newkilled))
err(1, "DIOCKILLSTATES");
- killed += psk.psk_killed;
+ killed += newkilled;
}
freeaddrinfo(res[1]);
} else {
- if (ioctl(dev, DIOCKILLSTATES, &psk))
+ if (pfctl_kill_states(dev, &kill, &newkilled))
err(1, "DIOCKILLSTATES");
- killed += psk.psk_killed;
+ killed += newkilled;
}
}
@@ -746,26 +747,27 @@ pfctl_net_kill_states(int dev, const char *iface, int opts)
int
pfctl_label_kill_states(int dev, const char *iface, int opts)
{
- struct pfioc_state_kill psk;
+ struct pfctl_kill kill;
+ unsigned int killed;
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
warnx("no label specified");
usage();
}
- 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 (strlcpy(psk.psk_label, state_kill[1], sizeof(psk.psk_label)) >=
- sizeof(psk.psk_label))
+ if (strlcpy(kill.label, state_kill[1], sizeof(kill.label)) >=
+ sizeof(kill.label))
errx(1, "label too long: %s", state_kill[1]);
- if (ioctl(dev, DIOCKILLSTATES, &psk))
+ if (pfctl_kill_states(dev, &kill, &killed))
err(1, "DIOCKILLSTATES");
if ((opts & PF_OPT_QUIET) == 0)
- fprintf(stderr, "killed %d states\n", psk.psk_killed);
+ fprintf(stderr, "killed %d states\n", killed);
return (0);
}
@@ -773,34 +775,35 @@ pfctl_label_kill_states(int dev, const char *iface, int opts)
int
pfctl_id_kill_states(int dev, const char *iface, int opts)
{
- struct pfioc_state_kill psk;
+ struct pfctl_kill kill;
+ unsigned int killed;
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
warnx("no id specified");
usage();
}
- memset(&psk, 0, sizeof(psk));
+ memset(&kill, 0, sizeof(kill));
if ((sscanf(state_kill[1], "%jx/%x",
- &psk.psk_pfcmp.id, &psk.psk_pfcmp.creatorid)) == 2)
- HTONL(psk.psk_pfcmp.creatorid);
- else if ((sscanf(state_kill[1], "%jx", &psk.psk_pfcmp.id)) == 1) {
- psk.psk_pfcmp.creatorid = 0;
+ &kill.cmp.id, &kill.cmp.creatorid)) == 2)
+ HTONL(kill.cmp.creatorid);
+ else if ((sscanf(state_kill[1], "%jx", &kill.cmp.id)) == 1) {
+ kill.cmp.creatorid = 0;
} else {
warnx("wrong id format specified");
usage();
}
- if (psk.psk_pfcmp.id == 0) {
+ if (kill.cmp.id == 0) {
warnx("cannot kill id 0");
usage();
}
- psk.psk_pfcmp.id = htobe64(psk.psk_pfcmp.id);
- if (ioctl(dev, DIOCKILLSTATES, &psk))
+ kill.cmp.id = htobe64(kill.cmp.id);
+ if (pfctl_kill_states(dev, &kill, &killed))
err(1, "DIOCKILLSTATES");
if ((opts & PF_OPT_QUIET) == 0)
- fprintf(stderr, "killed %d states\n", psk.psk_killed);
+ fprintf(stderr, "killed %d states\n", killed);
return (0);
}