Avoid inlining siphash globally to avoid hitting BPF instruction limits
authorMatt Corallo <git@bluematt.me>
Sat, 23 Oct 2021 17:34:00 +0000 (17:34 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 28 Oct 2021 01:34:22 +0000 (01:34 +0000)
siphash.h
test.sh
xdp.c

index 4c2ec7aa3d2db82582c978a7a27729475faa18d9..298a3a2dd626470915f21c7fe39fa0f0d56e827d 100644 (file)
--- a/siphash.h
+++ b/siphash.h
@@ -140,3 +140,15 @@ static inline uint64_t siphash(const void *in, const size_t inlen, const uint8_t
     b = v0 ^ v1 ^ v2 ^ v3;
     return b;
 }
+
+#include "rand.h"
+static uint64_t siphash_uint64_t(const uint64_t in) {
+       return siphash(&in, sizeof(uint64_t), COMPILE_TIME_RAND);
+}
+__attribute__((always_inline))
+static inline uint64_t siphash_uint32_t(const uint32_t in) {
+       return siphash_uint64_t(in);
+}
+static uint64_t siphash_uint128_t(const __uint128_t in) {
+       return siphash(&in, sizeof(__uint128_t), COMPILE_TIME_RAND);
+}
diff --git a/test.sh b/test.sh
index 0a0dd50fa1d399cc6b0d4cce49c62160382be8c3..e17ec4bcc9a170ed9f946500f50c6ea91993174e 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -7,12 +7,12 @@ COMMUNITY_DROP="
        BGP.ext_community: (generic, 0x80060000, 0x0) (generic, 0x80070000, 0xf) (generic, 0x80090000, 0x3f)"
 
 DO_TEST() {
-       clang -g -std=c99 -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -Wno-tautological-constant-out-of-range-compare -Wno-unused-function -Wno-visibility -O3 -emit-llvm -c xdp.c -o xdp.bc
+       clang -g -std=c99 -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -Wno-unused-function -Wno-tautological-constant-out-of-range-compare -Wno-unused-function -Wno-visibility -O3 -emit-llvm -c xdp.c -o xdp.bc
        cat xdp.bc | llc -O3 -march=bpf -filetype=obj -o xdp
 
        echo "$TEST_PKT" >> rules.h
        echo "#define TEST_EXP $1" >> rules.h
-       clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -Wno-tautological-constant-out-of-range-compare -O0 -g xdp.c -o xdp && ./xdp
+       clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -Wno-unused-function -Wno-tautological-constant-out-of-range-compare -O0 -g xdp.c -o xdp && ./xdp
 }
 
 TEST_PKT='#define TEST \
diff --git a/xdp.c b/xdp.c
index e63bec379ee143672211c59c9bb4aaab19af9c2a..36a45e2a72783c2ee49a326c689edc16e69cd1a3 100644 (file)
--- a/xdp.c
+++ b/xdp.c
@@ -226,8 +226,6 @@ struct {
 #define SRC_HASH_BUCKET_COUNT_POW 4
 #define SRC_HASH_BUCKET_COUNT (1 << SRC_HASH_BUCKET_COUNT_POW)
 
-#include "rand.h"
-
 #define CREATE_PERSRC_LOOKUP(IPV, IP_TYPE) \
 struct persrc_rate##IPV##_entry { \
        uint64_t sent_time; \
@@ -247,7 +245,7 @@ struct persrc_rate##IPV##_ptr { \
 __attribute__((always_inline)) \
 static inline struct persrc_rate##IPV##_ptr get_v##IPV##_persrc_ratelimit(IP_TYPE key, void *map, size_t map_limit, int64_t cur_time_masked) { \
        struct persrc_rate##IPV##_ptr res = { .rate = NULL, .lock = NULL }; \
-       uint64_t hash = siphash(&key, sizeof(key), COMPILE_TIME_RAND); \
+       uint64_t hash = siphash_##IP_TYPE(key); \
  \
        const uint32_t map_key = hash % SRC_HASH_MAX_PARALLELISM; \
        struct persrc_rate##IPV##_bucket *buckets = bpf_map_lookup_elem(map, &map_key); \