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. An example usage: ipfw pipe 1000 config bw 1000Kbyte/s ipfw pipe 4000 config bw 4000Kbyte/s ipfw table 1 add x.x.x.x 1000 ipfw table 1 add x.x.x.y 4000 ipfw pipe tablearg ip from table(1) to any In the example above the rule will throw different packets to different pipes. TODO: - Support "skipto" action, but without searching all rules. - Improve parser, so that it warns about bad rules. These are: - "tablearg" argument to action, but no "table" in the rule. All traffic will be blocked. - "tablearg" argument to action, but "table" searches for entry with a specific value. All traffic will be blocked. - "tablearg" argument to action, and two "table" looks - for src and for dst. The last lookup will match.
This commit is contained in:
parent
2778b70e71
commit
40b1ae9e00
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153374
@ -420,6 +420,8 @@ struct _s_x rule_options[] = {
|
|||||||
{ NULL, 0 } /* terminator */
|
{ NULL, 0 } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TABLEARG "tablearg"
|
||||||
|
|
||||||
static __inline uint64_t
|
static __inline uint64_t
|
||||||
align_uint64(uint64_t *pll) {
|
align_uint64(uint64_t *pll) {
|
||||||
uint64_t ret;
|
uint64_t ret;
|
||||||
@ -1457,33 +1459,28 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
|||||||
print_unreach6_code(cmd->arg1);
|
print_unreach6_code(cmd->arg1);
|
||||||
break;
|
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:
|
case O_SKIPTO:
|
||||||
printf("skipto %u", cmd->arg1);
|
PRINT_WITH_ARG("skipto");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_PIPE:
|
case O_PIPE:
|
||||||
printf("pipe %u", cmd->arg1);
|
PRINT_WITH_ARG("pipe");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_QUEUE:
|
case O_QUEUE:
|
||||||
printf("queue %u", cmd->arg1);
|
PRINT_WITH_ARG("queue");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_DIVERT:
|
case O_DIVERT:
|
||||||
printf("divert %u", cmd->arg1);
|
PRINT_WITH_ARG("divert");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_TEE:
|
case O_TEE:
|
||||||
printf("tee %u", cmd->arg1);
|
PRINT_WITH_ARG("tee");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_NETGRAPH:
|
case O_NETGRAPH:
|
||||||
printf("netgraph %u", cmd->arg1);
|
PRINT_WITH_ARG("netgraph");
|
||||||
break;
|
|
||||||
|
|
||||||
case O_NGTEE:
|
case O_NGTEE:
|
||||||
printf("ngtee %u", cmd->arg1);
|
PRINT_WITH_ARG("ngtee");
|
||||||
break;
|
#undef PRINT_WITH_ARG
|
||||||
|
|
||||||
case O_FORWARD_IP:
|
case O_FORWARD_IP:
|
||||||
{
|
{
|
||||||
@ -3863,26 +3860,36 @@ add(int ac, char *av[])
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_QUEUE:
|
case TOK_QUEUE:
|
||||||
|
action->opcode = O_QUEUE;
|
||||||
|
goto chkarg;
|
||||||
case TOK_PIPE:
|
case TOK_PIPE:
|
||||||
action->len = F_INSN_SIZE(ipfw_insn);
|
action->opcode = O_PIPE;
|
||||||
|
goto chkarg;
|
||||||
case TOK_SKIPTO:
|
case TOK_SKIPTO:
|
||||||
if (i == TOK_QUEUE)
|
action->opcode = O_SKIPTO;
|
||||||
action->opcode = O_QUEUE;
|
goto chkarg;
|
||||||
else if (i == TOK_PIPE)
|
case TOK_NETGRAPH:
|
||||||
action->opcode = O_PIPE;
|
action->opcode = O_NETGRAPH;
|
||||||
else if (i == TOK_SKIPTO)
|
goto chkarg;
|
||||||
action->opcode = O_SKIPTO;
|
case TOK_NGTEE:
|
||||||
NEED1("missing skipto/pipe/queue number");
|
action->opcode = O_NGTEE;
|
||||||
action->arg1 = strtoul(*av, NULL, 10);
|
goto chkarg;
|
||||||
av++; ac--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOK_DIVERT:
|
case TOK_DIVERT:
|
||||||
|
action->opcode = O_DIVERT;
|
||||||
|
goto chkarg;
|
||||||
case TOK_TEE:
|
case TOK_TEE:
|
||||||
action->opcode = (i == TOK_DIVERT) ? O_DIVERT : O_TEE;
|
action->opcode = O_TEE;
|
||||||
NEED1("missing divert/tee port");
|
chkarg:
|
||||||
action->arg1 = strtoul(*av, NULL, 0);
|
if (!ac)
|
||||||
if (action->arg1 == 0) {
|
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;
|
struct servent *s;
|
||||||
setservent(1);
|
setservent(1);
|
||||||
s = getservbyname(av[0], "divert");
|
s = getservbyname(av[0], "divert");
|
||||||
@ -3890,17 +3897,8 @@ add(int ac, char *av[])
|
|||||||
action->arg1 = ntohs(s->s_port);
|
action->arg1 = ntohs(s->s_port);
|
||||||
else
|
else
|
||||||
errx(EX_DATAERR, "illegal divert/tee port");
|
errx(EX_DATAERR, "illegal divert/tee port");
|
||||||
}
|
} else
|
||||||
ac--; av++;
|
errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
|
||||||
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");
|
|
||||||
ac--; av++;
|
ac--; av++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -461,6 +461,8 @@ typedef struct _ipfw_table {
|
|||||||
ipfw_table_entry ent[0]; /* entries */
|
ipfw_table_entry ent[0]; /* entries */
|
||||||
} ipfw_table;
|
} ipfw_table;
|
||||||
|
|
||||||
|
#define IP_FW_TABLEARG 65535
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main firewall chains definitions and global var's definitions.
|
* Main firewall chains definitions and global var's definitions.
|
||||||
*/
|
*/
|
||||||
|
@ -2383,9 +2383,9 @@ do { \
|
|||||||
* Now scan the rules, and parse microinstructions for each rule.
|
* Now scan the rules, and parse microinstructions for each rule.
|
||||||
*/
|
*/
|
||||||
for (; f; f = f->next) {
|
for (; f; f = f->next) {
|
||||||
int l, cmdlen;
|
|
||||||
ipfw_insn *cmd;
|
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:
|
again:
|
||||||
if (set_disable & (1 << f->set) )
|
if (set_disable & (1 << f->set) )
|
||||||
@ -2548,6 +2548,8 @@ do { \
|
|||||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
|
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
|
||||||
match =
|
match =
|
||||||
((ipfw_insn_u32 *)cmd)->d[0] == v;
|
((ipfw_insn_u32 *)cmd)->d[0] == v;
|
||||||
|
else
|
||||||
|
tablearg = v;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2999,7 +3001,10 @@ do { \
|
|||||||
case O_PIPE:
|
case O_PIPE:
|
||||||
case O_QUEUE:
|
case O_QUEUE:
|
||||||
args->rule = f; /* report matching rule */
|
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;
|
retval = IP_FW_DUMMYNET;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@ -3020,7 +3025,10 @@ do { \
|
|||||||
}
|
}
|
||||||
dt = (struct divert_tag *)(mtag+1);
|
dt = (struct divert_tag *)(mtag+1);
|
||||||
dt->cookie = f->rulenum;
|
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);
|
m_tag_prepend(m, mtag);
|
||||||
retval = (cmd->opcode == O_DIVERT) ?
|
retval = (cmd->opcode == O_DIVERT) ?
|
||||||
IP_FW_DIVERT : IP_FW_TEE;
|
IP_FW_DIVERT : IP_FW_TEE;
|
||||||
@ -3085,7 +3093,10 @@ do { \
|
|||||||
case O_NETGRAPH:
|
case O_NETGRAPH:
|
||||||
case O_NGTEE:
|
case O_NGTEE:
|
||||||
args->rule = f; /* report matching rule */
|
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) ?
|
retval = (cmd->opcode == O_NETGRAPH) ?
|
||||||
IP_FW_NETGRAPH : IP_FW_NGTEE;
|
IP_FW_NETGRAPH : IP_FW_NGTEE;
|
||||||
goto done;
|
goto done;
|
||||||
|
Loading…
Reference in New Issue
Block a user