aboutsummaryrefslogtreecommitdiff
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2018-12-04 16:12:43 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2018-12-04 16:12:43 +0000
commitd66f9c86fa3fd8d8f0a56ea96b03ca11f2fac1fb (patch)
tree0315ee86648d11c7484394ebdf189819d9c638a1 /sbin/ipfw
parentcefe3d67e29b9d9321a0677cc565d8c05c230d82 (diff)
downloadsrc-d66f9c86fa3fd8d8f0a56ea96b03ca11f2fac1fb.tar.gz
src-d66f9c86fa3fd8d8f0a56ea96b03ca11f2fac1fb.zip
Add ability to request listing and deleting only for dynamic states.
This can be useful, when net.inet.ip.fw.dyn_keep_states is enabled, but after rules reloading some state must be deleted. Added new flag '-D' for such purpose. Retire '-e' flag, since there can not be expired states in the meaning that this flag historically had. Also add "verbose" mode for listing of dynamic states, it can be enabled with '-v' flag and adds additional information to states list. This can be useful for debugging. Obtained from: Yandex LLC MFC after: 2 months Sponsored by: Yandex LLC
Notes
Notes: svn path=/head/; revision=341472
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw.89
-rw-r--r--sbin/ipfw/ipfw2.c65
-rw-r--r--sbin/ipfw/ipfw2.h4
-rw-r--r--sbin/ipfw/main.c8
4 files changed, 61 insertions, 25 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 8e3acb3e6d1c..79b874c3b00e 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 13, 2018
+.Dd December 4, 2018
.Dt IPFW 8
.Os
.Sh NAME
@@ -310,10 +310,9 @@ i.e., omitting the "ip from any to any" string
when this does not carry any additional information.
.It Fl d
When listing, show dynamic rules in addition to static ones.
-.It Fl e
-When listing and
-.Fl d
-is specified, also show expired dynamic rules.
+.It Fl D
+When listing, show only dynamic states.
+When deleting, delete only dynamic states.
.It Fl f
Run without prompting for confirmation for commands that can cause problems if misused,
i.e.,
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index dfd472ac8a0c..1092d5e22719 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -2247,10 +2247,9 @@ show_dyn_state(struct cmdline_opts *co, struct format_opts *fo,
uint16_t rulenum;
char buf[INET6_ADDRSTRLEN];
- if (!co->do_expired) {
- if (!d->expire && !(d->dyn_type == O_LIMIT_PARENT))
- return;
- }
+ if (d->expire == 0 && d->dyn_type != O_LIMIT_PARENT)
+ return;
+
bcopy(&d->rule, &rulenum, sizeof(rulenum));
bprintf(bp, "%05d", rulenum);
if (fo->pcwidth > 0 || fo->bcwidth > 0) {
@@ -2292,6 +2291,33 @@ show_dyn_state(struct cmdline_opts *co, struct format_opts *fo,
if (d->kidx != 0)
bprintf(bp, " :%s", object_search_ctlv(fo->tstate,
d->kidx, IPFW_TLV_STATE_NAME));
+
+#define BOTH_SYN (TH_SYN | (TH_SYN << 8))
+#define BOTH_FIN (TH_FIN | (TH_FIN << 8))
+ if (co->verbose) {
+ bprintf(bp, " state 0x%08x%s", d->state,
+ d->state ? " ": ",");
+ if (d->state & IPFW_DYN_ORPHANED)
+ bprintf(bp, "ORPHANED,");
+ if ((d->state & BOTH_SYN) == BOTH_SYN)
+ bprintf(bp, "BOTH_SYN,");
+ else {
+ if (d->state & TH_SYN)
+ bprintf(bp, "F_SYN,");
+ if (d->state & (TH_SYN << 8))
+ bprintf(bp, "R_SYN,");
+ }
+ if ((d->state & BOTH_FIN) == BOTH_FIN)
+ bprintf(bp, "BOTH_FIN,");
+ else {
+ if (d->state & TH_FIN)
+ bprintf(bp, "F_FIN,");
+ if (d->state & (TH_FIN << 8))
+ bprintf(bp, "R_FIN,");
+ }
+ bprintf(bp, " f_ack 0x%x, r_ack 0x%x", d->ack_fwd,
+ d->ack_rev);
+ }
}
static int
@@ -2695,7 +2721,8 @@ ipfw_list(int ac, char *av[], int show_counters)
cfg = NULL;
sfo.show_counters = show_counters;
sfo.show_time = co.do_time;
- sfo.flags = IPFW_CFG_GET_STATIC;
+ if (co.do_dynamic != 2)
+ sfo.flags |= IPFW_CFG_GET_STATIC;
if (co.do_dynamic != 0)
sfo.flags |= IPFW_CFG_GET_STATES;
if ((sfo.show_counters | sfo.show_time) != 0)
@@ -2740,17 +2767,15 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
fo->set_mask = cfg->set_mask;
ctlv = (ipfw_obj_ctlv *)(cfg + 1);
+ if (ctlv->head.type == IPFW_TLV_TBLNAME_LIST) {
+ object_sort_ctlv(ctlv);
+ fo->tstate = ctlv;
+ readsz += ctlv->head.length;
+ ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv + ctlv->head.length);
+ }
if (cfg->flags & IPFW_CFG_GET_STATIC) {
/* We've requested static rules */
- if (ctlv->head.type == IPFW_TLV_TBLNAME_LIST) {
- object_sort_ctlv(ctlv);
- fo->tstate = ctlv;
- readsz += ctlv->head.length;
- ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv +
- ctlv->head.length);
- }
-
if (ctlv->head.type == IPFW_TLV_RULE_LIST) {
rbase = (ipfw_obj_tlv *)(ctlv + 1);
rcnt = ctlv->count;
@@ -2777,10 +2802,12 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
if (ac == 0) {
fo->first = 0;
fo->last = IPFW_DEFAULT_RULE;
- list_static_range(co, fo, &bp, rbase, rcnt);
+ if (cfg->flags & IPFW_CFG_GET_STATIC)
+ list_static_range(co, fo, &bp, rbase, rcnt);
if (co->do_dynamic && dynsz > 0) {
- printf("## Dynamic rules (%d %zu):\n", fo->dcnt, dynsz);
+ printf("## Dynamic rules (%d %zu):\n", fo->dcnt,
+ dynsz);
list_dyn_range(co, fo, &bp, dynbase, dynsz);
}
@@ -2800,6 +2827,9 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
continue;
}
+ if ((cfg->flags & IPFW_CFG_GET_STATIC) == 0)
+ continue;
+
if (list_static_range(co, fo, &bp, rbase, rcnt) == 0) {
/* give precedence to other error(s) */
if (exitval == EX_OK)
@@ -3313,6 +3343,8 @@ ipfw_delete(char *av[])
rt.flags |= IPFW_RCFLAG_SET;
}
}
+ if (co.do_dynamic == 2)
+ rt.flags |= IPFW_RCFLAG_DYNAMIC;
i = do_range_cmd(IP_FW_XDEL, &rt);
if (i != 0) {
exitval = EX_UNAVAILABLE;
@@ -3320,7 +3352,8 @@ ipfw_delete(char *av[])
continue;
warn("rule %u: setsockopt(IP_FW_XDEL)",
rt.start_rule);
- } else if (rt.new_set == 0 && do_set == 0) {
+ } else if (rt.new_set == 0 && do_set == 0 &&
+ co.do_dynamic != 2) {
exitval = EX_UNAVAILABLE;
if (co.do_quiet)
continue;
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index bb0a4cdfdeb3..8e279389a1eb 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -37,8 +37,6 @@ struct cmdline_opts {
int do_quiet; /* Be quiet in add and flush */
int do_pipe; /* this cmd refers to a pipe/queue/sched */
int do_nat; /* this cmd refers to a nat config */
- int do_dynamic; /* display dynamic rules */
- int do_expired; /* display expired dynamic rules */
int do_compact; /* show rules in compact mode */
int do_force; /* do not ask for confirmation */
int show_sets; /* display the set each rule belongs to */
@@ -48,6 +46,8 @@ struct cmdline_opts {
/* The options below can have multiple values. */
+ int do_dynamic; /* 1 - display dynamic rules */
+ /* 2 - display/delete only dynamic rules */
int do_sort; /* field to sort results (0 = no) */
/* valid fields are 1 and above */
diff --git a/sbin/ipfw/main.c b/sbin/ipfw/main.c
index befc1ec867d7..0a9791b77981 100644
--- a/sbin/ipfw/main.c
+++ b/sbin/ipfw/main.c
@@ -262,7 +262,7 @@ ipfw_main(int oldac, char **oldav)
save_av = av;
optind = optreset = 1; /* restart getopt() */
- while ((ch = getopt(ac, av, "abcdefhinNp:qs:STtv")) != -1)
+ while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1)
switch (ch) {
case 'a':
do_acct = 1;
@@ -281,8 +281,12 @@ ipfw_main(int oldac, char **oldav)
co.do_dynamic = 1;
break;
+ case 'D':
+ co.do_dynamic = 2;
+ break;
+
case 'e':
- co.do_expired = 1;
+ /* nop for compatibility */
break;
case 'f':