Fix/better handling of no-stats-tracking rules
authorMatt Corallo <git@bluematt.me>
Sat, 23 Oct 2021 16:10:20 +0000 (16:10 +0000)
committerMatt Corallo <git@bluematt.me>
Sat, 23 Oct 2021 18:07:29 +0000 (18:07 +0000)
genrules.py
install.sh
xdp.c

index 3f901e1c908a1595e35264279016e01e37874c7c..7e71d755fbd43e1187e76651b3e4c3ede8716eeb 100755 (executable)
@@ -294,7 +294,7 @@ with open("rules.h", "w") as out:
     rules6 = ""
     rules4 = ""
     use_v6_frags = False
-    rulecnt = 0
+    stats_rulecnt = 0
     ratelimitcnt = 0
     v4persrcratelimits = []
     v5persrcratelimits = []
@@ -369,7 +369,7 @@ with open("rules.h", "w") as out:
 
             # Now write the match handling!
             first_action = None
-            stats_action = None
+            stats_action = ""
             last_action = None
             for community in line.split("("):
                 if not community.startswith("generic, "):
@@ -467,7 +467,7 @@ with open("rules.h", "w") as out:
                     if low_bytes & 1 == 0:
                         last_action = "return XDP_PASS;"
                     if low_bytes & 2 == 2:
-                        stats_action = f"const uint32_t ruleidx = STATIC_RULE_CNT + {rulecnt};\n"
+                        stats_action = f"const uint32_t ruleidx = STATIC_RULE_CNT + {stats_rulecnt};\n"
                         stats_action += "INCREMENT_MATCH(ruleidx);"
                 elif ty == "0x8008":
                     assert False # We do not implement the redirect action
@@ -487,7 +487,7 @@ with open("rules.h", "w") as out:
                         write_rule("ip6->flow_lbl[0] = (ip6->flow_lbl[0] & 0x3f) | " + str((low_bytes & 3) << 6) + ";")
             if first_action is not None:
                 write_rule(first_action.replace("{stats_replace}", stats_action))
-            if stats_action is not None and (first_action is None or "{stats_replace}" not in first_action):
+            if stats_action != "" and (first_action is None or "{stats_replace}" not in first_action):
                 write_rule(stats_action)
             if last_action is not None:
                 write_rule(last_action)
@@ -495,11 +495,13 @@ with open("rules.h", "w") as out:
                 rules6 += "\t} while(0);\\\n"
             else:
                 rules4 += "\t} while(0);\\\n"
-            rulecnt += 1
+            if stats_action != "":
+                print(rule)
+                stats_rulecnt += 1
             lastrule = None
 
     out.write("\n")
-    out.write(f"#define RULECNT {rulecnt}\n")
+    out.write(f"#define STATS_RULECNT {stats_rulecnt}\n")
     if ratelimitcnt != 0:
         out.write(f"#define RATE_CNT {ratelimitcnt}\n")
     if rules4 != "":
index b8f83ab1e85823bfdfaadb0dc2ae47c3c6d622ab..8106defcede58a12000699055160daf35c3e5856 100755 (executable)
@@ -17,7 +17,7 @@ $(birdc show route table flowspec6 primary all)"
 
 echo "const uint8_t COMPILE_TIME_RAND[] = { $(dd if=/dev/urandom of=/dev/stdout bs=1 count=8 2>/dev/null | hexdump -e '4/1 "0x%02x, "') };" > rand.h
 
-echo "$RULES" | ./genrules.py --8021q=drop-vlan --v6frag=ignore-parse-if-rule --ihl=parse-options
+STATS_RULES="$(echo "$RULES" | ./genrules.py --8021q=drop-vlan --v6frag=ignore-parse-if-rule --ihl=parse-options)"
 clang $CLANG_ARGS -g -std=c99 -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -Wno-unused-function -O3 -emit-llvm -c xdp.c -o xdp.bc
 if [ "$2" != "" ]; then
        clang $4 -g -std=c99 -pedantic -Wall -Wextra -Wno-pointer-arith -O3 -emit-llvm -c "$2" -o wrapper.bc
@@ -37,4 +37,4 @@ ip link set "$1" xdpoffload obj xdp sec $XDP_SECTION || (
                echo "Failed to install in driver, using generic..." && ip link set "$1" xdpgeneric obj xdp sec $XDP_SECTION
        )
 )
-echo "$RULES" | grep "^flow. {" > installed-rules.txt
+echo "$STATS_RULES" > installed-rules.txt
diff --git a/xdp.c b/xdp.c
index 62120d2ef52107511c5f4a4f245c666ef5d4dcb2..e63bec379ee143672211c59c9bb4aaab19af9c2a 100644 (file)
--- a/xdp.c
+++ b/xdp.c
@@ -151,7 +151,7 @@ struct xdp_md {
 static const int XDP_PASS = 0;
 static const int XDP_DROP = 1;
 
-static long drop_cnt_map[RULECNT + STATIC_RULE_CNT];
+static long drop_cnt_map[STATS_RULECNT + STATIC_RULE_CNT];
 #define INCREMENT_MATCH(reason) { drop_cnt_map[reason] += 1; drop_cnt_map[reason] += data_end - pktdata; }
 
 #else /* TEST */
@@ -164,7 +164,7 @@ struct match_counter {
 };
 struct {
        __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
-       __uint(max_entries, RULECNT + STATIC_RULE_CNT);
+       __uint(max_entries, STATS_RULECNT + STATIC_RULE_CNT);
        __u32 *key;
        struct match_counter *value;
 } drop_cnt_map SEC(".maps");