Page MenuHomeFreeBSD

D60894.1794387787.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D60894.1794387787.diff

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1029,6 +1029,11 @@
TAILQ_HEAD(, pf_kstate) states[2];
};
+CTASSERT(offsetof(struct pf_state_key, addr) == offsetof(struct pf_state_key_cmp, addr));
+CTASSERT(offsetof(struct pf_state_key, port) == offsetof(struct pf_state_key_cmp, port));
+CTASSERT(offsetof(struct pf_state_key, proto) == offsetof(struct pf_state_key_cmp, proto));
+CTASSERT(offsetof(struct pf_state_key, af) == offsetof(struct pf_state_key_cmp, af));
+
#define PF_REVERSED_KEY(state, family) \
(((state)->key[PF_SK_WIRE]->af != (state)->key[PF_SK_STACK]->af) && \
((state)->key[PF_SK_WIRE]->af != (family)) && \
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
@@ -931,6 +931,42 @@
sizeof(sum), (caddr_t)&sum);
}
+/*
+ * compare state keys
+ *
+ * clang emits a call to memcmp despite the size being small-ish (40 bytes) and
+ * known at compilation time, which is clearly wasteful.
+ *
+ * Optimize it on amd64 the same way memcmp is implemented on this platform.
+ * Interested parties running other architectures are welcome to add their own
+ * implementation or add to the ifdef.
+ */
+#ifdef __amd64__
+static __always_inline int
+pf_bcmp_state_key(const struct pf_state_key *k1, const struct pf_state_key_cmp *k2)
+{
+ const uint64_t *k1_bytes = (const uint64_t *)k1;
+ const uint64_t *k2_bytes = (const uint64_t *)k2;
+ uint64_t res;
+ size_t i;
+
+ res = 0;
+ for (i = 0; i < sizeof(struct pf_state_key_cmp) / sizeof(uint64_t); i++) {
+ res |= k1_bytes[i] - k2_bytes[i];
+ }
+
+ return (res != 0);
+}
+_Static_assert(sizeof(struct pf_state_key_cmp) % sizeof(uint64_t) == 0,
+ "pf_bcmp_state_key operates on 8 byte chunks");
+#else
+static __always_inline int
+pf_bcmp_state_key(const struct pf_state_key*k1, const struct pf_state_key_cmp *k2)
+{
+ return (bcmp(k1, k2, sizeof(struct pf_state_key_cmp)));
+}
+#endif
+
int
pf_addr_cmp(const struct pf_addr *a, const struct pf_addr *b, sa_family_t af)
{
@@ -1798,7 +1834,7 @@
keyattach:
LIST_FOREACH(cur, &kh->keys, entry)
- if (bcmp(cur, sk, sizeof(struct pf_state_key_cmp)) == 0)
+ if (pf_bcmp_state_key(cur, (struct pf_state_key_cmp *)sk) == 0)
break;
if (cur != NULL) {
@@ -2256,7 +2292,7 @@
PF_HASHROW_LOCK(kh);
LIST_FOREACH(sk, &kh->keys, entry)
- if (bcmp(sk, key, sizeof(struct pf_state_key_cmp)) == 0)
+ if (pf_bcmp_state_key(sk, key) == 0)
break;
if (sk == NULL) {
PF_HASHROW_UNLOCK(kh);
@@ -2353,7 +2389,7 @@
PF_HASHROW_LOCK(kh);
LIST_FOREACH(sk, &kh->keys, entry)
- if (bcmp(sk, key, sizeof(struct pf_state_key_cmp)) == 0)
+ if (pf_bcmp_state_key(sk, key) == 0)
break;
if (sk == NULL) {
PF_HASHROW_UNLOCK(kh);

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 11, 9:03 AM (17 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41657272
Default Alt Text
D60894.1794387787.diff (2 KB)

Event Timeline