aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2017-03-15 13:36:35 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2017-03-15 13:36:35 +0000
commit6ed14738679b38f27c789e01791809ffdef6bc02 (patch)
tree1807b6e6463999d7626f023d6c04cadba2fee76f /sbin
parent776c68249b2c2a850a6d21a2bbf15e38395f34d0 (diff)
downloadsrc-6ed14738679b38f27c789e01791809ffdef6bc02.tar.gz
src-6ed14738679b38f27c789e01791809ffdef6bc02.zip
Change the syntax of ipfw's named states.
Since the state name is an optional argument, it often can conflict with other options. To avoid ambiguity now the state name must be prefixed with a colon. Obtained from: Yandex LLC MFC after: 2 week Sponsored by: Yandex LLC
Notes
Notes: svn path=/head/; revision=315305
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw.830
-rw-r--r--sbin/ipfw/ipfw2.c74
2 files changed, 45 insertions, 59 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index dd8f34b3b6a0..f7c3a78f6262 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 18, 2016
+.Dd March 15, 2017
.Dt IPFW 8
.Os
.Sh NAME
@@ -781,7 +781,7 @@ will be executed when the packet matches the body of the rule.
.It Cm allow | accept | pass | permit
Allow packets that match rule.
The search terminates.
-.It Cm check-state Op Ar flowname | Cm any
+.It Cm check-state Op Ar :flowname | Cm :any
Checks the packet against the dynamic ruleset.
If a match is found, execute the action associated with
the rule which generated this dynamic rule, otherwise
@@ -797,15 +797,15 @@ or
.Cm limit
rule.
The
-.Ar flowname
+.Ar :flowname
is symbolic name assigned to dynamic rule by
.Cm keep-state
opcode.
The special flowname
-.Cm any
+.Cm :any
can be used to ignore states flowname when matching.
The
-.Cm default
+.Cm :default
keyword is special name used for compatibility with old rulesets.
.It Cm count
Update counters for all packets that match rule.
@@ -1662,7 +1662,7 @@ specified in the same way as
.It Cm ipversion Ar ver
Matches IP packets whose IP version field is
.Ar ver .
-.It Cm keep-state Op Ar flowname
+.It Cm keep-state Op Ar :flowname
Upon a match, the firewall will create a dynamic rule, whose
default behaviour is to match bidirectional traffic between
source and destination IP/port using the same protocol.
@@ -1671,19 +1671,19 @@ The rule has a limited lifetime (controlled by a set of
variables), and the lifetime is refreshed every time a matching
packet is found.
The
-.Ar flowname
+.Ar :flowname
is used to assign additional to addresses, ports and protocol parameter
to dynamic rule. It can be used for more accurate matching by
.Cm check-state
rule.
The
-.Cm default
+.Cm :default
keyword is special name used for compatibility with old rulesets.
.It Cm layer2
Matches only layer2 packets, i.e., those passed to
.Nm
from ether_demux() and ether_output_frame().
-.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N Op Ar flowname
+.It Cm limit Bro Cm src-addr | src-port | dst-addr | dst-port Brc Ar N Op Ar :flowname
The firewall will only allow
.Ar N
connections with the same
@@ -2286,7 +2286,7 @@ are completely equivalent afterwards).
Rules created by
.Cm keep-state
option also have a
-.Ar flowname
+.Ar :flowname
taken from it.
This name is used in matching together with addresses, ports and protocol.
Dynamic rules will be checked at the first
@@ -2297,23 +2297,23 @@ occurrence, and the action performed upon a match will be the same
as in the parent rule.
.Pp
Note that no additional attributes other than protocol and IP addresses
-and ports and flowname are checked on dynamic rules.
+and ports and :flowname are checked on dynamic rules.
.Pp
The typical use of dynamic rules is to keep a closed firewall configuration,
but let the first TCP SYN packet from the inside network install a
dynamic rule for the flow so that packets belonging to that session
will be allowed through the firewall:
.Pp
-.Dl "ipfw add check-state OUTBOUND"
-.Dl "ipfw add allow tcp from my-subnet to any setup keep-state OUTBOUND"
+.Dl "ipfw add check-state :OUTBOUND"
+.Dl "ipfw add allow tcp from my-subnet to any setup keep-state :OUTBOUND"
.Dl "ipfw add deny tcp from any to any"
.Pp
A similar approach can be used for UDP, where an UDP packet coming
from the inside will install a dynamic rule to let the response through
the firewall:
.Pp
-.Dl "ipfw add check-state OUTBOUND"
-.Dl "ipfw add allow udp from my-subnet to any keep-state OUTBOUND"
+.Dl "ipfw add check-state :OUTBOUND"
+.Dl "ipfw add allow udp from my-subnet to any keep-state :OUTBOUND"
.Dl "ipfw add deny udp from any to any"
.Pp
Dynamic rules expire after some time, which depends on the status
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 7a8519a3dfed..b26d7f04aa58 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -1483,7 +1483,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
cmd->arg1, IPFW_TLV_STATE_NAME);
else
ename = NULL;
- bprintf(bp, " %s", ename ? ename: "any");
+ bprintf(bp, " :%s", ename ? ename: "any");
/* avoid printing anything else */
flags = HAVE_PROTO | HAVE_SRCIP |
HAVE_DSTIP | HAVE_IP;
@@ -2076,7 +2076,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
case O_KEEP_STATE:
bprintf(bp, " keep-state");
- bprintf(bp, " %s",
+ bprintf(bp, " :%s",
object_search_ctlv(fo->tstate, cmd->arg1,
IPFW_TLV_STATE_NAME));
break;
@@ -2095,7 +2095,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
comma = ",";
}
bprint_uint_arg(bp, " ", c->conn_limit);
- bprintf(bp, " %s",
+ bprintf(bp, " :%s",
object_search_ctlv(fo->tstate, cmd->arg1,
IPFW_TLV_STATE_NAME));
break;
@@ -2198,7 +2198,7 @@ show_dyn_state(struct cmdline_opts *co, struct format_opts *fo,
} else
bprintf(bp, " UNKNOWN <-> UNKNOWN");
if (d->kidx != 0)
- bprintf(bp, " %s", object_search_ctlv(fo->tstate,
+ bprintf(bp, " :%s", object_search_ctlv(fo->tstate,
d->kidx, IPFW_TLV_STATE_NAME));
}
@@ -3714,27 +3714,25 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
case TOK_CHECKSTATE:
have_state = action;
action->opcode = O_CHECK_STATE;
- if (*av == NULL) {
+ if (*av == NULL ||
+ match_token(rule_options, *av) == TOK_COMMENT) {
action->arg1 = pack_object(tstate,
default_state_name, IPFW_TLV_STATE_NAME);
break;
}
- if (strcmp(*av, "any") == 0)
- action->arg1 = 0;
- else if ((i = match_token(rule_options, *av)) != -1) {
- action->arg1 = pack_object(tstate,
- default_state_name, IPFW_TLV_STATE_NAME);
- if (i != TOK_COMMENT)
- warn("Ambiguous state name '%s', '%s'"
- " used instead.\n", *av,
- default_state_name);
+ if (*av[0] == ':') {
+ if (strcmp(*av + 1, "any") == 0)
+ action->arg1 = 0;
+ else if (state_check_name(*av + 1) == 0)
+ action->arg1 = pack_object(tstate, *av + 1,
+ IPFW_TLV_STATE_NAME);
+ else
+ errx(EX_DATAERR, "Invalid state name %s",
+ *av);
+ av++;
break;
- } else if (state_check_name(*av) == 0)
- action->arg1 = pack_object(tstate, *av,
- IPFW_TLV_STATE_NAME);
- else
- errx(EX_DATAERR, "Invalid state name %s", *av);
- av++;
+ }
+ errx(EX_DATAERR, "Invalid state name %s", *av);
break;
case TOK_ACCEPT:
@@ -4577,22 +4575,16 @@ read_options:
if (have_state)
errx(EX_USAGE, "only one of keep-state "
"and limit is allowed");
- if (*av == NULL ||
- (i = match_token(rule_options, *av)) != -1) {
- if (*av != NULL && i != TOK_COMMENT)
- warn("Ambiguous state name '%s',"
- " '%s' used instead.\n", *av,
- default_state_name);
- uidx = pack_object(tstate, default_state_name,
- IPFW_TLV_STATE_NAME);
- } else {
- if (state_check_name(*av) != 0)
+ if (*av != NULL && *av[0] == ':') {
+ if (state_check_name(*av + 1) != 0)
errx(EX_DATAERR,
"Invalid state name %s", *av);
- uidx = pack_object(tstate, *av,
+ uidx = pack_object(tstate, *av + 1,
IPFW_TLV_STATE_NAME);
av++;
- }
+ } else
+ uidx = pack_object(tstate, default_state_name,
+ IPFW_TLV_STATE_NAME);
have_state = cmd;
fill_cmd(cmd, O_KEEP_STATE, 0, uidx);
break;
@@ -4629,22 +4621,16 @@ read_options:
TOK_LIMIT, rule_options);
av++;
- if (*av == NULL ||
- (i = match_token(rule_options, *av)) != -1) {
- if (*av != NULL && i != TOK_COMMENT)
- warn("Ambiguous state name '%s',"
- " '%s' used instead.\n", *av,
- default_state_name);
- cmd->arg1 = pack_object(tstate,
- default_state_name, IPFW_TLV_STATE_NAME);
- } else {
- if (state_check_name(*av) != 0)
+ if (*av != NULL && *av[0] == ':') {
+ if (state_check_name(*av + 1) != 0)
errx(EX_DATAERR,
"Invalid state name %s", *av);
- cmd->arg1 = pack_object(tstate, *av,
+ cmd->arg1 = pack_object(tstate, *av + 1,
IPFW_TLV_STATE_NAME);
av++;
- }
+ } else
+ cmd->arg1 = pack_object(tstate,
+ default_state_name, IPFW_TLV_STATE_NAME);
break;
}