pf: fix DIOCCHANGERULE after pf config and rb tree of rules

Reviewed by:	kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
This commit is contained in:
Mateusz Guzik 2022-05-04 19:53:12 +00:00
parent c4a6d412c9
commit ff80dd034a

View file

@ -3432,6 +3432,7 @@ DIOCGETRULENV_error:
} }
#define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x) #define ERROUT(x) ERROUT_IOCTL(DIOCCHANGERULE_error, x)
PF_CONFIG_LOCK();
PF_RULES_WLOCK(); PF_RULES_WLOCK();
#ifdef PF_WANT_32_TO_64_COUNTER #ifdef PF_WANT_32_TO_64_COUNTER
if (newrule != NULL) { if (newrule != NULL) {
@ -3540,6 +3541,7 @@ DIOCGETRULENV_error:
if (error) { if (error) {
pf_free_rule(newrule); pf_free_rule(newrule);
PF_RULES_WUNLOCK(); PF_RULES_WUNLOCK();
PF_CONFIG_UNLOCK();
break; break;
} }
@ -3562,6 +3564,7 @@ DIOCGETRULENV_error:
if (newrule != NULL) if (newrule != NULL)
pf_free_rule(newrule); pf_free_rule(newrule);
PF_RULES_WUNLOCK(); PF_RULES_WUNLOCK();
PF_CONFIG_UNLOCK();
error = EINVAL; error = EINVAL;
break; break;
} }
@ -3570,8 +3573,20 @@ DIOCGETRULENV_error:
if (pcr->action == PF_CHANGE_REMOVE) { if (pcr->action == PF_CHANGE_REMOVE) {
pf_unlink_rule(ruleset->rules[rs_num].active.ptr, pf_unlink_rule(ruleset->rules[rs_num].active.ptr,
oldrule); oldrule);
RB_REMOVE(pf_krule_global,
ruleset->rules[rs_num].active.tree, oldrule);
ruleset->rules[rs_num].active.rcount--; ruleset->rules[rs_num].active.rcount--;
} else { } else {
pf_hash_rule(newrule);
if (RB_INSERT(pf_krule_global,
ruleset->rules[rs_num].active.tree, newrule) != NULL) {
pf_free_rule(newrule);
PF_RULES_WUNLOCK();
PF_CONFIG_UNLOCK();
error = EEXIST;
break;
}
if (oldrule == NULL) if (oldrule == NULL)
TAILQ_INSERT_TAIL( TAILQ_INSERT_TAIL(
ruleset->rules[rs_num].active.ptr, ruleset->rules[rs_num].active.ptr,
@ -3597,6 +3612,7 @@ DIOCGETRULENV_error:
pf_remove_if_empty_kruleset(ruleset); pf_remove_if_empty_kruleset(ruleset);
PF_RULES_WUNLOCK(); PF_RULES_WUNLOCK();
PF_CONFIG_UNLOCK();
break; break;
#undef ERROUT #undef ERROUT