Index: pf_ioctl.c =================================================================== --- pf_ioctl.c +++ pf_ioctl.c @@ -1174,7 +1174,8 @@ #define ERROUT(x) { error = (x); goto DIOCADDRULE_error; } - PF_RULES_WLOCK(); + sx_xlock(&pf_ioctl_lock); + PF_RULES_RLOCK(); pr->anchor[sizeof(pr->anchor) - 1] = 0; ruleset = pf_find_ruleset(pr->anchor); if (ruleset == NULL) @@ -1268,7 +1269,8 @@ if (error) { pf_free_rule(rule); - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); break; } @@ -1278,12 +1280,14 @@ TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr, rule, entries); ruleset->rules[rs_num].inactive.rcount++; - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); break; #undef ERROUT DIOCADDRULE_error: - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock) counter_u64_free(rule->states_cur); counter_u64_free(rule->states_tot); counter_u64_free(rule->src_nodes); @@ -1299,17 +1303,20 @@ struct pf_rule *tail; int rs_num; - PF_RULES_WLOCK(); + sx_slock(&pf_ioctl_lock); + PF_RULES_RLOCK(); pr->anchor[sizeof(pr->anchor) - 1] = 0; ruleset = pf_find_ruleset(pr->anchor); if (ruleset == NULL) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EINVAL; break; } rs_num = pf_get_ruleset_number(pr->rule.action); if (rs_num >= PF_RULESET_MAX) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EINVAL; break; } @@ -1320,7 +1327,8 @@ else pr->nr = 0; pr->ticket = ruleset->rules[rs_num].active.ticket; - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); break; } @@ -1330,22 +1338,26 @@ struct pf_rule *rule; int rs_num, i; - PF_RULES_WLOCK(); + sx_slock(&pf_ioctl_lock); + PF_RULES_RLOCK(); pr->anchor[sizeof(pr->anchor) - 1] = 0; ruleset = pf_find_ruleset(pr->anchor); if (ruleset == NULL) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EINVAL; break; } rs_num = pf_get_ruleset_number(pr->rule.action); if (rs_num >= PF_RULESET_MAX) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EINVAL; break; } if (pr->ticket != ruleset->rules[rs_num].active.ticket) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EBUSY; break; } @@ -1353,7 +1365,8 @@ while ((rule != NULL) && (rule->nr != pr->nr)) rule = TAILQ_NEXT(rule, entries); if (rule == NULL) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EBUSY; break; } @@ -1362,7 +1375,8 @@ pr->rule.u_states_tot = counter_u64_fetch(rule->states_tot); pr->rule.u_src_nodes = counter_u64_fetch(rule->src_nodes); if (pf_anchor_copyout(ruleset, rule, pr)) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); error = EBUSY; break; } @@ -1381,7 +1395,8 @@ rule->bytes[0] = rule->bytes[1] = 0; counter_u64_zero(rule->states_tot); } - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_sunlock(&pf_ioctl_lock); break; } @@ -2055,9 +2070,11 @@ bcopy(&pa->altq, altq, sizeof(struct pf_altq)); altq->local_flags = 0; - PF_RULES_WLOCK(); + sx_xlock(&pf_ioctl_lock); + PF_RULES_RLOCK(); if (pa->ticket != V_ticket_altqs_inactive) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); free(altq, M_PFALTQ); error = EBUSY; break; @@ -2069,7 +2086,8 @@ */ if (altq->qname[0] != 0) { if ((altq->qid = pf_qname2qid(altq->qname)) == 0) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); error = EBUSY; free(altq, M_PFALTQ); break; @@ -2090,7 +2108,8 @@ error = altq_add(altq); if (error) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); free(altq, M_PFALTQ); break; } @@ -2097,7 +2116,8 @@ TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries); bcopy(altq, &pa->altq, sizeof(struct pf_altq)); - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); break; } @@ -2223,9 +2243,11 @@ bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr)); if (pa->ifname[0]) kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK); - PF_RULES_WLOCK(); + sx_xlock(&pf_ioctl_lock); + PF_RULES_RLOCK(); if (pp->ticket != V_ticket_pabuf) { - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); if (pa->ifname[0]) free(kif, PFI_MTYPE); free(pa, M_PFRULE); @@ -2241,12 +2263,14 @@ pfi_dynaddr_setup(&pa->addr, pp->af)) != 0)) { if (pa->ifname[0]) pfi_kif_unref(pa->kif); - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); free(pa, M_PFRULE); break; } TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries); - PF_RULES_WUNLOCK(); + PF_RULES_RUNLOCK(); + sx_xunlock(&pf_ioctl_lock); break; }