git: c4a08ef2af6f - main - pf: handle duplicate rules gracefully
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 01 Apr 2022 18:02:09 UTC
The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=c4a08ef2af6fe0b0d1b03f7ec4f20bed96de20e8 commit c4a08ef2af6fe0b0d1b03f7ec4f20bed96de20e8 Author: Mateusz Guzik <mjg@FreeBSD.org> AuthorDate: 2022-04-01 15:04:03 +0000 Commit: Mateusz Guzik <mjg@FreeBSD.org> CommitDate: 2022-04-01 18:01:48 +0000 pf: handle duplicate rules gracefully Reviewed by: kp Reported by: dch PR: 262971 Sponsored by: Rubicon Communications, LLC ("Netgate") --- lib/libpfctl/libpfctl.c | 2 ++ sbin/pfctl/pfctl.c | 19 +++++++++++++++++-- sys/netpfil/pf/pf_ioctl.c | 5 +++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 8696ef1ace25..991d3fce9780 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -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); diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 67358a325f77..13e8e825c1ab 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -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); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index eae7b3bf1fa0..c170a270454b 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -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();