Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140029044
D29669.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D29669.diff
View Options
Index: lib/libpfctl/libpfctl.h
===================================================================
--- lib/libpfctl/libpfctl.h
+++ lib/libpfctl/libpfctl.h
@@ -43,6 +43,7 @@
struct pf_rule_addr dst;
union pf_rule_ptr skip[PF_SKIP_COUNT];
char label[PF_RULE_LABEL_SIZE];
+ char schedule[PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
@@ -174,5 +175,6 @@
int libpfctl_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 libpfctl_kill_schedule(int dev, const char *sched, int *killed);
#endif
Index: lib/libpfctl/libpfctl.c
===================================================================
--- lib/libpfctl/libpfctl.c
+++ lib/libpfctl/libpfctl.c
@@ -291,6 +291,9 @@
rule->skip[i].nr = skip[i];
strlcpy(rule->label, nvlist_get_string(nvl, "label"), PF_RULE_LABEL_SIZE);
+ if (nvlist_exists_string(nvl, "schedule"))
+ strlcpy(rule->schedule, nvlist_get_string(nvl, "schedule"),
+ PF_RULE_LABEL_SIZE);
strlcpy(rule->ifname, nvlist_get_string(nvl, "ifname"), IFNAMSIZ);
strlcpy(rule->qname, nvlist_get_string(nvl, "qname"), PF_QNAME_SIZE);
strlcpy(rule->pqname, nvlist_get_string(nvl, "pqname"), PF_QNAME_SIZE);
@@ -395,6 +398,7 @@
pfctl_nv_add_rule_addr(nvlr, "dst", &r->dst);
nvlist_add_string(nvlr, "label", r->label);
+ nvlist_add_string(nvlr, "schedule", r->schedule);
nvlist_add_string(nvlr, "ifname", r->ifname);
nvlist_add_string(nvlr, "qname", r->qname);
nvlist_add_string(nvlr, "pqname", r->pqname);
@@ -534,3 +538,40 @@
return (0);
}
+
+int
+libpfctl_kill_schedule(int dev, const char *sched, int *killed)
+{
+ struct pfioc_nv nv;
+ nvlist_t *nvl;
+ int ret;
+
+ nvl = nvlist_create(0);
+
+ nvlist_add_string(nvl, "schedule", sched);
+
+ nv.data = nvlist_pack(nvl, &nv.len);
+ nv.size = nv.len; // Reply will be smaller than the request
+
+ nvlist_destroy(nvl);
+
+ ret = ioctl(dev, DIOCKILLSCHEDULE, &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");
+
+ free(nv.data);
+ nvlist_destroy(nvl);
+
+ return (0);
+}
Index: sbin/pfctl/parse.y
===================================================================
--- sbin/pfctl/parse.y
+++ sbin/pfctl/parse.y
@@ -242,6 +242,7 @@
int fragment;
int allowopts;
char *label;
+ char *schedule;
struct node_qassign queues;
char *tag;
char *match_tag;
@@ -349,6 +350,7 @@
int check_rulestate(int);
int getservice(char *);
int rule_label(struct pfctl_rule *, char *);
+int rule_schedule(struct pfctl_rule *, char *);
int rt_tableid_max(void);
void mv_rules(struct pfctl_ruleset *, struct pfctl_ruleset *);
@@ -460,7 +462,7 @@
%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY FAILPOLICY
%token RANDOMID REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
-%token ANTISPOOF FOR INCLUDE
+%token ANTISPOOF FOR INCLUDE SCHEDULE
%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
%token ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME
%token UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL
@@ -499,7 +501,7 @@
%type <v.gid> gids gid_list gid_item
%type <v.route> route
%type <v.redirection> redirection redirpool
-%type <v.string> label stringall tag anchorname
+%type <v.string> label schedule stringall tag anchorname
%type <v.string> string varstring numberstring
%type <v.keep_state> keep
%type <v.state_opt> state_opt_spec state_opt_list state_opt_item
@@ -2090,6 +2092,9 @@
if (rule_label(&r, $9.label))
YYERROR;
free($9.label);
+ if (rule_schedule(&r, $9.schedule))
+ YYERROR;
+ free($9.schedule);
r.flags = $9.flags.b1;
r.flagset = $9.flags.b2;
if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
@@ -2533,6 +2538,13 @@
}
filter_opts.label = $1;
}
+ | schedule {
+ if (filter_opts.schedule) {
+ yyerror("schedule cannot be redefined");
+ YYERROR;
+ }
+ filter_opts.schedule = $1;
+ }
| qname {
if (filter_opts.queues.qname) {
yyerror("queue cannot be redefined");
@@ -3852,6 +3864,11 @@
}
;
+schedule : SCHEDULE STRING {
+ $$ = $2;
+ }
+ ;
+
qname : QUEUE STRING {
$$.qname = $2;
$$.pqname = NULL;
@@ -5260,6 +5277,7 @@
int added = 0, error = 0;
char ifname[IF_NAMESIZE];
char label[PF_RULE_LABEL_SIZE];
+ char schedule[PF_RULE_LABEL_SIZE];
char tagname[PF_TAG_NAME_SIZE];
char match_tagname[PF_TAG_NAME_SIZE];
struct pf_pooladdr *pa;
@@ -5268,6 +5286,8 @@
if (strlcpy(label, r->label, sizeof(label)) >= sizeof(label))
errx(1, "expand_rule: strlcpy");
+ if (strlcpy(schedule, r->schedule, sizeof(schedule)) >= sizeof(schedule))
+ errx(1, "expand_rule: strlcpy");
if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
errx(1, "expand_rule: strlcpy");
if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
@@ -5319,6 +5339,9 @@
if (strlcpy(r->label, label, sizeof(r->label)) >=
sizeof(r->label))
errx(1, "expand_rule: strlcpy");
+ if (strlcpy(r->schedule, schedule, sizeof(r->schedule)) >=
+ sizeof(r->schedule))
+ errx(1, "expand_rule: strlcpy");
if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
sizeof(r->tagname))
errx(1, "expand_rule: strlcpy");
@@ -5327,6 +5350,8 @@
errx(1, "expand_rule: strlcpy");
expand_label(r->label, PF_RULE_LABEL_SIZE, r->ifname, r->af,
src_host, src_port, dst_host, dst_port, proto->proto);
+ expand_label(r->schedule, PF_RULE_LABEL_SIZE, r->ifname, r->af,
+ src_host, src_port, dst_host, dst_port, proto->proto);
expand_label(r->tagname, PF_TAG_NAME_SIZE, r->ifname, r->af,
src_host, src_port, dst_host, dst_port, proto->proto);
expand_label(r->match_tagname, PF_TAG_NAME_SIZE, r->ifname,
@@ -5592,6 +5617,7 @@
{ "rtable", RTABLE},
{ "rule", RULE},
{ "ruleset-optimization", RULESET_OPTIMIZATION},
+ { "schedule", SCHEDULE},
{ "scrub", SCRUB},
{ "set", SET},
{ "set-tos", SETTOS},
@@ -6227,6 +6253,20 @@
return (0);
}
+int
+rule_schedule(struct pfctl_rule *r, char *s)
+{
+ if (s) {
+ if (strlcpy(r->schedule, s, sizeof(r->schedule)) >=
+ sizeof(r->schedule)) {
+ yyerror("rule schedule too long (max %d chars)",
+ sizeof(r->schedule)-1);
+ return (-1);
+ }
+ }
+ return (0);
+}
+
u_int16_t
parseicmpspec(char *w, sa_family_t af)
{
Index: sbin/pfctl/pfctl.8
===================================================================
--- sbin/pfctl/pfctl.8
+++ sbin/pfctl/pfctl.8
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 3, 2016
+.Dd April 9, 2021
.Dt PFCTL 8
.Os
.Sh NAME
@@ -56,6 +56,7 @@
.Op Ar address ...
.Oc Xc
.Op Fl x Ar level
+.Op Fl y Ar schedule
.Ek
.Sh DESCRIPTION
The
@@ -658,6 +659,9 @@
.It Fl x Cm loud
Generate debug messages for common conditions.
.El
+.It Fl y Ar schedule
+Kill all states marked with
+.Ar schedule .
.It Fl z
Clear per-rule statistics.
.El
Index: sbin/pfctl/pfctl.c
===================================================================
--- sbin/pfctl/pfctl.c
+++ sbin/pfctl/pfctl.c
@@ -125,6 +125,7 @@
static const char *pf_device = "/dev/pf";
static char *ifaceopt;
static char *tableopt;
+static char *schedule;
static const char *tblcmdopt;
static int src_node_killers;
static char *src_node_kill[2];
@@ -2122,7 +2123,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:mnNOo:Pp:rRs:t:T:vx:y:z")) != -1) {
switch (ch) {
case 'a':
anchoropt = optarg;
@@ -2244,6 +2245,14 @@
}
mode = O_RDWR;
break;
+ case 'y':
+ if (schedule != NULL && strlen(schedule) >
+ PF_RULE_LABEL_SIZE)
+ errx(1, "Schedule label cannot be more than %d"
+ " characters\n", PF_RULE_LABEL_SIZE);
+ schedule = optarg;
+ mode = O_RDWR;
+ break;
case 'z':
opts |= PF_OPT_CLRRULECTRS;
mode = O_RDWR;
@@ -2447,6 +2456,17 @@
if (src_node_killers)
pfctl_kill_src_nodes(dev, ifaceopt, opts);
+ if (schedule) {
+ int killed;
+
+ if (libpfctl_kill_schedule(dev, schedule, &killed))
+ err(1, "DIOCKILLSCHEDULE");
+
+ if ((opts & PF_OPT_QUIET) == 0)
+ fprintf(stderr, "killed %d states from %s schedule label\n",
+ killed, schedule);
+ }
+
if (tblcmdopt != NULL) {
error = pfctl_command_tables(argc, argv, tableopt,
tblcmdopt, rulesopt, anchorname, opts);
Index: sbin/pfctl/pfctl_parser.c
===================================================================
--- sbin/pfctl/pfctl_parser.c
+++ sbin/pfctl/pfctl_parser.c
@@ -1018,6 +1018,8 @@
}
if (r->label[0])
printf(" label \"%s\"", r->label);
+ if (r->schedule[0])
+ printf(" schedule \"%s\"", r->schedule);
if (r->qname[0] && r->pqname[0])
printf(" queue(%s, %s)", r->qname, r->pqname);
else if (r->qname[0])
Index: share/man/man5/pf.conf.5
===================================================================
--- share/man/man5/pf.conf.5
+++ share/man/man5/pf.conf.5
@@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd December 7, 2019
+.Dd April 9, 2021
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -1807,6 +1807,13 @@
The macro expansion for the
.Ar label
directive occurs only at configuration file parse time, not during runtime.
+.It Ar schedule Aq Ar string
+Adds a schedule label (name) to the rule, which can be used to identify and
+terminate states created by matching rules,
+using
+.Bd -literal -offset indent
+# pfctl -y string
+.Ed
.It Xo Ar queue Aq Ar queue
.No \*(Ba ( Aq Ar queue ,
.Aq Ar queue )
@@ -2885,9 +2892,10 @@
"max-mss" number | "random-id" | "reassemble tcp" |
fragmentation | "allow-opts" |
"label" string | "tag" string | [ ! ] "tagged" string |
- "set prio" ( number | "(" number [ [ "," ] number ] ")" ) |
- "queue" ( string | "(" string [ [ "," ] string ] ")" ) |
- "rtable" number | "probability" number"%" | "prio" number
+ "schedule" string | "set prio" ( number | "(" number [ [ "," ]
+ number ] ")" ) | "queue" ( string | "(" string [ [ "," ]
+ string ] ")" ) | "rtable" number | "probability" number"%" |
+ "prio" number
nat-rule = [ "no" ] "nat" [ "pass" [ "log" [ "(" logopts ")" ] ] ]
[ "on" ifspec ] [ af ]
Index: sys/net/pfvar.h
===================================================================
--- sys/net/pfvar.h
+++ sys/net/pfvar.h
@@ -324,6 +324,7 @@
struct pf_rule_addr dst;
union pf_krule_ptr skip[PF_SKIP_COUNT];
char label[PF_RULE_LABEL_SIZE];
+ char schedule[PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
@@ -1299,6 +1300,8 @@
#define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface)
#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
+#define DIOCKILLSCHEDULE _IOWR('D', 92, struct pfioc_nv)
+
struct pf_ifspeed_v0 {
char ifname[IFNAMSIZ];
u_int32_t baudrate;
Index: sys/netpfil/pf/pf_ioctl.c
===================================================================
--- sys/netpfil/pf/pf_ioctl.c
+++ sys/netpfil/pf/pf_ioctl.c
@@ -197,6 +197,7 @@
static int pf_clear_tables(void);
static void pf_clear_srcnodes(struct pf_ksrc_node *);
static void pf_kill_srcnodes(struct pfioc_src_node_kill *);
+static int pf_kill_schedule(struct pfioc_nv *);
static void pf_tbladdr_copyout(struct pf_addr_wrap *);
/*
@@ -1764,6 +1765,9 @@
&rule->dst));
PFNV_CHK(pf_nvstring(nvl, "label", rule->label, sizeof(rule->label)));
+ if (nvlist_exists_string(nvl, "schedule"))
+ PFNV_CHK(pf_nvstring(nvl, "schedule", rule->schedule,
+ sizeof(rule->schedule)));
PFNV_CHK(pf_nvstring(nvl, "ifname", rule->ifname,
sizeof(rule->ifname)));
PFNV_CHK(pf_nvstring(nvl, "qname", rule->qname, sizeof(rule->qname)));
@@ -1938,6 +1942,7 @@
}
nvlist_add_string(nvl, "label", rule->label);
+ nvlist_add_string(nvl, "schedule", rule->schedule);
nvlist_add_string(nvl, "ifname", rule->ifname);
nvlist_add_string(nvl, "qname", rule->qname);
nvlist_add_string(nvl, "pqname", rule->pqname);
@@ -4372,6 +4377,10 @@
pf_kill_srcnodes((struct pfioc_src_node_kill *)addr);
break;
+ case DIOCKILLSCHEDULE:
+ error = pf_kill_schedule((struct pfioc_nv *)addr);
+ break;
+
case DIOCSETHOSTID: {
u_int32_t *hostid = (u_int32_t *)addr;
@@ -4651,6 +4660,74 @@
psnk->psnk_killed = pf_free_src_nodes(&kill);
}
+static int
+pf_kill_schedule(struct pfioc_nv *nv)
+{
+ nvlist_t *nvl = NULL;
+ void *nvlpacked = NULL;
+ const char *schedule;
+ struct pf_state *state;
+ int killed = 0;
+ int error = 0;
+
+#define ERROUT(x) do { error = (x); goto on_error; } while (0)
+
+ if (nv->len > pf_ioctl_maxcount)
+ ERROUT(ENOMEM);
+
+ nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK);
+ if (nvlpacked == NULL)
+ ERROUT(ENOMEM);
+
+ error = copyin(nv->data, nvlpacked, nv->len);
+ if (error)
+ ERROUT(error);
+
+ nvl = nvlist_unpack(nvlpacked, nv->len, 0);
+ if (nvl == NULL)
+ ERROUT(EBADMSG);
+
+ if (! nvlist_exists_string(nvl, "schedule"))
+ ERROUT(EBADMSG);
+
+ schedule = nvlist_get_string(nvl, "schedule");
+
+ for (u_long i = 0; i <= pf_hashmask; i++) {
+ struct pf_idhash *ih = &V_pf_idhash[i];
+
+relock_DIOCKILLSCHEDULE:
+ PF_HASHROW_LOCK(ih);
+ LIST_FOREACH(state, &ih->states, entry) {
+ if (!strcmp(schedule, state->rule.ptr->schedule)) {
+ pf_unlink_state(state, PF_ENTER_LOCKED);
+ killed++;
+ goto relock_DIOCKILLSCHEDULE;
+ }
+ }
+ PF_HASHROW_UNLOCK(ih);
+ }
+
+ nvlist_destroy(nvl);
+ nvl = nvlist_create(0);
+ if (nvl == NULL)
+ ERROUT(ENOMEM);
+
+ nvlist_add_number(nvl, "killed", killed);
+ free(nvlpacked, M_TEMP);
+ nvlpacked = nvlist_pack(nvl, &nv->len);
+ if (nvlpacked == NULL)
+ ERROUT(ENOMEM);
+
+ error = copyout(nvlpacked, nv->data, nv->len);
+
+#undef ERROUT
+on_error:
+ free(nvlpacked, M_TEMP);
+ nvlist_destroy(nvl);
+
+ return (error);
+}
+
/*
* XXX - Check for version missmatch!!!
*/
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 20, 6:37 AM (3 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27093061
Default Alt Text
D29669.diff (14 KB)
Attached To
Mode
D29669: pf: Kill connections by schedule
Attached
Detach File
Event Timeline
Log In to Comment