MFC:
Add a new feature for optimizining ipfw rulesets - substitution of the action argument with the value obtained from table lookup. The feature is now applicable only to "pipe", "queue", "divert", "tee", "netgraph" and "ngtee" rules.
This commit is contained in:
parent
9bfc349ebe
commit
470df2fb19
@ -1,7 +1,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 13, 2005
|
||||
.Dd January 16, 2006
|
||||
.Dt IPFW 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -1523,6 +1523,19 @@ the routing table (see
|
||||
.Xr route 4 ) .
|
||||
.Pp
|
||||
Lookup tables currently support IPv4 addresses only.
|
||||
.Pp
|
||||
The
|
||||
.Cm tablearg
|
||||
feature provides the ability to use a value, looked up in the table, as
|
||||
the argument for a rule action.
|
||||
This can significantly reduce number of rules in some configurations.
|
||||
The
|
||||
.Cm tablearg
|
||||
argument can be used with the following actions:
|
||||
.Cm pipe , queue, divert, tee, netgraph, ngtee .
|
||||
See the
|
||||
.Sx EXAMPLES
|
||||
Section for example usage of tables and the tablearg keyword.
|
||||
.Sh SETS OF RULES
|
||||
Each rule belongs to one of 32 different
|
||||
.Em sets
|
||||
@ -2425,6 +2438,23 @@ on a net with per-host limits, rather than per-network limits:
|
||||
.Dl "ipfw add pipe 2 ip from any to 192.168.2.0/24 in"
|
||||
.Dl "ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
|
||||
.Dl "ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes"
|
||||
.Ss LOOKUP TABLES
|
||||
In the following example, we need to create several traffic bandwidth
|
||||
classes and we need different hosts/networks to fall into different classes.
|
||||
We create one pipe for each class and configure them accordingly.
|
||||
Then we create a single table and fill it with IP subnets and addresses.
|
||||
For each subnet/host we set the argument equal to the number of the pipe
|
||||
that it should use.
|
||||
Then we classify traffic using a single rule:
|
||||
.Pp
|
||||
.Dl "ipfw pipe 1 config bw 1000Kbyte/s"
|
||||
.Dl "ipfw pipe 4 config bw 4000Kbyte/s"
|
||||
.Dl "..."
|
||||
.Dl "ipfw table 1 add 192.168.2.0/24 1"
|
||||
.Dl "ipfw table 1 add 192.168.0.0/27 4"
|
||||
.Dl "ipfw table 1 add 192.168.0.2 1"
|
||||
.Dl "..."
|
||||
.Dl "ipfw pipe tablearg ip from table(1) to any"
|
||||
.Ss SETS OF RULES
|
||||
To add a set of rules atomically, e.g.\& set 18:
|
||||
.Pp
|
||||
|
@ -420,6 +420,8 @@ struct _s_x rule_options[] = {
|
||||
{ NULL, 0 } /* terminator */
|
||||
};
|
||||
|
||||
#define TABLEARG "tablearg"
|
||||
|
||||
static __inline uint64_t
|
||||
align_uint64(uint64_t *pll) {
|
||||
uint64_t ret;
|
||||
@ -1457,33 +1459,28 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
print_unreach6_code(cmd->arg1);
|
||||
break;
|
||||
|
||||
#define PRINT_WITH_ARG(o) \
|
||||
if (cmd->arg1 == IP_FW_TABLEARG) \
|
||||
printf("%s tablearg", (o)); \
|
||||
else \
|
||||
printf("%s %u", (o), cmd->arg1); \
|
||||
break;
|
||||
|
||||
case O_SKIPTO:
|
||||
printf("skipto %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("skipto");
|
||||
case O_PIPE:
|
||||
printf("pipe %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("pipe");
|
||||
case O_QUEUE:
|
||||
printf("queue %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("queue");
|
||||
case O_DIVERT:
|
||||
printf("divert %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("divert");
|
||||
case O_TEE:
|
||||
printf("tee %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("tee");
|
||||
case O_NETGRAPH:
|
||||
printf("netgraph %u", cmd->arg1);
|
||||
break;
|
||||
|
||||
PRINT_WITH_ARG("netgraph");
|
||||
case O_NGTEE:
|
||||
printf("ngtee %u", cmd->arg1);
|
||||
break;
|
||||
PRINT_WITH_ARG("ngtee");
|
||||
#undef PRINT_WITH_ARG
|
||||
|
||||
case O_FORWARD_IP:
|
||||
{
|
||||
@ -3863,26 +3860,38 @@ add(int ac, char *av[])
|
||||
break;
|
||||
|
||||
case TOK_QUEUE:
|
||||
action->len = F_INSN_SIZE(ipfw_insn_pipe);
|
||||
action->opcode = O_QUEUE;
|
||||
goto chkarg;
|
||||
case TOK_PIPE:
|
||||
action->len = F_INSN_SIZE(ipfw_insn_pipe);
|
||||
action->opcode = O_PIPE;
|
||||
goto chkarg;
|
||||
case TOK_SKIPTO:
|
||||
if (i == TOK_QUEUE)
|
||||
action->opcode = O_QUEUE;
|
||||
else if (i == TOK_PIPE)
|
||||
action->opcode = O_PIPE;
|
||||
else if (i == TOK_SKIPTO)
|
||||
action->opcode = O_SKIPTO;
|
||||
NEED1("missing skipto/pipe/queue number");
|
||||
action->arg1 = strtoul(*av, NULL, 10);
|
||||
av++; ac--;
|
||||
break;
|
||||
|
||||
action->opcode = O_SKIPTO;
|
||||
goto chkarg;
|
||||
case TOK_NETGRAPH:
|
||||
action->opcode = O_NETGRAPH;
|
||||
goto chkarg;
|
||||
case TOK_NGTEE:
|
||||
action->opcode = O_NGTEE;
|
||||
goto chkarg;
|
||||
case TOK_DIVERT:
|
||||
action->opcode = O_DIVERT;
|
||||
goto chkarg;
|
||||
case TOK_TEE:
|
||||
action->opcode = (i == TOK_DIVERT) ? O_DIVERT : O_TEE;
|
||||
NEED1("missing divert/tee port");
|
||||
action->arg1 = strtoul(*av, NULL, 0);
|
||||
if (action->arg1 == 0) {
|
||||
action->opcode = O_TEE;
|
||||
chkarg:
|
||||
if (!ac)
|
||||
errx(EX_USAGE, "missing argument for %s", *(av - 1));
|
||||
if (isdigit(**av)) {
|
||||
action->arg1 = strtoul(*av, NULL, 10);
|
||||
if (action->arg1 <= 0 || action->arg1 >= IP_FW_TABLEARG)
|
||||
errx(EX_DATAERR, "illegal argument for %s",
|
||||
*(av - 1));
|
||||
} else if (_substrcmp(*av, TABLEARG) == 0) {
|
||||
action->arg1 = IP_FW_TABLEARG;
|
||||
} else if (i == TOK_DIVERT || i == TOK_TEE) {
|
||||
struct servent *s;
|
||||
setservent(1);
|
||||
s = getservbyname(av[0], "divert");
|
||||
@ -3890,17 +3899,8 @@ add(int ac, char *av[])
|
||||
action->arg1 = ntohs(s->s_port);
|
||||
else
|
||||
errx(EX_DATAERR, "illegal divert/tee port");
|
||||
}
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
case TOK_NETGRAPH:
|
||||
case TOK_NGTEE:
|
||||
action->opcode = (i == TOK_NETGRAPH ) ? O_NETGRAPH : O_NGTEE;
|
||||
NEED1("missing netgraph cookie");
|
||||
action->arg1 = strtoul(*av, NULL, 0);
|
||||
if (action->arg1 == 0)
|
||||
errx(EX_DATAERR, "illegal netgraph cookie");
|
||||
} else
|
||||
errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
|
||||
ac--; av++;
|
||||
break;
|
||||
|
||||
|
@ -474,6 +474,8 @@ typedef struct _ipfw_table {
|
||||
ipfw_table_entry ent[0]; /* entries */
|
||||
} ipfw_table;
|
||||
|
||||
#define IP_FW_TABLEARG 65535
|
||||
|
||||
/*
|
||||
* Main firewall chains definitions and global var's definitions.
|
||||
*/
|
||||
|
@ -2383,9 +2383,9 @@ do { \
|
||||
* Now scan the rules, and parse microinstructions for each rule.
|
||||
*/
|
||||
for (; f; f = f->next) {
|
||||
int l, cmdlen;
|
||||
ipfw_insn *cmd;
|
||||
int skip_or; /* skip rest of OR block */
|
||||
uint32_t tablearg = 0;
|
||||
int l, cmdlen, skip_or; /* skip rest of OR block */
|
||||
|
||||
again:
|
||||
if (set_disable & (1 << f->set) )
|
||||
@ -2548,6 +2548,8 @@ check_body:
|
||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
|
||||
match =
|
||||
((ipfw_insn_u32 *)cmd)->d[0] == v;
|
||||
else
|
||||
tablearg = v;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2999,7 +3001,10 @@ check_body:
|
||||
case O_PIPE:
|
||||
case O_QUEUE:
|
||||
args->rule = f; /* report matching rule */
|
||||
args->cookie = cmd->arg1;
|
||||
if (cmd->arg1 == IP_FW_TABLEARG)
|
||||
args->cookie = tablearg;
|
||||
else
|
||||
args->cookie = cmd->arg1;
|
||||
retval = IP_FW_DUMMYNET;
|
||||
goto done;
|
||||
|
||||
@ -3020,7 +3025,10 @@ check_body:
|
||||
}
|
||||
dt = (struct divert_tag *)(mtag+1);
|
||||
dt->cookie = f->rulenum;
|
||||
dt->info = cmd->arg1;
|
||||
if (cmd->arg1 == IP_FW_TABLEARG)
|
||||
dt->info = tablearg;
|
||||
else
|
||||
dt->info = cmd->arg1;
|
||||
m_tag_prepend(m, mtag);
|
||||
retval = (cmd->opcode == O_DIVERT) ?
|
||||
IP_FW_DIVERT : IP_FW_TEE;
|
||||
@ -3085,7 +3093,10 @@ check_body:
|
||||
case O_NETGRAPH:
|
||||
case O_NGTEE:
|
||||
args->rule = f; /* report matching rule */
|
||||
args->cookie = cmd->arg1;
|
||||
if (cmd->arg1 == IP_FW_TABLEARG)
|
||||
args->cookie = tablearg;
|
||||
else
|
||||
args->cookie = cmd->arg1;
|
||||
retval = (cmd->opcode == O_NETGRAPH) ?
|
||||
IP_FW_NETGRAPH : IP_FW_NGTEE;
|
||||
goto done;
|
||||
|
Loading…
x
Reference in New Issue
Block a user