summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2009-12-15 09:46:27 +0000
committerluigi <luigi@FreeBSD.org>2009-12-15 09:46:27 +0000
commit84d17b9dde0bca3ba11491efd293d666259c204f (patch)
tree6801a26cde90c352ef557ec26fb56589ca42c654 /sbin
parent507718c519a5c35f2ef041763a9715b79c33b177 (diff)
downloadFreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.zip
FreeBSD-src-84d17b9dde0bca3ba11491efd293d666259c204f.tar.gz
implement a new match option,
lookup {dst-ip|src-ip|dst-port|src-port|uid|jail} N which searches the specified field in table N and sets tablearg accordingly. With dst-ip or src-ip the option replicates two existing options. When used with other arguments, the option can be useful to quickly dispatch traffic based on other fields. Work supported by the Onelab project. MFC after: 1 week
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw.814
-rw-r--r--sbin/ipfw/ipfw2.c45
-rw-r--r--sbin/ipfw/ipfw2.h1
3 files changed, 60 insertions, 0 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 1483dd0..fc83ecc 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1391,6 +1391,20 @@ of source and destination addresses and ports can be
specified.
Currently,
only IPv4 flows are supported.
+.It Cm lookup Bro Cm dst-ip | dst-port | src-ip | src-port | uid | jail Brc Ar N
+Search an entry in lookup table
+.Ar N
+that matches the field specified as argument.
+If not found, the match fails.
+Otherwise, the match succeeds and
+.Cm tablearg
+is set to the value extracted from the table.
+.Br
+This option can be useful to quickly dispatch traffic based on
+certain packet fields.
+See the
+.Sx LOOKUP TABLES
+section below for more information on lookup tables.
.It Cm { MAC | mac } Ar dst-mac src-mac
Match packets with a given
.Ar dst-mac
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 7edfbd5..d4740c9 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -224,6 +224,15 @@ static struct _s_x rule_action_params[] = {
{ NULL, 0 } /* terminator */
};
+/*
+ * The 'lookup' instruction accepts one of the following arguments.
+ * -1 is a terminator for the list.
+ * Arguments are passed as v[1] in O_DST_LOOKUP options.
+ */
+static int lookup_key[] = {
+ TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT,
+ TOK_UID, TOK_JAIL, -1 };
+
static struct _s_x rule_options[] = {
{ "tagged", TOK_TAGGED },
{ "uid", TOK_UID },
@@ -290,6 +299,7 @@ static struct _s_x rule_options[] = {
{ "dst-ip6", TOK_DSTIP6},
{ "src-ipv6", TOK_SRCIP6},
{ "src-ip6", TOK_SRCIP6},
+ { "lookup", TOK_LOOKUP},
{ "//", TOK_COMMENT },
{ "not", TOK_NOT }, /* pseudo option */
@@ -742,6 +752,16 @@ print_ip(ipfw_insn_ip *cmd, char const *s)
int len = F_LEN((ipfw_insn *)cmd);
uint32_t *a = ((ipfw_insn_u32 *)cmd)->d;
+ if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) {
+ uint32_t d = a[1];
+ const char *arg = "<invalid>";
+
+ if (d < sizeof(lookup_key)/sizeof(lookup_key[0]))
+ arg = match_value(rule_options, lookup_key[d]);
+ printf("%s lookup %s %d", cmd->o.len & F_NOT ? " not": "",
+ arg, cmd->o.arg1);
+ return;
+ }
printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s);
if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) {
@@ -3479,6 +3499,31 @@ read_options:
ac--; av++;
break;
+ case TOK_LOOKUP: {
+ ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd;
+ char *p;
+ int j;
+
+ if (ac < 2)
+ errx(EX_USAGE, "format: lookup argument tablenum");
+ cmd->opcode = O_IP_DST_LOOKUP;
+ cmd->len |= F_INSN_SIZE(ipfw_insn) + 2;
+ i = match_token(rule_options, *av);
+ for (j = 0; lookup_key[j] >= 0 ; j++) {
+ if (i == lookup_key[j])
+ break;
+ }
+ if (lookup_key[j] <= 0)
+ errx(EX_USAGE, "format: cannot lookup on %s", *av);
+ c->d[1] = j; // i converted to option
+ ac--; av++;
+ cmd->arg1 = strtoul(*av, &p, 0);
+ if (p && *p)
+ errx(EX_USAGE, "format: lookup argument tablenum");
+ ac--; av++;
+ }
+ break;
+
default:
errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s);
}
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index d3ce7fb..b393a7d 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -186,6 +186,7 @@ enum tokens {
TOK_FIB,
TOK_SETFIB,
+ TOK_LOOKUP,
};
/*
* the following macro returns an error message if we run out of
OpenPOWER on IntegriCloud