* Switch tablearg value from 65535 to 0.

* Use u16 table kidx instead of integer on for iface opcode.
* Provide compability layer for old clients.
This commit is contained in:
Alexander V. Chernikov 2014-08-08 14:23:20 +00:00
parent adf3b2b9d8
commit 2c452b20dd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/ipfw/; revision=269716
7 changed files with 133 additions and 21 deletions

View File

@ -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);
@ -1843,7 +1843,7 @@ show_static_rule(struct cmdline_opts *co, struct format_opts *fo,
else if (cmdif->name[0] == '\1') {
/* interface table */
t = table_search_ctlv(fo->tstate,
cmdif->p.glob);
cmdif->p.kidx);
printf(" %s table(%s)", s, t);
} else
printf(" %s %s", s, cmdif->name);
@ -3092,7 +3092,7 @@ fill_iface(ipfw_insn_if *cmd, char *arg, int cblen, struct tidx *tstate)
errx(EX_DATAERR, "Invalid table name: %s", arg + 6);
cmd->name[0] = '\1'; /* Special value indicating table */
cmd->p.glob = uidx;
cmd->p.kidx = uidx;
} else if (!isdigit(*arg)) {
strlcpy(cmd->name, arg, sizeof(cmd->name));
cmd->p.glob = strpbrk(arg, "*?[") != NULL ? 1 : 0;
@ -3596,11 +3596,11 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
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);
@ -3724,7 +3724,7 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
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,
@ -3744,7 +3744,7 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
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");

View File

