From: Matt Corallo Date: Thu, 10 Jun 2021 15:35:31 +0000 (+0000) Subject: Optimize per-src v6 matching on <= /64s to avoid always storing 4 0-bytes X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=flowspec-xdp;a=commitdiff_plain;h=04df12ec0dbd79134619a437e88c43e6e256b8d5 Optimize per-src v6 matching on <= /64s to avoid always storing 4 0-bytes --- diff --git a/genrules.py b/genrules.py index 1ab90b0..b2bf796 100755 --- a/genrules.py +++ b/genrules.py @@ -297,6 +297,7 @@ with open("rules.h", "w") as out: rulecnt = 0 ratelimitcnt = 0 v4persrcratelimits = [] + v5persrcratelimits = [] v6persrcratelimits = [] lastrule = None @@ -422,6 +423,12 @@ with open("rules.h", "w") as out: first_action += f"struct persrc_rate4_ptr rate_ptr = get_v4_persrc_ratelimit(srcip, rate_map, {(high_byte + 1) * 4096});\n" first_action += f"struct persrc_rate4_entry *rate = rate_ptr.rate;\n" v4persrcratelimits.append((high_byte + 1) * 4096) + elif mid_byte <= 64: + first_action += f"const uint64_t srcip = BE128BEHIGH64(ip6->saddr & MASK6({mid_byte}));\n" + first_action += f"void *rate_map = &v5_src_rate_{len(v5persrcratelimits)};\n" + first_action += f"struct persrc_rate5_ptr rate_ptr = get_v5_persrc_ratelimit(srcip, rate_map, {(high_byte + 1) * 4096});\n" + first_action += f"struct persrc_rate5_entry *rate = rate_ptr.rate;\n" + v5persrcratelimits.append((high_byte + 1) * 4096) else: if mid_byte > 128: continue @@ -504,5 +511,7 @@ with open("rules.h", "w") as out: with open("maps.h", "w") as out: for idx, limit in enumerate(v4persrcratelimits): out.write(f"SRC_RATE_DEFINE(4, {idx}, {limit})\n") + for idx, limit in enumerate(v5persrcratelimits): + out.write(f"SRC_RATE_DEFINE(5, {idx}, {limit})\n") for idx, limit in enumerate(v6persrcratelimits): out.write(f"SRC_RATE_DEFINE(6, {idx}, {limit})\n") diff --git a/xdp.c b/xdp.c index 29e2cf3..95ab7df 100644 --- a/xdp.c +++ b/xdp.c @@ -96,10 +96,15 @@ struct tcphdr { #define HTON128(a) BIGEND128(a >> 3*32, a >> 2*32, a >> 1*32, a>> 0*32) // Yes, somehow macro'ing this changes LLVM's view of htons... #define BE16(a) (((((uint16_t)a) & 0xff00) >> 8) | ((((uint16_t)a) & 0xff) << 8)) +#define BE128BEHIGH64(val) ((uint64_t)((uint128_t)(val))) + #elif defined(__BIG_ENDIAN) + #define BIGEND128(a, b, c, d) ((((uint128_t)(a)) << 3*32) | (((uint128_t)(b)) << 2*32) | (((uint128_t)(c)) << 1*32) | (((uint128_t)(d)) << 0*32)) #define HTON128(a) ((uint128_t)(a)) #define BE16(a) ((uint16_t)(a)) +#define BE128BEHIGH64(val) ((uint64_t)(((uint128_t)(val)) >> 64)) + #else #error "Need endian info" #endif @@ -256,6 +261,7 @@ static inline struct persrc_rate##IPV##_ptr get_v##IPV##_persrc_ratelimit(IP_TYP } CREATE_PERSRC_LOOKUP(6, uint128_t) +CREATE_PERSRC_LOOKUP(5, uint64_t) // IPv6 matching no more than a /64 CREATE_PERSRC_LOOKUP(4, uint32_t) #define SRC_RATE_DEFINE(IPV, n, limit) \