git: e56b2f0b2804 - stable/12 - MFC r364117 by glebius:
Gordon Bergling
gbe at FreeBSD.org
Sun Jan 3 13:27:05 UTC 2021
The branch stable/12 has been updated by gbe (doc committer):
URL: https://cgit.FreeBSD.org/src/commit/?id=e56b2f0b28048cea88fa6000a2bf08a75f055526
commit e56b2f0b28048cea88fa6000a2bf08a75f055526
Author: Gleb Smirnoff <glebius at FreeBSD.org>
AuthorDate: 2020-08-11 15:46:22 +0000
Commit: Gordon Bergling <gbe at FreeBSD.org>
CommitDate: 2021-01-03 13:23:48 +0000
MFC r364117 by glebius:
ipfw: make the "frag" keyword accept additional options "mf",
"df", "rf" and "offset". This allows to match on specific
bits of ip_off field.
For compatibility reasons lack of keyword means "offset".
Reviewed by: ae
Approved by: glebius
Differential Revision: https://reviews.freebsd.org/D26021
(cherry picked from commit 825398f946221045c565363a0349f68d054d6455)
---
sbin/ipfw/ipfw.8 | 33 +++++++++++++++++++++++++--------
sbin/ipfw/ipfw2.c | 20 ++++++++++++++++++--
sys/netpfil/ipfw/ip_fw2.c | 18 +++++++++++++++++-
3 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index ea35a2767845..58bc3662fcc7 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 21, 2019
+.Dd August 10, 2020
.Dt IPFW 8
.Os
.Sh NAME
@@ -600,7 +600,7 @@ See Section
By name or address
.It Misc. IP header fields
Version, type of service, datagram length, identification,
-fragment flag (non-zero IP offset),
+fragmentation flags,
Time To Live
.It IP options
.It IPv6 Extension headers
@@ -1602,12 +1602,29 @@ Matches IPv6 packets containing any of the flow labels given in
.Ar labels .
.Ar labels
is a comma separated list of numeric flow labels.
-.It Cm frag
-Matches packets that are fragments and not the first
-fragment of an IP datagram.
-Note that these packets will not have
-the next protocol header (e.g.\& TCP, UDP) so options that look into
-these headers cannot match.
+.It Cm frag Ar spec
+Matches IPv4 packets whose
+.Cm ip_off
+field contains the comma separated list of IPv4 fragmentation
+options specified in
+.Ar spec .
+The recognized options are:
+.Cm df
+.Pq Dv don't fragment ,
+.Cm mf
+.Pq Dv more fragments ,
+.Cm rf
+.Pq Dv reserved fragment bit
+.Cm offset
+.Pq Dv non-zero fragment offset .
+The absence of a particular options may be denoted
+with a
+.Ql \&! .
+.Pp
+Empty list of options defaults to matching on non-zero fragment offset.
+Such rule would match all not the first fragment datagrams,
+both IPv4 and IPv6.
+This is a backward compatibility with older rulesets.
.It Cm gid Ar group
Matches all TCP or UDP packets sent by or received for a
.Ar group .
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index cf66422d2ff0..e0b5371adb91 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -168,6 +168,14 @@ static struct _s_x f_iptos[] = {
{ NULL, 0 }
};
+static struct _s_x f_ipoff[] = {
+ { "rf", IP_RF >> 8 },
+ { "df", IP_DF >> 8 },
+ { "mf", IP_MF >> 8 },
+ { "offset", 0x1 },
+ { NULL, 0}
+};
+
struct _s_x f_ipdscp[] = {
{ "af11", IPTOS_DSCP_AF11 >> 2 }, /* 001010 */
{ "af12", IPTOS_DSCP_AF12 >> 2 }, /* 001100 */
@@ -1531,7 +1539,7 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo,
IPPROTO_ETHERTYPE, cmd->opcode);
break;
case O_FRAG:
- bprintf(bp, " frag");
+ print_flags(bp, "frag", cmd, f_ipoff);
break;
case O_FIB:
bprintf(bp, " fib %u", cmd->arg1);
@@ -4553,7 +4561,15 @@ read_options:
break;
case TOK_FRAG:
- fill_cmd(cmd, O_FRAG, 0, 0);
+ fill_flags_cmd(cmd, O_FRAG, f_ipoff, *av);
+ /*
+ * Compatibility: no argument after "frag"
+ * keyword equals to "frag offset".
+ */
+ if (cmd->arg1 == 0)
+ cmd->arg1 = 0x1;
+ else
+ av++;
break;
case TOK_LAYER2:
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
index 90f3b3c08198..f639a3bfabbd 100644
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -1916,7 +1916,23 @@ do { \
break;
case O_FRAG:
- match = (offset != 0);
+ if (is_ipv4) {
+ /*
+ * Since flags_match() works with
+ * uint8_t we pack ip_off into 8 bits.
+ * For this match offset is a boolean.
+ */
+ match = flags_match(cmd,
+ ((ntohs(ip->ip_off) & ~IP_OFFMASK)
+ >> 8) | (offset != 0));
+ } else {
+ /*
+ * Compatiblity: historically bare
+ * "frag" would match IPv6 fragments.
+ */
+ match = (cmd->arg1 == 0x1 &&
+ (offset != 0));
+ }
break;
case O_IN: /* "out" is "not in" */
More information about the dev-commits-src-all
mailing list