Page MenuHomeFreeBSD

D31739.diff
No OneTemporary

D31739.diff

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -39,6 +39,7 @@
#include <sys/queue.h>
#include <sys/counter.h>
#include <sys/cpuset.h>
+#include <sys/epoch.h>
#include <sys/malloc.h>
#include <sys/nv.h>
#include <sys/refcount.h>
@@ -624,6 +625,8 @@
struct pf_keth_rules rules;
uint32_t ticket;
int open;
+ struct vnet *vnet;
+ struct epoch_context epoch_ctx;
};
union pf_krule_ptr {
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3712,18 +3712,18 @@
struct ether_header *e;
struct pf_keth_rule *r, *rm;
struct pf_mtag *mtag;
+ struct pf_keth_settings *settings;
uint8_t action;
- PF_RULES_RLOCK_TRACKER;
+ NET_EPOCH_ASSERT();
MPASS(kif->pfik_ifp->if_vnet == curvnet);
NET_EPOCH_ASSERT();
e = mtod(m, struct ether_header *);
- PF_RULES_RLOCK();
-
- r = TAILQ_FIRST(&V_pf_keth->rules);
+ settings = ck_pr_load_ptr(&V_pf_keth);
+ r = TAILQ_FIRST(&settings->rules);
rm = NULL;
while (r != NULL) {
@@ -3753,26 +3753,21 @@
r = rm;
/* Default to pass. */
- if (r == NULL) {
- PF_RULES_RUNLOCK();
+ if (r == NULL)
return (PF_PASS);
- }
/* Execute action. */
counter_u64_add(r->packets[dir == PF_OUT], 1);
counter_u64_add(r->bytes[dir == PF_OUT], m_length(m, NULL));
/* Shortcut. Don't tag if we're just going to drop anyway. */
- if (r->action == PF_DROP) {
- PF_RULES_RUNLOCK();
+ if (r->action == PF_DROP)
return (PF_DROP);
- }
if (r->tag > 0) {
mtag = pf_get_mtag(m);
if (mtag == NULL) {
counter_u64_add(V_pf_status.counters[PFRES_MEMORY], 1);
- PF_RULES_RUNLOCK();
return (PF_DROP);
}
mtag->tag = r->tag;
@@ -3782,7 +3777,6 @@
mtag = pf_get_mtag(m);
if (mtag == NULL) {
counter_u64_add(V_pf_status.counters[PFRES_MEMORY], 1);
- PF_RULES_RUNLOCK();
return (PF_DROP);
}
mtag->qid = r->qid;
@@ -3790,8 +3784,6 @@
action = r->action;
- PF_RULES_RUNLOCK();
-
return (action);
}
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -107,6 +107,7 @@
static int pfioctl(struct cdev *, u_long, caddr_t, int,
struct thread *);
static int pf_begin_eth(uint32_t *);
+static void pf_rollback_eth_cb(struct epoch_context *);
static int pf_rollback_eth(uint32_t);
static int pf_commit_eth(uint32_t);
static void pf_free_eth_rule(struct pf_keth_rule *);
@@ -701,6 +702,12 @@
PF_RULES_WASSERT();
+ if (V_pf_keth_inactive->open) {
+ /* We may be waiting for NET_EPOCH_CALL(pf_rollback_eth_cb) to
+ * finish. */
+ return (EBUSY);
+ }
+
/* Purge old inactive rules. */
TAILQ_FOREACH_SAFE(rule, &V_pf_keth_inactive->rules, entries, tmp) {
TAILQ_REMOVE(&V_pf_keth_inactive->rules, rule, entries);
@@ -713,6 +720,24 @@
return (0);
}
+static void
+pf_rollback_eth_cb(struct epoch_context *ctx)
+{
+ struct pf_keth_settings *settings;
+
+ settings = __containerof(ctx, struct pf_keth_settings, epoch_ctx);
+
+ CURVNET_SET(settings->vnet);
+
+ MPASS(settings == V_pf_keth_inactive);
+
+ PF_RULES_WLOCK();
+ pf_rollback_eth(V_pf_keth_inactive->ticket);
+ PF_RULES_WUNLOCK();
+
+ CURVNET_RESTORE();
+}
+
static int
pf_rollback_eth(uint32_t ticket)
{
@@ -780,15 +805,20 @@
ticket != V_pf_keth_inactive->ticket)
return (EBUSY);
+ PF_RULES_WASSERT();
+
pf_eth_calc_skip_steps(&V_pf_keth_inactive->rules);
settings = V_pf_keth;
- V_pf_keth = V_pf_keth_inactive;
+ ck_pr_store_ptr(&V_pf_keth, V_pf_keth_inactive);
V_pf_keth_inactive = settings;
V_pf_keth_inactive->ticket = V_pf_keth->ticket;
- /* Clean up inactive rules. */
- return (pf_rollback_eth(ticket));
+ /* Clean up inactive rules (i.e. previously active rules), only when
+ * we're sure they're no longer used. */
+ NET_EPOCH_CALL(pf_rollback_eth_cb, &V_pf_keth_inactive->epoch_ctx);
+
+ return (0);
}
#ifdef ALTQ
diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c
--- a/sys/netpfil/pf/pf_ruleset.c
+++ b/sys/netpfil/pf/pf_ruleset.c
@@ -154,6 +154,7 @@
TAILQ_INIT(&settings->rules);
settings->ticket = 0;
settings->open = 0;
+ settings->vnet = curvnet;
}
struct pf_kruleset *

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 12, 5:37 AM (17 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16606694
Default Alt Text
D31739.diff (4 KB)

Event Timeline