pf: handle duplicate rules gracefully
Reviewed by: kp Reported by: dch PR: 262971 Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
parent
b3b462229f
commit
c4a08ef2af
@ -961,6 +961,8 @@ pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor,
|
||||
nv.size = nv.len;
|
||||
|
||||
ret = ioctl(dev, DIOCADDRULENV, &nv);
|
||||
if (ret == -1)
|
||||
ret = errno;
|
||||
|
||||
free(nv.data);
|
||||
nvlist_destroy(nvl);
|
||||
|
@ -1846,6 +1846,8 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
|
||||
u_int32_t ticket;
|
||||
char anchor[PF_ANCHOR_NAME_SIZE];
|
||||
int len = strlen(path);
|
||||
int error;
|
||||
bool was_present;
|
||||
|
||||
/* set up anchor before adding to path for anchor_call */
|
||||
if ((pf->opts & PF_OPT_NOACTION) == 0)
|
||||
@ -1867,12 +1869,23 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
|
||||
} else
|
||||
name = "";
|
||||
|
||||
was_present = false;
|
||||
if ((pf->opts & PF_OPT_NOACTION) == 0) {
|
||||
if (pfctl_add_pool(pf, &r->rpool, r->af))
|
||||
return (1);
|
||||
if (pfctl_add_rule(pf->dev, r, anchor, name, ticket,
|
||||
pf->paddr.ticket))
|
||||
error = pfctl_add_rule(pf->dev, r, anchor, name, ticket,
|
||||
pf->paddr.ticket);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/* things worked, do nothing */
|
||||
break;
|
||||
case EEXIST:
|
||||
/* an identical rule is already present */
|
||||
was_present = true;
|
||||
break;
|
||||
default:
|
||||
err(1, "DIOCADDRULENV");
|
||||
}
|
||||
}
|
||||
|
||||
if (pf->opts & PF_OPT_VERBOSE) {
|
||||
@ -1880,6 +1893,8 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pfctl_rule *r, int depth)
|
||||
print_rule(r, r->anchor ? r->anchor->name : "",
|
||||
pf->opts & PF_OPT_VERBOSE2,
|
||||
pf->opts & PF_OPT_NUMERIC);
|
||||
if (was_present)
|
||||
printf(" -- rule was already present");
|
||||
}
|
||||
path[len] = '\0';
|
||||
pfctl_clear_pool(&r->rpool);
|
||||
|
@ -2240,10 +2240,11 @@ pf_ioctl_addrule(struct pf_krule *rule, uint32_t ticket,
|
||||
pf_hash_rule(rule);
|
||||
if (RB_INSERT(pf_krule_global, ruleset->rules[rs_num].inactive.tree, rule) != NULL) {
|
||||
PF_RULES_WLOCK();
|
||||
TAILQ_REMOVE(ruleset->rules[rs_num].inactive.ptr, rule, entries);
|
||||
ruleset->rules[rs_num].inactive.rcount--;
|
||||
pf_free_rule(rule);
|
||||
rule = NULL;
|
||||
error = EINVAL;
|
||||
ERROUT(error);
|
||||
ERROUT(EEXIST);
|
||||
}
|
||||
PF_CONFIG_UNLOCK();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user