@ -49,7 +49,7 @@
* Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit
* argument between 1 and 65534. The value 0 is unused, the value
* 65535 (IP_FW_TABLEARG) is used to represent 'tablearg', i.e. the
* can be 1..65534, or 65535 to indicate the use of a 'tablearg'
* can be 1..65534, or 0 to indicate the use of a 'tablearg'
* result of the most recent table() lookup.
* Note that 16bit is only a historical limit, resulting from
* the use of a 16-bit fields for that value. In reality, we can have
@ -57,7 +57,8 @@
*/
#define IPFW_ARG_MIN 1
#define IPFW_ARG_MAX 65534
#define IP_FW_TABLEARG 65535 /* XXX should use 0 */
#define IP_FW_TABLEARG 65535 /* Compat value for old clients */
#define IP_FW_TARG 0 /* Current tablearg value */
/*
* Number of entries in the call stack of the call/return commands.
@ -391,6 +392,7 @@ typedef struct _ipfw_insn_if {
union {
struct in_addr ip;
int glob;
uint16_t kidx;
} p;
char name[IFNAMSIZ];
} ipfw_insn_if;

View File

@ -368,7 +368,7 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain,
/* Check by name or by IP address */
if (cmd->name[0] != '\0') { /* match by name */
if (cmd->name[0] == '\1') /* use tablearg to match */
return ipfw_lookup_table_extended(chain, cmd->p.glob, 0,
return ipfw_lookup_table_extended(chain, cmd->p.kidx, 0,
&ifp->if_index, tablearg);
/* Check name */
if (cmd->p.glob) {
@ -810,7 +810,7 @@ jump_fast(struct ip_fw_chain *chain, struct ip_fw *f, int num,
* whose version is written in f->next_rule
* (horrible hacks to avoid changing the ABI).
*/
if (num != IP_FW_TABLEARG && (uintptr_t)f->x_next == chain->id)
if (num != IP_FW_TARG && (uintptr_t)f->x_next == chain->id)
f_pos = (uintptr_t)f->next_rule;
else {
int i = IP_FW_ARG_TABLEARG(num);
@ -822,7 +822,7 @@ jump_fast(struct ip_fw_chain *chain, struct ip_fw *f, int num,
else
f_pos = ipfw_find_rule(chain, i, 0);
/* update the cache */
if (num != IP_FW_TABLEARG) {
if (num != IP_FW_TARG) {
f->next_rule = (void *)(uintptr_t)f_pos;
f->x_next = (void *)(uintptr_t)chain->id;
}
@ -2461,7 +2461,7 @@ do { \
retval = IP_FW_DENY;
break;
}
if (cmd->arg1 != IP_FW_TABLEARG)
if (cmd->arg1 != IP_FW_TARG)
((ipfw_insn_nat *)cmd)->nat = t;
}
retval = ipfw_nat_ptr(args, t, m);

View File

@ -719,7 +719,7 @@ ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
conn_limit = IP_FW_ARG_TABLEARG(cmd->conn_limit);
DEB(
if (cmd->conn_limit == IP_FW_TABLEARG)
if (cmd->conn_limit == IP_FW_TARG)
printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
"(tablearg)\n", __func__, conn_limit);
else

View File

@ -384,7 +384,7 @@ struct ipfw_ifc {
#endif
#define IP_FW_ARG_TABLEARG(a) (((a) == IP_FW_TABLEARG) ? tablearg : (a))
#define IP_FW_ARG_TABLEARG(a) (((a) == IP_FW_TARG) ? tablearg : (a))
/*
* The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
* so the variable and the macros must be here.

View File

@ -375,7 +375,7 @@ export_cntr0_base(struct ip_fw *krule, struct ip_fw_bcounter0 *cntr)
}
/*
* Copies rule @urule from v1 userland format
* Copies rule @urule from v1 userland format (current).
* to kernel @krule.
* Assume @krule is zeroed.
*/
@ -454,6 +454,10 @@ import_rule0(struct rule_check_info *ci)
{
struct ip_fw_rule0 *urule;
struct ip_fw *krule;
int cmdlen, l;
ipfw_insn *cmd;
ipfw_insn_limit *lcmd;
ipfw_insn_if *cmdif;
urule = (struct ip_fw_rule0 *)ci->urule;
krule = (struct ip_fw *)ci->krule;
@ -471,11 +475,68 @@ import_rule0(struct rule_check_info *ci)
/* Copy opcodes */
memcpy(krule->cmd, urule->cmd, krule->cmd_len * sizeof(uint32_t));
/*
* Alter opcodes:
* 1) convert tablearg value from 65335 to 0
* 2) convert table number in iface opcodes to u16
*/
l = krule->cmd_len;
cmd = krule->cmd;
cmdlen = 0;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
switch (cmd->opcode) {
/* Opcodes supporting tablearg */
case O_TAG:
case O_TAGGED:
case O_PIPE:
case O_QUEUE:
case O_DIVERT:
case O_TEE:
case O_SKIPTO:
case O_CALLRETURN:
case O_NETGRAPH:
case O_NGTEE:
case O_SETFIB:
case O_SETDSCP:
case O_NAT:
if (cmd->arg1 == 65535)
cmd->arg1 = IP_FW_TARG;
break;
case O_LIMIT:
lcmd = (ipfw_insn_limit *)cmd;
if (lcmd->conn_limit == 65535)
lcmd->conn_limit = IP_FW_TARG;
break;
/* Interface tables */
case O_XMIT:
case O_RECV:
case O_VIA:
/* Interface table, possibly */
cmdif = (ipfw_insn_if *)cmd;
if (cmdif->name[0] != '\1')
break;
cmdif->p.kidx = (uint16_t)cmdif->p.glob;
break;
}
}
}
/*
* Copies rule @krule from kernel to FreeBSD8 userland format (v0)
*/
static void
export_rule0(struct ip_fw *krule, struct ip_fw_rule0 *urule, int len)
{
int cmdlen, l;
ipfw_insn *cmd;
ipfw_insn_limit *lcmd;
ipfw_insn_if *cmdif;
/* copy header */
memset(urule, 0, len);
urule->act_ofs = krule->act_ofs;
@ -490,6 +551,55 @@ export_rule0(struct ip_fw *krule, struct ip_fw_rule0 *urule, int len)
/* Export counters */
export_cntr0_base(krule, (struct ip_fw_bcounter0 *)&urule->pcnt);
/*
* Alter opcodes:
* 1) convert tablearg value from 0 to 65335
* 2) convert table number in iface opcodes to int
*/
l = urule->cmd_len;
cmd = urule->cmd;
cmdlen = 0;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
switch (cmd->opcode) {
/* Opcodes supporting tablearg */
case O_TAG:
case O_TAGGED:
case O_PIPE:
case O_QUEUE:
case O_DIVERT:
case O_TEE:
case O_SKIPTO:
case O_CALLRETURN:
case O_NETGRAPH:
case O_NGTEE:
case O_SETFIB:
case O_SETDSCP:
case O_NAT:
if (cmd->arg1 == IP_FW_TARG)
cmd->arg1 = 65535;
break;
case O_LIMIT:
lcmd = (ipfw_insn_limit *)cmd;
if (lcmd->conn_limit == IP_FW_TARG)
lcmd->conn_limit = 65535;
break;
/* Interface tables */
case O_XMIT:
case O_RECV:
case O_VIA:
/* Interface table, possibly */
cmdif = (ipfw_insn_if *)cmd;
if (cmdif->name[0] != '\1')
break;
cmdif->p.glob = cmdif->p.kidx;
break;
}
}
}
/*

View File

@ -2047,7 +2047,7 @@ classify_table_opcode(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype)
break;
*ptype = IPFW_TABLE_INTERFACE;
*puidx = cmdif->p.glob;
*puidx = cmdif->p.kidx;
skip = 0;
break;
case O_IP_FLOW_LOOKUP:
@ -2080,7 +2080,7 @@ update_table_opcode(ipfw_insn *cmd, uint16_t idx)
case O_VIA:
/* Interface table, possibly */
cmdif = (ipfw_insn_if *)cmd;
cmdif->p.glob = idx;
cmdif->p.kidx = idx;
break;
case O_IP_FLOW_LOOKUP:
cmd->arg1 = idx;