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
This commit is contained in:
parent
99652d0eb2
commit
12b5dc6a39
@ -840,6 +840,20 @@ show_ipfw(struct ip_fw *rule)
|
||||
if (show_sets)
|
||||
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
|
||||
*/
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -3118,6 +3120,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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user