summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorluigi <luigi@FreeBSD.org>2002-11-26 19:58:12 +0000
committerluigi <luigi@FreeBSD.org>2002-11-26 19:58:12 +0000
commite7e1590ec6bd185936901503ca73cd07cd2740e8 (patch)
treec1c8d60637c33608ad2ff260ba7a7c3bfc4cea0a /sbin
parentd3e60132e272506103a159ad8ce1948e3c1b7426 (diff)
downloadFreeBSD-src-e7e1590ec6bd185936901503ca73cd07cd2740e8.zip
FreeBSD-src-e7e1590ec6bd185936901503ca73cd07cd2740e8.tar.gz
Fix a kernel panic with rules of the type
prob 0.5 pipe NN .... due to the generation of an invalid ipfw instruction sequence. No ABI change, but you need to upgrade /sbin/ipfw to generate the correct code. Approved by: re
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw2.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 0dbc1a4..145f226 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -841,6 +841,20 @@ show_ipfw(struct ip_fw *rule)
printf("set %d ", rule->set);
/*
+ * print the optional "match probability"
+ */
+ if (rule->cmd_len > 0) {
+ cmd = rule->cmd ;
+ if (cmd->opcode == O_PROB) {
+ ipfw_insn_u32 *p = (ipfw_insn_u32 *)cmd;
+ double d = 1.0 * p->d[0];
+
+ d = (d / 0x7fffffff);
+ printf("prob %f ", d);
+ }
+ }
+
+ /*
* first print actions
*/
for (l = rule->cmd_len - rule->act_ofs, cmd = ACTION_PTR(rule);
@@ -851,16 +865,6 @@ show_ipfw(struct ip_fw *rule)
flags = HAVE_IP; /* avoid printing anything else */
break;
- case O_PROB:
- {
- ipfw_insn_u32 *p = (ipfw_insn_u32 *)cmd;
- double d = 1.0 * p->d[0];
-
- d = 1 - (d / 0x7fffffff);
- printf("prob %f ", d);
- }
- break;
-
case O_ACCEPT:
printf("allow");
break;
@@ -945,6 +949,9 @@ show_ipfw(struct ip_fw *rule)
show_prerequisites(&flags, 0, cmd->opcode);
switch(cmd->opcode) {
+ case O_PROB:
+ break; /* done already */
+
case O_PROBE_STATE:
break; /* no need to print anything here */
@@ -2453,6 +2460,8 @@ add(int ac, char *av[])
/* proto is here because it is used to fetch ports */
u_char proto = IPPROTO_IP; /* default protocol */
+ double match_prob = 1; /* match probability, default is always match */
+
bzero(actbuf, sizeof(actbuf)); /* actions go here */
bzero(cmdbuf, sizeof(cmdbuf));
bzero(rulebuf, sizeof(rulebuf));
@@ -2481,17 +2490,10 @@ add(int ac, char *av[])
/* [prob D] -- match probability, optional */
if (ac > 1 && !strncmp(*av, "prob", strlen(*av))) {
- double d = strtod(av[1], NULL);
+ match_prob = strtod(av[1], NULL);
- if (d <= 0 || d > 1)
+ if (match_prob <= 0 || match_prob > 1)
errx(EX_DATAERR, "illegal match prob. %s", av[1]);
- if (d != 1) { /* 1 means always match */
- action->opcode = O_PROB;
- action->len = 2;
- *((int32_t *)(action+1)) =
- (int32_t)((1 - d) * 0x7fffffff);
- action += action->len;
- }
av += 2; ac -= 2;
}
@@ -3119,6 +3121,16 @@ done:
dst = (ipfw_insn *)rule->cmd;
/*
+ * First thing to write into the command stream is the match probability.
+ */
+ if (match_prob != 1) { /* 1 means always match */
+ dst->opcode = O_PROB;
+ dst->len = 2;
+ *((int32_t *)(dst+1)) = (int32_t)(match_prob * 0x7fffffff);
+ dst += dst->len;
+ }
+
+ /*
* generate O_PROBE_STATE if necessary
*/
if (have_state && have_state->opcode != O_CHECK_STATE) {
OpenPOWER on IntegriCloud