summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-08-12 15:51:48 +0000
committermelifaro <melifaro@FreeBSD.org>2014-08-12 15:51:48 +0000
commit20eb17aed6d26d7d3c707c19a003ded76903f2dd (patch)
treea8fa20927c28cd192b16b34d205f195ff47c0df4 /sbin/ipfw
parentac4e64f311e12711c03067871b5030c7051e40b6 (diff)
downloadFreeBSD-src-20eb17aed6d26d7d3c707c19a003ded76903f2dd.zip
FreeBSD-src-20eb17aed6d26d7d3c707c19a003ded76903f2dd.tar.gz
Change tablearg value to be 0 (try #2).
Most of the tablearg-supported opcodes does not accept 0 as valid value: O_TAG, O_TAGGED, O_PIPE, O_QUEUE, O_DIVERT, O_TEE, O_SKIPTO, O_CALLRET, O_NETGRAPH, O_NGTEE, O_NAT treats 0 as invalid input. The rest are O_SETDSCP and O_SETFIB. 'Fix' them by adding high-order bit (0x8000) set for non-tablearg values. Do translation in kernel for old clients (import_rule0 / export_rule0), teach current ipfw(8) binary to add/remove given bit. This change does not affect handling SETDSCP values, but limit O_SETFIB values to 32767 instead of 65k. Since currently we have either old (16) or new (2^32) max fibs, this should not be a big deal: we're definitely OK for former and have to add another opcode to deal with latter, regardless of tablearg value.
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw2.c33
-rw-r--r--sbin/ipfw/ipfw2.h1
2 files changed, 23 insertions, 11 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index d90ac1a..5406583 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -93,7 +93,7 @@ int ipfw_socket = -1;
if (!av[0]) \
errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \
if (_substrcmp(*av, "tablearg") == 0) { \
- arg = IP_FW_TABLEARG; \
+ arg = IP_FW_TARG; \
break; \
} \
\
@@ -111,7 +111,7 @@ int ipfw_socket = -1;
errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", \
match_value(s_x, tok), min, max, *av); \
\
- if (_xval == IP_FW_TABLEARG) \
+ if (_xval == IP_FW_TARG) \
errx(EX_DATAERR, "%s: illegal argument value: %s", \
match_value(s_x, tok), *av); \
arg = _xval; \
@@ -123,7 +123,7 @@ PRINT_UINT_ARG(const char *str, uint32_t arg)
{
if (str != NULL)
printf("%s",str);
- if (arg == IP_FW_TABLEARG)
+ if (arg == IP_FW_TARG)
printf("tablearg");
else
printf("%u", arg);
@@ -469,7 +469,7 @@ bprint_uint_arg(struct buf_pr *bp, const char *str, uint32_t arg)
if (str != NULL)
bprintf(bp, "%s", str);
- if (arg == IP_FW_TABLEARG)
+ if (arg == IP_FW_TARG)
bprintf(bp, "tablearg");
else
bprintf(bp, "%u", arg);
@@ -1386,6 +1386,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
ipfw_insn_log *logptr = NULL; /* set if we find an O_LOG */
ipfw_insn_altq *altqptr = NULL; /* set if we find an O_ALTQ */
int or_block = 0; /* we are in an or block */
+ uint32_t uval;
if ((fo->set_mask & (1 << rule->set)) == 0) {
/* disabled mask */
@@ -1556,17 +1557,22 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
break;
case O_SETFIB:
- bprint_uint_arg(bp, "setfib ", cmd->arg1);
+ bprint_uint_arg(bp, "setfib ", cmd->arg1 & 0x7FFF);
break;
case O_SETDSCP:
{
const char *code;
- if ((code = match_value(f_ipdscp, cmd->arg1)) != NULL)
+ if (cmd->arg1 == IP_FW_TARG) {
+ bprint_uint_arg(bp, "setdscp ", cmd->arg1);
+ break;
+ }
+ uval = cmd->arg1 & 0x3F;
+ if ((code = match_value(f_ipdscp, uval)) != NULL)
bprintf(bp, "setdscp %s", code);
else
- bprint_uint_arg(bp, "setdscp ", cmd->arg1);
+ bprint_uint_arg(bp, "setdscp ", uval);
}
break;
@@ -3597,11 +3603,11 @@ chkarg:
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)
+ if (action->arg1 <= 0 || action->arg1 >= IP_FW_TARG)
errx(EX_DATAERR, "illegal argument for %s",
*(av - 1));
} else if (_substrcmp(*av, "tablearg") == 0) {
- action->arg1 = IP_FW_TABLEARG;
+ action->arg1 = IP_FW_TARG;
} else if (i == TOK_DIVERT || i == TOK_TEE) {
struct servent *s;
setservent(1);
@@ -3725,7 +3731,7 @@ chkarg:
action->opcode = O_SETFIB;
NEED1("missing fib number");
if (_substrcmp(*av, "tablearg") == 0) {
- action->arg1 = IP_FW_TABLEARG;
+ action->arg1 = IP_FW_TARG;
} else {
action->arg1 = strtoul(*av, NULL, 10);
if (sysctlbyname("net.fibs", &numfibs, &intsize,
@@ -3733,6 +3739,8 @@ chkarg:
errx(EX_DATAERR, "fibs not suported.\n");
if (action->arg1 >= numfibs) /* Temporary */
errx(EX_DATAERR, "fib too large.\n");
+ /* Add high-order bit to fib to make room for tablearg*/
+ action->arg1 |= 0x8000;
}
av++;
break;
@@ -3745,13 +3753,16 @@ chkarg:
action->opcode = O_SETDSCP;
NEED1("missing DSCP code");
if (_substrcmp(*av, "tablearg") == 0) {
- action->arg1 = IP_FW_TABLEARG;
+ action->arg1 = IP_FW_TARG;
} else if (isalpha(*av[0])) {
if ((code = match_token(f_ipdscp, *av)) == -1)
errx(EX_DATAERR, "Unknown DSCP code");
action->arg1 = code;
} else
action->arg1 = strtoul(*av, NULL, 10);
+ /* Add high-order bit to DSCP to make room for tablearg */
+ if (action->arg1 != IP_FW_TARG)
+ action->arg1 |= 0x8000;
av++;
break;
}
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index d15df7e..05e234d 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -228,6 +228,7 @@ enum tokens {
TOK_LOCK,
TOK_UNLOCK,
};
+
/*
* the following macro returns an error message if we run out of
* arguments.
OpenPOWER on IntegriCloud