Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135946553
D53694.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D53694.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D53694: [ipfw] Add support for masked ip-address lookups
Attached
Detach File
Event Timeline
Log In to Comment