Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107165081
D30092.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D30092.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
@@ -194,6 +194,7 @@
struct pf_rule_addr rt_addr;
char ifname[IFNAMSIZ];
char label[PF_RULE_LABEL_SIZE];
+ bool kill_match;
};
int pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket,
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -645,6 +645,7 @@
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);
+ nvlist_add_bool(nvl, "kill_match", kill->kill_match);
nv.data = nvlist_pack(nvl, &nv.len);
nv.size = nv.len;
diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8
--- a/sbin/pfctl/pfctl.8
+++ b/sbin/pfctl/pfctl.8
@@ -35,7 +35,7 @@
.Sh SYNOPSIS
.Nm pfctl
.Bk -words
-.Op Fl AdeghmNnOPqRrvz
+.Op Fl AdeghMmNnOPqRrvz
.Op Fl a Ar anchor
.Oo Fl D Ar macro Ns =
.Ar value Oc
@@ -331,6 +331,17 @@
To kill all states using a gateway in 192.168.0.0/24:
.Pp
.Dl # pfctl -k gateway -k 192.168.0.0/24
+.Pp
+.It Fl M
+Kill matching states in the opposite direction (on other interfaces) when
+killing states.
+This applies to states killed using the -k option and also will apply to the
+flush command when flushing states.
+This is useful when an interface is specified when flushing states.
+Example:
+.Pp
+.Dl # pfctl -M -i interface -Fs
+.Pp
.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
@@ -245,7 +245,7 @@
extern char *__progname;
fprintf(stderr,
-"usage: %s [-AdeghmNnOPqRrvz] [-a anchor] [-D macro=value] [-F modifier]\n"
+"usage: %s [-AdeghMmNnOPqRrvz] [-a anchor] [-D macro=value] [-F modifier]\n"
"\t[-f file] [-i interface] [-K host | network]\n"
"\t[-k host | network | gateway | label | id] [-o level] [-p device]\n"
"\t[-s modifier] [-t table -T command [address ...]] [-x level]\n",
@@ -478,6 +478,9 @@
sizeof(kill.ifname)) >= sizeof(kill.ifname))
errx(1, "invalid interface: %s", iface);
+ if (opts & PF_OPT_KILLMATCH)
+ kill.kill_match = true;
+
if (pfctl_clear_states(dev, &kill, &killed))
err(1, "DIOCCLRSTATES");
if ((opts & PF_OPT_QUIET) == 0)
@@ -661,6 +664,9 @@
pfctl_addrprefix(state_kill[0], &kill.src.addr.v.a.mask);
+ if (opts & PF_OPT_KILLMATCH)
+ kill.kill_match = true;
+
if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) {
errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
/* NOTREACHED */
@@ -768,6 +774,9 @@
sizeof(kill.ifname)) >= sizeof(kill.ifname))
errx(1, "invalid interface: %s", iface);
+ if (opts & PF_OPT_KILLMATCH)
+ kill.kill_match = true;
+
pfctl_addrprefix(state_kill[1], &kill.rt_addr.addr.v.a.mask);
if ((ret_ga = getaddrinfo(state_kill[1], NULL, NULL, &res))) {
@@ -821,6 +830,9 @@
sizeof(kill.ifname)) >= sizeof(kill.ifname))
errx(1, "invalid interface: %s", iface);
+ if (opts & PF_OPT_KILLMATCH)
+ kill.kill_match = true;
+
if (strlcpy(kill.label, state_kill[1], sizeof(kill.label)) >=
sizeof(kill.label))
errx(1, "label too long: %s", state_kill[1]);
@@ -846,6 +858,10 @@
}
memset(&kill, 0, sizeof(kill));
+
+ if (opts & PF_OPT_KILLMATCH)
+ kill.kill_match = true;
+
if ((sscanf(state_kill[1], "%jx/%x",
&kill.cmp.id, &kill.cmp.creatorid)) == 2)
HTONL(kill.cmp.creatorid);
@@ -2199,7 +2215,7 @@
usage();
while ((ch = getopt(argc, argv,
- "a:AdD:eqf:F:ghi:k:K:mnNOo:Pp:rRs:t:T:vx:z")) != -1) {
+ "a:AdD:eqf:F:ghi:k:K:mMnNOo:Pp:rRs:t:T:vx:z")) != -1) {
switch (ch) {
case 'a':
anchoropt = optarg;
@@ -2252,6 +2268,9 @@
case 'm':
opts |= PF_OPT_MERGE;
break;
+ case 'M':
+ opts |= PF_OPT_KILLMATCH;
+ break;
case 'n':
opts |= PF_OPT_NOACTION;
break;
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -55,6 +55,7 @@
#define PF_OPT_NUMERIC 0x1000
#define PF_OPT_MERGE 0x2000
#define PF_OPT_RECURSE 0x4000
+#define PF_OPT_KILLMATCH 0x8000
#define PF_TH_ALL 0xFF
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1085,6 +1085,7 @@
char psk_ifname[IFNAMSIZ];
char psk_label[PF_RULE_LABEL_SIZE];
u_int psk_killed;
+ bool psk_kill_match;
};
#endif
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
@@ -2467,6 +2467,8 @@
sizeof(kill->psk_ifname)));
PFNV_CHK(pf_nvstring(nvl, "label", kill->psk_label,
sizeof(kill->psk_label)));
+ if (nvlist_exists_bool(nvl, "kill_match"))
+ kill->psk_kill_match = nvlist_get_bool(nvl, "kill_match");
errout:
return (error);
@@ -2644,13 +2646,33 @@
return (false);
}
+static unsigned int
+pf_kill_matching_state(struct pf_state_key_cmp *key, int dir)
+{
+ struct pf_state *match;
+ int more = 0;
+ unsigned int killed = 0;
+
+ /* Call with unlocked hashrow */
+
+ match = pf_find_state_all(key, dir, &more);
+ if (match && !more) {
+ pf_unlink_state(match, 0);
+ killed++;
+ }
+
+ return (killed);
+}
+
static int
pf_killstates_row(struct pf_kstate_kill *psk, struct pf_idhash *ih)
{
struct pf_state *s;
struct pf_state_key *sk;
struct pf_addr *srcaddr, *dstaddr;
- int killed = 0;
+ struct pf_state_key_cmp match_key;
+ int idx, killed = 0;
+ unsigned int dir;
u_int16_t srcport, dstport;
relock_DIOCKILLSTATES:
@@ -2707,8 +2729,36 @@
s->kif->pfik_name))
continue;
+ if (psk->psk_kill_match) {
+ /* Create the key to find matching states, with lock
+ * held. */
+
+ bzero(&match_key, sizeof(match_key));
+
+ if (s->direction == PF_OUT) {
+ dir = PF_IN;
+ idx = PF_SK_STACK;
+ } else {
+ dir = PF_OUT;
+ idx = PF_SK_WIRE;
+ }
+
+ match_key.af = s->key[idx]->af;
+ match_key.proto = s->key[idx]->proto;
+ PF_ACPY(&match_key.addr[0],
+ &s->key[idx]->addr[1], match_key.af);
+ match_key.port[0] = s->key[idx]->port[1];
+ PF_ACPY(&match_key.addr[1],
+ &s->key[idx]->addr[0], match_key.af);
+ match_key.port[1] = s->key[idx]->port[0];
+ }
+
pf_unlink_state(s, PF_ENTER_LOCKED);
killed++;
+
+ if (psk->psk_kill_match)
+ killed += pf_kill_matching_state(&match_key, dir);
+
goto relock_DIOCKILLSTATES;
}
PF_HASHROW_UNLOCK(ih);
@@ -5442,27 +5492,57 @@
static unsigned int
pf_clear_states(const struct pf_kstate_kill *kill)
{
+ struct pf_state_key_cmp match_key;
struct pf_state *s;
- unsigned int killed = 0;
+ int idx;
+ unsigned int killed = 0, dir;
for (unsigned int i = 0; i <= pf_hashmask; i++) {
struct pf_idhash *ih = &V_pf_idhash[i];
relock_DIOCCLRSTATES:
PF_HASHROW_LOCK(ih);
- LIST_FOREACH(s, &ih->states, entry)
- if (!kill->psk_ifname[0] ||
- !strcmp(kill->psk_ifname,
- s->kif->pfik_name)) {
- /*
- * Don't send out individual
- * delete messages.
- */
- s->state_flags |= PFSTATE_NOSYNC;
- pf_unlink_state(s, PF_ENTER_LOCKED);
- killed++;
- goto relock_DIOCCLRSTATES;
+ LIST_FOREACH(s, &ih->states, entry) {
+ if (kill->psk_ifname[0] &&
+ strcmp(kill->psk_ifname,
+ s->kif->pfik_name))
+ continue;
+
+ if (kill->psk_kill_match) {
+ bzero(&match_key, sizeof(match_key));
+
+ if (s->direction == PF_OUT) {
+ dir = PF_IN;
+ idx = PF_SK_STACK;
+ } else {
+ dir = PF_OUT;
+ idx = PF_SK_WIRE;
+ }
+
+ match_key.af = s->key[idx]->af;
+ match_key.proto = s->key[idx]->proto;
+ PF_ACPY(&match_key.addr[0],
+ &s->key[idx]->addr[1], match_key.af);
+ match_key.port[0] = s->key[idx]->port[1];
+ PF_ACPY(&match_key.addr[1],
+ &s->key[idx]->addr[0], match_key.af);
+ match_key.port[1] = s->key[idx]->port[0];
}
+
+ /*
+ * Don't send out individual
+ * delete messages.
+ */
+ s->state_flags |= PFSTATE_NOSYNC;
+ pf_unlink_state(s, PF_ENTER_LOCKED);
+ killed++;
+
+ if (kill->psk_kill_match)
+ killed += pf_kill_matching_state(&match_key,
+ dir);
+
+ goto relock_DIOCCLRSTATES;
+ }
PF_HASHROW_UNLOCK(ih);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 3:03 AM (20 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15760409
Default Alt Text
D30092.diff (8 KB)
Attached To
Mode
D30092: pf: Support killing 'matching' states
Attached
Detach File
Event Timeline
Log In to Comment