Page MenuHomeFreeBSD

D53694.diff
No OneTemporary

D53694.diff

diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1421,8 +1421,7 @@
with multiple addresses) is provided for convenience only and
its use is discouraged.
.It Ar addr : Oo Cm not Oc Bro
-.Cm any | me | me6 |
-.Cm table Ns Pq Ar name Ns Op , Ns Ar value
+.Cm any | me | me6 | Ar table-ref
.Ar | addr-list | addr-set
.Brc
.Bl -tag -width indent
@@ -1434,16 +1433,32 @@
Matches any IPv6 address configured on an interface in the system.
The address list is evaluated at the time the packet is
analysed.
-.It Cm table Ns Pq Ar name Ns Op , Ns Ar value
+.El
+.It Ar table-ref :
+A table lookup can be specified in one of the following ways:
+.Bl -tag -width indent
+.It table Ns Pq Ar name Ns
Matches any IPv4 or IPv6 address for which an entry exists in the lookup table
.Ar number .
-If an optional 32-bit unsigned
+.It table Ns Pq Ar name , Ns Ar value
+Matches any IPv4 or IPv6 address for which an entry exists in the lookup table
+.Ar number
+and 32-bit unsigned
+.Ar value
+specified matchess entry value.
+.It table Ns Pq Ar name , Ns Ar value-type Ns = Ns Ar value
+Matches any IPv4 or IPv6 address for which an entry exists in the lookup table
+.Ar number
+and 32-bit unsigned
.Ar value
-is also specified, an entry will match only if it has this value.
+specified matches corresponding
+.Ar value-type
+field for the record found.
+.El
+.Pp
See the
.Sx LOOKUP TABLES
section below for more information on lookup tables.
-.El
.It Ar addr-list : ip-addr Ns Op , Ns Ar addr-list
.It Ar ip-addr :
A host or subnet address specified in one of the following ways:
@@ -1664,9 +1679,9 @@
.It Cm fib Ar fibnum
Matches a packet that has been tagged to use
the given FIB (routing table) number.
-.It Cm flow Ar table Ns Pq Ar name Ns Op , Ns Ar value
-Search for the flow entry in lookup table
-.Ar name .
+.It Cm flow Ar table-ref
+Search for the flow entry in lookup table specified by
+.Ar table-ref .
If not found, the match fails.
Otherwise, the match succeeds and
.Cm tablearg
@@ -1682,16 +1697,16 @@
.Ar labels .
.Ar labels
is a comma separated list of numeric flow labels.
-.It Cm dst-mac Ar table Ns Pq Ar name Ns Op , Ns Ar value
-Search for the destination MAC address entry in lookup table
-.Ar name .
+.It Cm dst-mac Ar table-ref
+Search for the destination MAC address entry in lookup table specified by
+.Ar table-ref .
If not found, the match fails.
Otherwise, the match succeeds and
.Cm tablearg
is set to the value extracted from the table.
-.It Cm src-mac Ar table Ns Pq Ar name Ns Op , Ns Ar value
-Search for the source MAC address entry in lookup table
-.Ar name .
+.It Cm src-mac Ar table-ref
+Search for the source MAC address entry in lookup table specified by
+.Ar table-ref .
If not found, the match fails.
Otherwise, the match succeeds and
.Cm tablearg
@@ -1909,8 +1924,9 @@
One or more
of source and destination addresses and ports can be
specified.
-.It Cm lookup Bro Cm dst-ip | dst-port | dst-mac | src-ip | src-port | src-mac | uid |
-.Cm jail | dscp | mark Brc Ar name
+.It Cm lookup Bro Cm dst-ip | dst-ip6 | dst-port | dst-mac | src-ip |
+.Cm dst-ip6 | src-port | src-mac | uid | jail | dscp | mark Brc Ns Bo : Ns
+.Ar bitmask Bc Ar name
Search an entry in lookup table
.Ar name
that matches the field specified as argument.
@@ -1919,8 +1935,62 @@
.Cm tablearg
is set to the value extracted from the table.
.Pp
+If an optional 32-bit unsigned
+.Ar bitmask
+is specified, value of the field is altered by bitwize AND with
+.Ar bitmask
+and resulting value is being searched instead of original one.
+The
+.Ar bitmask
+is accepted in the following formats:
+.Bl -enum -width indent
+.It
+A dotted-quad form, e.g. 127.88.34.0
+.It
+A number, e.g. 0xf00baa1 or 255
+.It
+As an IPv6 address when specified alongwith
+.Cm dst-ip6
+or
+.Cm src-ip6
+field.
+If used, the rule will match IPv6 packets only.
+Internally the
+.Ar bitmask
+is packed to 32-bit long format (see below) so only zero or 0xf values
+are supported in each 4-bit nibble.
+E.g. ffff:ff00:ffff:ffff:0:0:0:0f0f is a valid
+.Ar bitmask
+value while afff:ff00:ffff:ffff:0:0:0:0f0f is not.
+.El
+.Pp
+The
+.Ar bitmask
+specified for
+.Cm dst-ip
+or
+.Cm src-ip
+is applied to an IPv6 source or destination address as well, each bit in the
+.Ar bitmask
+sets (when 1) or clears (when 0) corresponding 4-bit nibble.
+E.g.
+.Ar bitmask Ns =0xfcff0005 is applied as ffff:ff00:ffff:ffff:0:0:0:0f0f.
+.Pp
This option can be useful to quickly dispatch traffic based on
certain packet fields.
+The
+.Ar bitmask
+allows to implement wildcard lookups by inserting into table masked prefix and
+appying
+.Ar bitmask
+upon each lookup.
+.Pp
+Note:
+.Cm dst-mac
+and
+.Cm src-mac
+lookups currently do not support masking.
+.Pp
See the
.Sx LOOKUP TABLES
section below for more information on lookup tables.
@@ -1983,7 +2053,7 @@
.Cm check-state
in contrast to
.Cm keep-state .
-.It Cm recv | xmit | via Brq Ar ifX | Ar ifmask | Ar table Ns Po Ar name Ns Oo , Ns Ar value Oc Pc | Ar ipno | Ar any
+.It Cm recv | xmit | via Brq Ar ifX | Ar ifmask | Ar table-ref | Ar ipno | Ar any
Matches packets received, transmitted or going through,
respectively, the interface specified by exact name
.Po Ar ifX Pc ,
@@ -2001,8 +2071,8 @@
.Sx EXAMPLES
section.
.Pp
-Table
-.Ar name
+A lookup table specified by
+.Ar table-ref
may be used to match interface by its kernel ifindex.
See the
.Sx LOOKUP TABLES
@@ -4309,7 +4379,8 @@
.Xr route 4
socket, that were logged using rules with
.Cm log Cm logdst Ar rtsock
-opcode. Optional
+opcode.
+Optional
.Ar filter-comment
can be specified to show only those messages, that were logged
by rules with specific rule comment.
@@ -4664,10 +4735,41 @@
The following example illustrate usage of flow tables:
.Pp
.Dl "ipfw table fl create type flow:src-ip,proto,dst-ip,dst-port"
-.Dl "ipfw table fl add 2a02:6b8:77::88,tcp,2a02:6b8:77::99,80 11"
+.Dl "ipfw table fl add 2001:db8:77::88,tcp,2001:db8:77::99,80 11"
.Dl "ipfw table fl add 10.0.0.1,udp,10.0.0.2,53 12"
.Dl ".."
.Dl "ipfw add 100 allow ip from any to any flow 'table(fl,11)' recv ix0"
+.Pp
+The following example illustrate masked table lookups to aid uniform client
+distribution among multiple NAT instances:
+.Bd -literal -offset indent
+# Configure NAT instances
+ipfw nat 10 config ip 192.0.2.0
+ipfw nat 11 config ip 192.0.2.1
+ipfw nat 12 config ip 192.0.2.2
+ipfw nat 13 config ip 192.0.2.3
+
+ipfw table mynats create type addr valtype nat
+# Map external NAT address to NAT instance
+ipfw table mynats add 192.0.2.0 10
+ipfw table mynats add 192.0.2.1 11
+ipfw table mynats add 192.0.2.2 12
+ipfw table mynats add 192.0.2.3 13
+
+# Map last 2 bits of client's IP address to NAT instance
+ipfw table mynats add 0.0.0.0 10
+ipfw table mynats add 0.0.0.1 11
+ipfw table mynats add 0.0.0.2 12
+ipfw table mynats add 0.0.0.3 13
+
+# In -> Out NAT, zero out all bits in a client's IP exept
+# 2 least significant prior to table lookup
+ipfw add nat tablearg ip from 10.0.0.0/24 to any
+ lookup src-ip:0.0.0.3 mynats
+# Out -> In NAT
+ipfw add nat tablearg ip from any to 192.0.2.0/30
+ lookup dst-ip mynats
+.Ed
.Ss SETS OF RULES
To add a set of rules atomically, e.g.\& set 18:
.Pp
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -317,6 +317,8 @@
static struct _s_x lookup_keys[] = {
{ "dst-ip", LOOKUP_DST_IP },
{ "src-ip", LOOKUP_SRC_IP },
+ { "dst-ip6", LOOKUP_DST_IP6 },
+ { "src-ip6", LOOKUP_SRC_IP6 },
{ "dst-port", LOOKUP_DST_PORT },
{ "src-port", LOOKUP_SRC_PORT },
{ "dst-mac", LOOKUP_DST_MAC },
@@ -1352,19 +1354,48 @@
if ((len == F_INSN_SIZE(ipfw_insn_kidx) ||
len == F_INSN_SIZE(ipfw_insn_table)) &&
IPFW_LOOKUP_TYPE(&cmd->o) != LOOKUP_NONE) {
+ static const uint32_t bits_to_mask[] =
+ BIT_MULTIPLICATOR_1_TO_4;
+ char maskbuf[INET6_ADDRSTRLEN];
+ struct in6_addr mask6;
const char *key;
+ uint32_t bitmask;
+ int i;
key = match_value(lookup_keys,
IPFW_LOOKUP_TYPE(&cmd->o));
t = table_search_ctlv(fo->tstate,
insntoc(&cmd->o, kidx)->kidx);
- if (len == F_INSN_SIZE(ipfw_insn_table)) {
+ if (len != F_INSN_SIZE(ipfw_insn_table)) {
+ bprintf(bp, "lookup %s %s",
+ (key != NULL ? key : "<invalid>"), t);
+ return;
+ }
+ bitmask = insntoc(&cmd->o, table)->value;
+ switch (IPFW_LOOKUP_TYPE(&cmd->o)) {
+ case LOOKUP_DST_IP6:
+ case LOOKUP_SRC_IP6:
+ for (i = 3; i >= 0; i--) {
+ mask6.__u6_addr.__u6_addr32[i] =
+ bits_to_mask[bitmask & 0xFF];
+ bitmask >>= 8;
+ }
+ if (inet_ntop(AF_INET6, &mask6, maskbuf,
+ sizeof(maskbuf)) == NULL)
+ strcpy(maskbuf, "<invalid>");
+ bprintf(bp, "lookup %s:%s %s", key, maskbuf, t);
+ break;
+ case LOOKUP_DST_IP:
+ case LOOKUP_SRC_IP:
+ bitmask = htonl(bitmask);
+ bprintf(bp, "lookup %s:%s %s", key,
+ inet_ntoa(*(struct in_addr *)&bitmask), t);
+ break;
+ default:
bprintf(bp, "lookup %s:%#x %s",
(key != NULL ? key : "<invalid>"),
- insntoc(&cmd->o, table)->value, t);
- } else
- bprintf(bp, "lookup %s %s", key != NULL ? key:
- "<invalid>", t);
+ bitmask, t);
+ }
return;
}
/* FALLTHROUGH */
@@ -4133,6 +4164,46 @@
return (ntohs(s->s_port));
}
+static uint32_t
+get_lookup_bitmask(int opcode, const char *src)
+{
+ struct in6_addr mask6;
+ int mc;
+ uint32_t value = 0;
+
+ if (opcode == LOOKUP_SRC_IP6 || opcode == LOOKUP_DST_IP6) {
+ if (inet_pton(AF_INET6, src, &mask6) != 1)
+ errx(EX_USAGE, "invalid IPv6 mask provided");
+ for (mc = 0; mc < 16; mc++) {
+ if (mc > 0)
+ value <<= 2;
+ switch (mask6.s6_addr[mc]) {
+ case 0xFF:
+ value |= 3;
+ break;
+ case 0xF0:
+ value |= 2;
+ break;
+ case 0x0F:
+ value |= 1;
+ break;
+ case 0x00:
+ break;
+ default:
+ errx(EX_USAGE, "invalid IPv6 mask provided");
+ }
+ }
+ /* mask in a dotted-quad notation */
+ } else if (strchr(src, '.') != NULL) {
+ if (inet_aton(src, (struct in_addr *)&value) != 1)
+ errx(EX_USAGE, "invalid dotted-quad mask provided");
+ value = ntohl(value);
+ } else {
+ value = strtoul(src, NULL, 0);
+ }
+ return (value);
+}
+
/*
* Parse arguments and assemble the microinstructions which make up a rule.
* Rules are added into the 'rulebuf' and then copied in the correct order
@@ -5492,6 +5563,10 @@
case LOOKUP_DSCP:
case LOOKUP_MARK:
case LOOKUP_RULENUM:
+ case LOOKUP_SRC_IP:
+ case LOOKUP_DST_IP:
+ case LOOKUP_SRC_IP6:
+ case LOOKUP_DST_IP6:
break;
default:
errx(EX_USAGE,
@@ -5499,7 +5574,7 @@
"for %s", lkey);
}
cmd->len |= F_INSN_SIZE(ipfw_insn_table);
- c->value = strtoul(*av, NULL, 0);
+ c->value = get_lookup_bitmask(i, *av);
if (c->value == 0)
errx(EX_USAGE,
"all-zeroes bitmask for lookup "
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -432,6 +432,8 @@
LOOKUP_SRC_MAC,
LOOKUP_MARK,
LOOKUP_RULENUM,
+ LOOKUP_DST_IP6,
+ LOOKUP_SRC_IP6,
};
enum ipfw_return_type {
@@ -1170,4 +1172,140 @@
uint64_t refcnt;
} ipfw_sopt_info;
+#if BYTE_ORDER == BIG_ENDIAN
+#define BIT_MULTIPLICATOR_1_TO_4 { \
+ 0x00000000, 0x0000000F, 0x000000F0, 0x000000FF, \
+ 0x00000F00, 0x00000F0F, 0x00000FF0, 0x00000FFF, \
+ 0x0000F000, 0x0000F00F, 0x0000F0F0, 0x0000F0FF, \
+ 0x0000FF00, 0x0000FF0F, 0x0000FFF0, 0x0000FFFF, \
+ 0x000F0000, 0x000F000F, 0x000F00F0, 0x000F00FF, \
+ 0x000F0F00, 0x000F0F0F, 0x000F0FF0, 0x000F0FFF, \
+ 0x000FF000, 0x000FF00F, 0x000FF0F0, 0x000FF0FF, \
+ 0x000FFF00, 0x000FFF0F, 0x000FFFF0, 0x000FFFFF, \
+ 0x00F00000, 0x00F0000F, 0x00F000F0, 0x00F000FF, \
+ 0x00F00F00, 0x00F00F0F, 0x00F00FF0, 0x00F00FFF, \
+ 0x00F0F000, 0x00F0F00F, 0x00F0F0F0, 0x00F0F0FF, \
+ 0x00F0FF00, 0x00F0FF0F, 0x00F0FFF0, 0x00F0FFFF, \
+ 0x00FF0000, 0x00FF000F, 0x00FF00F0, 0x00FF00FF, \
+ 0x00FF0F00, 0x00FF0F0F, 0x00FF0FF0, 0x00FF0FFF, \
+ 0x00FFF000, 0x00FFF00F, 0x00FFF0F0, 0x00FFF0FF, \
+ 0x00FFFF00, 0x00FFFF0F, 0x00FFFFF0, 0x00FFFFFF, \
+ 0x0F000000, 0x0F00000F, 0x0F0000F0, 0x0F0000FF, \
+ 0x0F000F00, 0x0F000F0F, 0x0F000FF0, 0x0F000FFF, \
+ 0x0F00F000, 0x0F00F00F, 0x0F00F0F0, 0x0F00F0FF, \
+ 0x0F00FF00, 0x0F00FF0F, 0x0F00FFF0, 0x0F00FFFF, \
+ 0x0F0F0000, 0x0F0F000F, 0x0F0F00F0, 0x0F0F00FF, \
+ 0x0F0F0F00, 0x0F0F0F0F, 0x0F0F0FF0, 0x0F0F0FFF, \
+ 0x0F0FF000, 0x0F0FF00F, 0x0F0FF0F0, 0x0F0FF0FF, \
+ 0x0F0FFF00, 0x0F0FFF0F, 0x0F0FFFF0, 0x0F0FFFFF, \
+ 0x0FF00000, 0x0FF0000F, 0x0FF000F0, 0x0FF000FF, \
+ 0x0FF00F00, 0x0FF00F0F, 0x0FF00FF0, 0x0FF00FFF, \
+ 0x0FF0F000, 0x0FF0F00F, 0x0FF0F0F0, 0x0FF0F0FF, \
+ 0x0FF0FF00, 0x0FF0FF0F, 0x0FF0FFF0, 0x0FF0FFFF, \
+ 0x0FFF0000, 0x0FFF000F, 0x0FFF00F0, 0x0FFF00FF, \
+ 0x0FFF0F00, 0x0FFF0F0F, 0x0FFF0FF0, 0x0FFF0FFF, \
+ 0x0FFFF000, 0x0FFFF00F, 0x0FFFF0F0, 0x0FFFF0FF, \
+ 0x0FFFFF00, 0x0FFFFF0F, 0x0FFFFFF0, 0x0FFFFFFF, \
+ 0xF0000000, 0xF000000F, 0xF00000F0, 0xF00000FF, \
+ 0xF0000F00, 0xF0000F0F, 0xF0000FF0, 0xF0000FFF, \
+ 0xF000F000, 0xF000F00F, 0xF000F0F0, 0xF000F0FF, \
+ 0xF000FF00, 0xF000FF0F, 0xF000FFF0, 0xF000FFFF, \
+ 0xF00F0000, 0xF00F000F, 0xF00F00F0, 0xF00F00FF, \
+ 0xF00F0F00, 0xF00F0F0F, 0xF00F0FF0, 0xF00F0FFF, \
+ 0xF00FF000, 0xF00FF00F, 0xF00FF0F0, 0xF00FF0FF, \
+ 0xF00FFF00, 0xF00FFF0F, 0xF00FFFF0, 0xF00FFFFF, \
+ 0xF0F00000, 0xF0F0000F, 0xF0F000F0, 0xF0F000FF, \
+ 0xF0F00F00, 0xF0F00F0F, 0xF0F00FF0, 0xF0F00FFF, \
+ 0xF0F0F000, 0xF0F0F00F, 0xF0F0F0F0, 0xF0F0F0FF, \
+ 0xF0F0FF00, 0xF0F0FF0F, 0xF0F0FFF0, 0xF0F0FFFF, \
+ 0xF0FF0000, 0xF0FF000F, 0xF0FF00F0, 0xF0FF00FF, \
+ 0xF0FF0F00, 0xF0FF0F0F, 0xF0FF0FF0, 0xF0FF0FFF, \
+ 0xF0FFF000, 0xF0FFF00F, 0xF0FFF0F0, 0xF0FFF0FF, \
+ 0xF0FFFF00, 0xF0FFFF0F, 0xF0FFFFF0, 0xF0FFFFFF, \
+ 0xFF000000, 0xFF00000F, 0xFF0000F0, 0xFF0000FF, \
+ 0xFF000F00, 0xFF000F0F, 0xFF000FF0, 0xFF000FFF, \
+ 0xFF00F000, 0xFF00F00F, 0xFF00F0F0, 0xFF00F0FF, \
+ 0xFF00FF00, 0xFF00FF0F, 0xFF00FFF0, 0xFF00FFFF, \
+ 0xFF0F0000, 0xFF0F000F, 0xFF0F00F0, 0xFF0F00FF, \
+ 0xFF0F0F00, 0xFF0F0F0F, 0xFF0F0FF0, 0xFF0F0FFF, \
+ 0xFF0FF000, 0xFF0FF00F, 0xFF0FF0F0, 0xFF0FF0FF, \
+ 0xFF0FFF00, 0xFF0FFF0F, 0xFF0FFFF0, 0xFF0FFFFF, \
+ 0xFFF00000, 0xFFF0000F, 0xFFF000F0, 0xFFF000FF, \
+ 0xFFF00F00, 0xFFF00F0F, 0xFFF00FF0, 0xFFF00FFF, \
+ 0xFFF0F000, 0xFFF0F00F, 0xFFF0F0F0, 0xFFF0F0FF, \
+ 0xFFF0FF00, 0xFFF0FF0F, 0xFFF0FFF0, 0xFFF0FFFF, \
+ 0xFFFF0000, 0xFFFF000F, 0xFFFF00F0, 0xFFFF00FF, \
+ 0xFFFF0F00, 0xFFFF0F0F, 0xFFFF0FF0, 0xFFFF0FFF, \
+ 0xFFFFF000, 0xFFFFF00F, 0xFFFFF0F0, 0xFFFFF0FF, \
+ 0xFFFFFF00, 0xFFFFFF0F, 0xFFFFFFF0, 0xFFFFFFFF, \
+}
+#else
+#define BIT_MULTIPLICATOR_1_TO_4 { \
+ 0x00000000, 0x0F000000, 0xF0000000, 0xFF000000, \
+ 0x000F0000, 0x0F0F0000, 0xF00F0000, 0xFF0F0000, \
+ 0x00F00000, 0x0FF00000, 0xF0F00000, 0xFFF00000, \
+ 0x00FF0000, 0x0FFF0000, 0xF0FF0000, 0xFFFF0000, \
+ 0x00000F00, 0x0F000F00, 0xF0000F00, 0xFF000F00, \
+ 0x000F0F00, 0x0F0F0F00, 0xF00F0F00, 0xFF0F0F00, \
+ 0x00F00F00, 0x0FF00F00, 0xF0F00F00, 0xFFF00F00, \
+ 0x00FF0F00, 0x0FFF0F00, 0xF0FF0F00, 0xFFFF0F00, \
+ 0x0000F000, 0x0F00F000, 0xF000F000, 0xFF00F000, \
+ 0x000FF000, 0x0F0FF000, 0xF00FF000, 0xFF0FF000, \
+ 0x00F0F000, 0x0FF0F000, 0xF0F0F000, 0xFFF0F000, \
+ 0x00FFF000, 0x0FFFF000, 0xF0FFF000, 0xFFFFF000, \
+ 0x0000FF00, 0x0F00FF00, 0xF000FF00, 0xFF00FF00, \
+ 0x000FFF00, 0x0F0FFF00, 0xF00FFF00, 0xFF0FFF00, \
+ 0x00F0FF00, 0x0FF0FF00, 0xF0F0FF00, 0xFFF0FF00, \
+ 0x00FFFF00, 0x0FFFFF00, 0xF0FFFF00, 0xFFFFFF00, \
+ 0x0000000F, 0x0F00000F, 0xF000000F, 0xFF00000F, \
+ 0x000F000F, 0x0F0F000F, 0xF00F000F, 0xFF0F000F, \
+ 0x00F0000F, 0x0FF0000F, 0xF0F0000F, 0xFFF0000F, \
+ 0x00FF000F, 0x0FFF000F, 0xF0FF000F, 0xFFFF000F, \
+ 0x00000F0F, 0x0F000F0F, 0xF0000F0F, 0xFF000F0F, \
+ 0x000F0F0F, 0x0F0F0F0F, 0xF00F0F0F, 0xFF0F0F0F, \
+ 0x00F00F0F, 0x0FF00F0F, 0xF0F00F0F, 0xFFF00F0F, \
+ 0x00FF0F0F, 0x0FFF0F0F, 0xF0FF0F0F, 0xFFFF0F0F, \
+ 0x0000F00F, 0x0F00F00F, 0xF000F00F, 0xFF00F00F, \
+ 0x000FF00F, 0x0F0FF00F, 0xF00FF00F, 0xFF0FF00F, \
+ 0x00F0F00F, 0x0FF0F00F, 0xF0F0F00F, 0xFFF0F00F, \
+ 0x00FFF00F, 0x0FFFF00F, 0xF0FFF00F, 0xFFFFF00F, \
+ 0x0000FF0F, 0x0F00FF0F, 0xF000FF0F, 0xFF00FF0F, \
+ 0x000FFF0F, 0x0F0FFF0F, 0xF00FFF0F, 0xFF0FFF0F, \
+ 0x00F0FF0F, 0x0FF0FF0F, 0xF0F0FF0F, 0xFFF0FF0F, \
+ 0x00FFFF0F, 0x0FFFFF0F, 0xF0FFFF0F, 0xFFFFFF0F, \
+ 0x000000F0, 0x0F0000F0, 0xF00000F0, 0xFF0000F0, \
+ 0x000F00F0, 0x0F0F00F0, 0xF00F00F0, 0xFF0F00F0, \
+ 0x00F000F0, 0x0FF000F0, 0xF0F000F0, 0xFFF000F0, \
+ 0x00FF00F0, 0x0FFF00F0, 0xF0FF00F0, 0xFFFF00F0, \
+ 0x00000FF0, 0x0F000FF0, 0xF0000FF0, 0xFF000FF0, \
+ 0x000F0FF0, 0x0F0F0FF0, 0xF00F0FF0, 0xFF0F0FF0, \
+ 0x00F00FF0, 0x0FF00FF0, 0xF0F00FF0, 0xFFF00FF0, \
+ 0x00FF0FF0, 0x0FFF0FF0, 0xF0FF0FF0, 0xFFFF0FF0, \
+ 0x0000F0F0, 0x0F00F0F0, 0xF000F0F0, 0xFF00F0F0, \
+ 0x000FF0F0, 0x0F0FF0F0, 0xF00FF0F0, 0xFF0FF0F0, \
+ 0x00F0F0F0, 0x0FF0F0F0, 0xF0F0F0F0, 0xFFF0F0F0, \
+ 0x00FFF0F0, 0x0FFFF0F0, 0xF0FFF0F0, 0xFFFFF0F0, \
+ 0x0000FFF0, 0x0F00FFF0, 0xF000FFF0, 0xFF00FFF0, \
+ 0x000FFFF0, 0x0F0FFFF0, 0xF00FFFF0, 0xFF0FFFF0, \
+ 0x00F0FFF0, 0x0FF0FFF0, 0xF0F0FFF0, 0xFFF0FFF0, \
+ 0x00FFFFF0, 0x0FFFFFF0, 0xF0FFFFF0, 0xFFFFFFF0, \
+ 0x000000FF, 0x0F0000FF, 0xF00000FF, 0xFF0000FF, \
+ 0x000F00FF, 0x0F0F00FF, 0xF00F00FF, 0xFF0F00FF, \
+ 0x00F000FF, 0x0FF000FF, 0xF0F000FF, 0xFFF000FF, \
+ 0x00FF00FF, 0x0FFF00FF, 0xF0FF00FF, 0xFFFF00FF, \
+ 0x00000FFF, 0x0F000FFF, 0xF0000FFF, 0xFF000FFF, \
+ 0x000F0FFF, 0x0F0F0FFF, 0xF00F0FFF, 0xFF0F0FFF, \
+ 0x00F00FFF, 0x0FF00FFF, 0xF0F00FFF, 0xFFF00FFF, \
+ 0x00FF0FFF, 0x0FFF0FFF, 0xF0FF0FFF, 0xFFFF0FFF, \
+ 0x0000F0FF, 0x0F00F0FF, 0xF000F0FF, 0xFF00F0FF, \
+ 0x000FF0FF, 0x0F0FF0FF, 0xF00FF0FF, 0xFF0FF0FF, \
+ 0x00F0F0FF, 0x0FF0F0FF, 0xF0F0F0FF, 0xFFF0F0FF, \
+ 0x00FFF0FF, 0x0FFFF0FF, 0xF0FFF0FF, 0xFFFFF0FF, \
+ 0x0000FFFF, 0x0F00FFFF, 0xF000FFFF, 0xFF00FFFF, \
+ 0x000FFFFF, 0x0F0FFFFF, 0xF00FFFFF, 0xFF0FFFFF, \
+ 0x00F0FFFF, 0x0FF0FFFF, 0xF0F0FFFF, 0xFFF0FFFF, \
+ 0x00FFFFFF, 0x0FFFFFFF, 0xF0FFFFFF, 0xFFFFFFFF, \
+}
+#endif
+
#endif /* _IPFW2_H */
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -1360,6 +1360,28 @@
return (tvalue == cmd->value);
}
+/*
+ * Apply 32-bit (1 bit per nibble) mask to an IPv6 address.
+ * Each bit in mask represents 4 bits in real IPv6 address mask.
+ * 0 = 0b0000, 1 = 0b1111 = 0xF
+ *
+ * mask is expected in HOST order
+ */
+
+static void
+apply_nibble_mask(struct in6_addr *dst, const struct in6_addr *src,
+ uint32_t mask)
+{
+ static const uint32_t bits_to_mask[] = BIT_MULTIPLICATOR_1_TO_4;
+ int i;
+
+ for (i = 3; i >= 0; i--) {
+ dst->__u6_addr.__u6_addr32[i] =
+ src->__u6_addr.__u6_addr32[i] & bits_to_mask[mask & 0xFF];
+ mask >>= 8;
+ }
+}
+
/*
* The main check routine for the firewall.
*
@@ -2096,6 +2118,7 @@
case O_IP_DST_LOOKUP:
if (IPFW_LOOKUP_TYPE(cmd) != LOOKUP_NONE) {
+ struct in6_addr in6_key;
void *pkey = NULL;
uint32_t key, vidx;
uint16_t keylen = 0; /* zero if can't match the packet */
@@ -2106,20 +2129,44 @@
switch (lookup_type) {
case LOOKUP_DST_IP:
case LOOKUP_SRC_IP:
+ /*
+ * Opcode formatted as
+ * ipfw_insn_table holds bitmask in
+ * value field to be applied prior
+ * to table lookup.
+ */
if (is_ipv4) {
keylen = sizeof(in_addr_t);
if (lookup_type == LOOKUP_DST_IP)
pkey = &dst_ip;
else
pkey = &src_ip;
- } else if (is_ipv6) {
+ if (cmdlen ==
+ F_INSN_SIZE(ipfw_insn_table)) {
+ key = *(uint32_t *)pkey &
+ htonl(insntod(cmd, table)->value);
+ pkey = &key;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ case LOOKUP_DST_IP6:
+ case LOOKUP_SRC_IP6:
+ if (is_ipv6) {
keylen = sizeof(struct in6_addr);
- if (lookup_type == LOOKUP_DST_IP)
+ if (lookup_type == LOOKUP_DST_IP ||
+ lookup_type == LOOKUP_DST_IP6)
pkey = &args->f_id.dst_ip6;
else
pkey = &args->f_id.src_ip6;
- } else /* only for L3 */
- break;
+ if (cmdlen ==
+ F_INSN_SIZE(ipfw_insn_table)) {
+ apply_nibble_mask(&in6_key, pkey,
+ insntod(cmd, table)->value);
+ pkey = &in6_key;
+ }
+ } /* only for L3 */
+ break;
case LOOKUP_DSCP:
if (is_ipv4)
key = ip->ip_tos >> 2;

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 15, 10:54 AM (12 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25324264
Default Alt Text
D53694.diff (19 KB)

Event Timeline