Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96309916
D30058.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D30058.diff
View Options
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -191,6 +191,7 @@
int proto;
struct pf_rule_addr src;
struct pf_rule_addr dst;
+ struct pf_rule_addr rt_addr;
char ifname[IFNAMSIZ];
char label[PF_RULE_LABEL_SIZE];
};
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -642,6 +642,7 @@
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);
+ pfctl_nv_add_rule_addr(nvl, "rt_addr", &kill->rt_addr);
nvlist_add_string(nvl, "ifname", kill->ifname);
nvlist_add_string(nvl, "label", kill->label);
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -45,7 +45,7 @@
.Op Fl K Ar host | network
.Xo
.Oo Fl k
-.Ar host | network | label | id
+.Ar host | network | label | id | gateway
.Oc Xc
.Op Fl o Ar level
.Op Fl p Ar device
@@ -256,14 +256,15 @@
entries from the first host/network to the second.
.It Xo
.Fl k
-.Ar host | network | label | id
+.Ar host | network | label | id | gateway
.Xc
Kill all of the state entries matching the specified
.Ar host ,
.Ar network ,
.Ar label ,
+.Ar id ,
or
-.Ar id .
+.Ar gateway.
.Pp
For example, to kill all of the state entries originating from
.Dq host :
@@ -317,6 +318,19 @@
firewall with hostid 00000002 use:
.Pp
.Dl # pfctl -k id -k 4823e84500000018/2
+.Pp
+It is also possible to kill states created from a rule with the route-to/reply-to
+parameter set to route the connection through a particular gateway.
+Note that rules routing via the default routing table (not via a route-to
+rule) will have their rt_addr set as 0.0.0.0 or ::.
+To kill all states using a gateway of 192.168.0.1 use:
+.Pp
+.Dl # pfctl -k gateway -k 192.168.0.1
+.Pp
+A network prefix length can also be specified.
+To kill all states using a gateway in 192.168.0.0/24:
+.Pp
+.Dl # pfctl -k gateway -k 192.168.0.0/24
.It Fl m
Merge in explicitly given options without resetting those
which are omitted.
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -83,6 +83,7 @@
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);
+int pfctl_gateway_kill_states(int, const char *, int);
int pfctl_label_kill_states(int, const char *, int);
int pfctl_id_kill_states(int, const char *, int);
void pfctl_init_options(struct pfctl *);
@@ -246,7 +247,7 @@
fprintf(stderr,
"usage: %s [-AdeghmNnOPqRrvz] [-a anchor] [-D macro=value] [-F modifier]\n"
"\t[-f file] [-i interface] [-K host | network]\n"
- "\t[-k host | network | label | id] [-o level] [-p device]\n"
+ "\t[-k host | network | gateway | label | id] [-o level] [-p device]\n"
"\t[-s modifier] [-t table -T command [address ...]] [-x level]\n",
__progname);
@@ -744,6 +745,67 @@
return (0);
}
+int
+pfctl_gateway_kill_states(int dev, const char *iface, int opts)
+{
+ struct pfctl_kill kill;
+ struct addrinfo *res, *resp;
+ struct sockaddr last_src;
+ unsigned int newkilled;
+ int killed = 0;
+ int ret_ga;
+
+ if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
+ warnx("no gateway specified");
+ usage();
+ }
+
+ memset(&kill, 0, sizeof(kill));
+ memset(&kill.rt_addr.addr.v.a.mask, 0xff,
+ sizeof(kill.rt_addr.addr.v.a.mask));
+ memset(&last_src, 0xff, sizeof(last_src));
+ if (iface != NULL && strlcpy(kill.ifname, iface,
+ sizeof(kill.ifname)) >= sizeof(kill.ifname))
+ errx(1, "invalid interface: %s", iface);
+
+ pfctl_addrprefix(state_kill[1], &kill.rt_addr.addr.v.a.mask);
+
+ if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL, &res))) {
+ errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
+ /* NOTREACHED */
+ }
+ for (resp = res; resp; resp = resp->ai_next) {
+ if (resp->ai_addr == NULL)
+ continue;
+ /* We get lots of duplicates. Catch the easy ones */
+ if (memcmp(&last_src, resp->ai_addr, sizeof(last_src)) == 0)
+ continue;
+ last_src = *(struct sockaddr *)resp->ai_addr;
+
+ kill.af = resp->ai_family;
+
+ if (kill.af == AF_INET)
+ kill.rt_addr.addr.v.a.addr.v4 =
+ ((struct sockaddr_in *)resp->ai_addr)->sin_addr;
+ else if (kill.af == AF_INET6)
+ kill.rt_addr.addr.v.a.addr.v6 =
+ ((struct sockaddr_in6 *)resp->ai_addr)->
+ sin6_addr;
+ else
+ errx(1, "Unknown address family %d", kill.af);
+
+ if (pfctl_kill_states(dev, &kill, &newkilled))
+ err(1, "DIOCKILLSTATES");
+ killed += newkilled;
+ }
+
+ freeaddrinfo(res);
+
+ if ((opts & PF_OPT_QUIET) == 0)
+ fprintf(stderr, "killed %d states\n", killed);
+ return (0);
+}
+
int
pfctl_label_kill_states(int dev, const char *iface, int opts)
{
@@ -2455,6 +2517,8 @@
pfctl_label_kill_states(dev, ifaceopt, opts);
else if (!strcmp(state_kill[0], "id"))
pfctl_id_kill_states(dev, ifaceopt, opts);
+ else if (!strcmp(state_kill[0], "gateway"))
+ pfctl_gateway_kill_states(dev, ifaceopt, opts);
else
pfctl_net_kill_states(dev, ifaceopt, opts);
}
diff --git a/share/man/man4/pf.4 b/share/man/man4/pf.4
--- a/share/man/man4/pf.4
+++ b/share/man/man4/pf.4
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 5, 2018
+.Dd May 7, 2021
.Dt PF 4
.Os
.Sh NAME
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1081,6 +1081,7 @@
int psk_proto;
struct pf_rule_addr psk_src;
struct pf_rule_addr psk_dst;
+ struct pf_rule_addr psk_rt_addr;
char psk_ifname[IFNAMSIZ];
char psk_label[PF_RULE_LABEL_SIZE];
u_int psk_killed;
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2458,6 +2458,10 @@
return (EINVAL);
PFNV_CHK(pf_nvrule_addr_to_rule_addr(nvlist_get_nvlist(nvl, "dst"),
&kill->psk_dst));
+ if (nvlist_exists_nvlist(nvl, "rt_addr")) {
+ PFNV_CHK(pf_nvrule_addr_to_rule_addr(
+ nvlist_get_nvlist(nvl, "rt_addr"), &kill->psk_rt_addr));
+ }
PFNV_CHK(pf_nvstring(nvl, "ifname", kill->psk_ifname,
sizeof(kill->psk_ifname)));
@@ -2679,6 +2683,12 @@
&psk->psk_dst.addr.v.a.mask, dstaddr, sk->af))
continue;
+ if (! PF_MATCHA(psk->psk_rt_addr.neg,
+ &psk->psk_rt_addr.addr.v.a.addr,
+ &psk->psk_rt_addr.addr.v.a.mask,
+ &s->rt_addr, sk->af))
+ continue;
+
if (psk->psk_src.port_op != 0 &&
! pf_match_port(psk->psk_src.port_op,
psk->psk_src.port[0], psk->psk_src.port[1], srcport))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 25, 12:30 PM (21 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12757581
Default Alt Text
D30058.diff (6 KB)
Attached To
Mode
D30058: pf: Allow states to by killed per 'gateway'
Attached
Detach File
Event Timeline
Log In to Comment