--- sys/netinet/ip_fw2.c Wed Apr 18 18:03:18 2007 +++ sys/netinet/ip_fw2.c Tue May 29 13:46:54 2007 @@ -3869,6 +3878,7 @@ * 2 move rules with given number to new set * 3 move rules with given set number to new set * 4 swap sets with given numbers + * 5 delete rules with given number and with given set number */ static int del_entry(struct ip_fw_chain *chain, u_int32_t arg) @@ -3881,16 +3891,14 @@ cmd = (arg >> 24) & 0xff; new_set = (arg >> 16) & 0xff; - if (cmd > 4) - return EINVAL; - if (new_set > RESVD_SET) - return EINVAL; - if (cmd == 0 || cmd == 2) { + if (cmd > 5 || new_set > RESVD_SET) + return (EINVAL); + if (cmd == 0 || cmd == 2 || cmd == 5) { if (rulenum >= IPFW_DEFAULT_RULE) - return EINVAL; + return (EINVAL); } else { if (rulenum > RESVD_SET) /* old_set */ - return EINVAL; + return (EINVAL); } IPFW_WLOCK(chain); @@ -3949,6 +3957,24 @@ else if (rule->set == new_set) rule->set = rulenum; break; + case 5: /* delete rules with given number and with given set number */ + /* rulenum - given rule number; + * new_set - given set number. + */ + for (; rule->rulenum < rulenum; prev = rule, rule = rule->next); + if (rule->rulenum != rulenum) { + IPFW_WUNLOCK(chain); + return (EINVAL); + } + flush_rule_ptrs(chain); + while (rule->rulenum == rulenum) { + if (rule->set == new_set) + rule = remove_rule(chain, rule, prev); + else { + prev = rule; + rule = rule->next; + } + } } /* * Look for rules to reclaim. We grab the list before @@ -4368,6 +4394,9 @@ bcopy(p, dst, sizeof *p); bcopy(&(p->rule->rulenum), &(dst->rule), sizeof(p->rule->rulenum)); + bcopy(&(p->rule->set), &dst->rule + + sizeof(p->rule->rulenum), + sizeof(p->rule->set)); /* * store a non-null value in "next". * The userland code will interpret a