summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-12-13 12:16:03 +0000
committerglebius <glebius@FreeBSD.org>2005-12-13 12:16:03 +0000
commitd5ab5191cf5df5bcf63257124ddb49c77c2d7137 (patch)
tree6cd65aeebdffa5fddf4f8da962ba7f377ec1a186 /sbin/ipfw
parent97acc24830d83fc3b09a8cf246b54ccb44f0940e (diff)
downloadFreeBSD-src-d5ab5191cf5df5bcf63257124ddb49c77c2d7137.zip
FreeBSD-src-d5ab5191cf5df5bcf63257124ddb49c77c2d7137.tar.gz
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.
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw2.c90
1 files changed, 44 insertions, 46 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 28a8c98..13e1df3 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -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;
- case O_SKIPTO:
- printf("skipto %u", cmd->arg1);
+#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:
+ 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,36 @@ add(int ac, char *av[])
break;
case TOK_QUEUE:
+ action->opcode = O_QUEUE;
+ goto chkarg;
case TOK_PIPE:
- action->len = F_INSN_SIZE(ipfw_insn);
+ 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 +3897,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;
OpenPOWER on IntegriCloud