Page MenuHomeFreeBSD

D3503.1783170121.diff
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

D3503.1783170121.diff

Index: pf_if.c
===================================================================
--- pf_if.c
+++ pf_if.c
@@ -120,6 +120,8 @@
kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
PF_RULES_WLOCK();
V_pfi_all = pfi_kif_attach(kif, IFG_ALL);
+ /* Make sure it does not go away */
+ pfi_kif_ref(kif);
PF_RULES_WUNLOCK();
IFNET_RLOCK();
@@ -207,6 +209,7 @@
*/
kif->pfik_tzero = time_second > 1 ? time_second : 0;
TAILQ_INIT(&kif->pfik_dynaddrs);
+ refcount_init(&kif->pfik_rulerefs, 0);
RB_INSERT(pfi_ifhead, &V_pfi_ifs, kif);
@@ -217,8 +220,7 @@
pfi_kif_ref(struct pfi_kif *kif)
{
- PF_RULES_WASSERT();
- kif->pfik_rulerefs++;
+ refcount_acquire(&kif->pfik_rulerefs);
}
void
@@ -225,10 +227,9 @@
pfi_kif_unref(struct pfi_kif *kif)
{
- PF_RULES_WASSERT();
KASSERT(kif->pfik_rulerefs > 0, ("%s: %p has zero refs", __func__, kif));
- kif->pfik_rulerefs--;
+ refcount_release(&kif->pfik_rulerefs);
if (kif->pfik_rulerefs > 0)
return;
@@ -237,6 +238,7 @@
if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == V_pfi_all)
return;
+ PF_RULES_WASSERT();
RB_REMOVE(pfi_ifhead, &V_pfi_ifs, kif);
kif->pfik_flags |= PFI_IFLAG_REFS;
Index: pf_ioctl.c
===================================================================
--- pf_ioctl.c
+++ pf_ioctl.c
@@ -1163,8 +1163,23 @@
rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK);
bcopy(&pr->rule, rule, sizeof(struct pf_rule));
- if (rule->ifname[0])
- kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
+ /* This is done here to hold RULES_WLOCK at a minimum */
+ if (rule->ifname[0]) {
+ if ((rule->kif = pfi_kif_find(rule->ifname)) == NULL) {
+ /*
+ * This happens rarely!
+ * Only for rules with non-existant interfaces
+ */
+ kif = malloc(sizeof(*kif), PFI_MTYPE, M_WAITOK);
+ PF_RULES_WLOCK();
+ rule->kif = pfi_kif_attach(kif, rule->ifname);
+ if (rule->kif != kif)
+ free(kif, PFI_MTYPE);
+ PF_RULES_WUNLOCK();
+ }
+ pfi_kif_ref(rule->kif);
+ } else
+ rule->kif = NULL;
rule->states_cur = counter_u64_alloc(M_WAITOK);
rule->states_tot = counter_u64_alloc(M_WAITOK);
rule->src_nodes = counter_u64_alloc(M_WAITOK);
@@ -1174,7 +1189,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)
@@ -1201,11 +1217,6 @@
rule->nr = tail->nr + 1;
else
rule->nr = 0;
- if (rule->ifname[0]) {
- rule->kif = pfi_kif_attach(kif, rule->ifname);
- pfi_kif_ref(rule->kif);
- } else
- rule->kif = NULL;
if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
error = EBUSY;
@@ -1268,7 +1279,8 @@
if (error) {
pf_free_rule(rule);
- PF_RULES_WUNLOCK();
+ PF_RULES_RUNLOCK();
+ sx_xunlock(&pf_ioctl_lock);
break;
}
@@ -1278,18 +1290,23 @@
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);
free(rule, M_PFRULE);
- if (kif)
- free(kif, PFI_MTYPE);
+ if (rule->kif != NULL) {
+ PF_RULES_WLOCK();
+ pfi_kif_unref(rule->kif);
+ PF_RULES_WUNLOCK();
+ }
break;
}
@@ -1299,17 +1316,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 +1340,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 +1351,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 +1378,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 +1388,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 +1408,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;
}
@@ -1456,6 +1484,9 @@
if (newrule->ifname[0]) {
newrule->kif = pfi_kif_attach(kif,
newrule->ifname);
+ if (newrule->kif != kif)
+ free(kif, PFI_MTYPE);
+ kif = NULL;
pfi_kif_ref(newrule->kif);
} else
newrule->kif = NULL;
@@ -2235,6 +2266,8 @@
if (pa->ifname[0]) {
pa->kif = pfi_kif_attach(kif, pa->ifname);
pfi_kif_ref(pa->kif);
+ if (pa->kif != kif)
+ free(kif, PFI_MTYPE);
} else
pa->kif = NULL;
if (pa->addr.type == PF_ADDR_DYNIFTL && ((error =
@@ -2354,6 +2387,8 @@
if (newpa->ifname[0]) {
newpa->kif = pfi_kif_attach(kif, newpa->ifname);
pfi_kif_ref(newpa->kif);
+ if (newpa->kif != kif)
+ free(kif, PFI_MTYPE);
kif = NULL;
}

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 4, 1:02 PM (18 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29012376
Default Alt Text
D3503.1783170121.diff (6 KB)

Event Timeline