Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109919416
D31739.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D31739.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D31739: pf: Do not hold PF_RULES_RLOCK while processing Ethernet rules
Attached
Detach File
Event Timeline
Log In to Comment