Improve arg parsing somewhat and add flexibility/standardness
authorMatt Corallo <git@bluematt.me>
Sat, 3 Apr 2021 22:08:01 +0000 (18:08 -0400)
committerMatt Corallo <git@bluematt.me>
Sun, 4 Apr 2021 00:08:08 +0000 (20:08 -0400)
genrules.py
test.sh
xdp.c

index d372806a8e8c99a6b9fed67158cbf6e04e0406ba..c0a5311916f6f25536848a21c3a5061be547bab5 100755 (executable)
@@ -3,17 +3,14 @@
 import sys
 import ipaddress
 from enum import Enum
+import argparse
+
 
 IP_PROTO_ICMP = 1
 IP_PROTO_ICMPV6 = 58
 IP_PROTO_TCP = 6
 IP_PROTO_UDP = 17
 
-if len(sys.argv) > 2 and sys.argv[2].startswith("parse_ihl"):
-    PARSE_IHL = True
-else:
-    PARSE_IHL = False
-
 class ASTAction(Enum):
     OR = 1,
     AND = 2,
@@ -239,12 +236,30 @@ def flow_label_to_rule(rules):
 if (!( {ast.write("((((uint32_t)(ip6->flow_lbl[0] & 0xf)) << 2*8) | (((uint32_t)ip6->flow_lbl[1]) << 1*8) | (uint32_t)ip6->flow_lbl[0])")} )) break;"""
 
 with open("rules.h", "w") as out:
-    if len(sys.argv) > 1 and sys.argv[1] == "parse_8021q":
-        out.write("#define PARSE_8021Q\n")
-    if len(sys.argv) > 1 and sys.argv[1].startswith("req_8021q="):
-        out.write("#define PARSE_8021Q\n")
-        out.write(f"#define REQ_8021Q {sys.argv[1][10:]}\n")
-
+    parse = argparse.ArgumentParser()
+    parse.add_argument("--ihl", dest="ihl", required=True, choices=["drop-options","accept-options","parse-options"])
+    parse.add_argument("--8021q", dest="vlan", required=True, choices=["drop-vlan","accept-vlan","parse-vlan"])
+    parse.add_argument("--require-8021q", dest="vlan_tag")
+    args = parse.parse_args(sys.argv[1:])
+
+    if args.ihl == "drop-options":
+        out.write("#define PARSE_IHL XDP_DROP\n")
+    elif args.ihl == "accept-options":
+        out.write("#define PARSE_IHL XDP_PASS\n")
+    elif args.ihl == "parse-options":
+        out.write("#define PARSE_IHL PARSE\n")
+
+    if args.vlan == "drop-vlan":
+        out.write("#define PARSE_8021Q XDP_DROP\n")
+    elif args.vlan == "accept-vlan":
+        out.write("#define PARSE_8021Q XDP_PASS\n")
+    elif args.vlan == "parse-vlan":
+        out.write("#define PARSE_8021Q PARSE\n")
+
+    if args.vlan_tag is not None:
+        if args.vlan != "parse-vlan":
+            assert False
+        out.write("#define REQ_8021Q " + args.vlan_tag + "\n")
 
     out.write("#define RULES \\\n")
 
diff --git a/test.sh b/test.sh
index bbb38dd363b59b607d51eb79104d38efe6da11d7..f25fffa482fb6a9c0ba6c341461c0ccaf8e42da8 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -15,33 +15,33 @@ TEST_PKT='#define TEST \
 "\xb5\xc3\xa9\xa6\x21\x14\xc7\xd9\x71\x07"'
 
 # Test all the things...
-echo "flow4 { src 72.229.104.206/32; dst 103.99.170.10/32; proto = 17; sport = 56733; dport = 4242; length = 140; dscp 0/0xff; fragment !dont_fragment && !is_fragment && !first_fragment && !last_fragment };" | ./genrules.py
+echo "flow4 { src 72.229.104.206/32; dst 103.99.170.10/32; proto = 17; sport = 56733; dport = 4242; length = 140; dscp 0/0xff; fragment !dont_fragment && !is_fragment && !first_fragment && !last_fragment };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { port = 4242; icmp code = 0; };" | ./genrules.py
+echo "flow4 { port = 4242; icmp code = 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
 # Some port tests...
-echo "flow4 { port = 4242 && = 56733; };" | ./genrules.py
+echo "flow4 { port = 4242 && = 56733; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { port = 4242 || 1; sport = 56733 };" | ./genrules.py
+echo "flow4 { port = 4242 || 1; sport = 56733 };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { port = 4242 && 1 };" | ./genrules.py
+echo "flow4 { port = 4242 && 1 };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { icmp code != 0; };" | ./genrules.py parse_8021q
+echo "flow4 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
@@ -55,17 +55,17 @@ TEST_PKT='#define TEST \
 "\x75\xde\xeb\x22\xd6\x80"'
 
 # Some v6 TCP tests...
-echo "flow6 { src 2a01:4f8:130:71d2::2/128; dst 2620:6e:a000:2001::6/128; next header 6; port 8333 && 49778; tcp flags 0x010/0xfff;};" | ./genrules.py
+echo "flow6 { src 2a01:4f8:130:71d2::2/128; dst 2620:6e:a000:2001::6/128; next header 6; port 8333 && 49778; tcp flags 0x010/0xfff;};" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 0:4f8:130:71d2::2/128 offset 16; dst 0:0:a000:2001::/64 offset 32; next header 6; port 8333 && 49778; tcp flags 0x010/0xfff;};" | ./genrules.py
+echo "flow6 { src 0:4f8:130:71d2::2/128 offset 16; dst 0:0:a000:2001::/64 offset 32; next header 6; port 8333 && 49778; tcp flags 0x010/0xfff;};" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { icmp code != 0; };" | ./genrules.py
+echo "flow6 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
@@ -80,41 +80,53 @@ TEST_PKT='#define TEST \
 "\x32\x33\x34\x35\x36\x37"'
 
 # ICMP and VLAN tests
-echo "flow4 { src 10.0.0.0/8; dst 209.250.0.0/16; proto = 1; icmp type 8; icmp code >= 0; length < 100; fragment dont_fragment; };" | ./genrules.py parse_8021q
+echo "flow4 { src 10.0.0.0/8; dst 209.250.0.0/16; proto = 1; icmp type 8; icmp code >= 0; length < 100; fragment dont_fragment; };" | ./genrules.py --ihl=accept-options --8021q=parse-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { icmp type 8; icmp code > 0; };" | ./genrules.py parse_8021q
+echo "flow4 { icmp type 8; icmp code > 0; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { icmp type 9; };" | ./genrules.py parse_8021q
+echo "flow4 { icmp type 9; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { src 10.0.0.0/8; dst 209.250.0.0/16; proto = 1; icmp type 8; icmp code >= 0; length < 100; fragment dont_fragment; };" | ./genrules.py req_8021q=3
+echo "flow4 { src 10.0.0.0/8; dst 209.250.0.0/16; proto = 1; icmp type 8; icmp code >= 0; length < 100; fragment dont_fragment; };" | ./genrules.py --ihl=accept-options --8021q=parse-vlan --require-8021q=3
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py req_8021q=4
+echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py --ihl=accept-options --8021q=parse-vlan --require-8021q=4
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py req_8021q=3
+echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan --require-8021q=3
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow4 { port 42; };" | ./genrules.py parse_8021q
+echo "flow4 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
+# Test --8021q option handling
+echo "flow4 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan --v6frag=drop-frags
+echo "$TEST_PKT" >> rules.h
+echo "#define TEST_EXP XDP_DROP" >> rules.h
+clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
+
+echo "flow4 { };" | ./genrules.py --ihl=drop-options --8021q=accept-vlan --v6frag=drop-frags
+echo "$TEST_PKT" >> rules.h
+echo "#define TEST_EXP XDP_PASS" >> rules.h
+clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
+
+
 TEST_PKT='#define TEST \
 "\x00\x0d\xb9\x50\x11\x4c\x00\x17\x10\x95\xe8\x96\x86\xdd\x60\x0a" \
 "\xb8\x00\x00\x40\x3a\x3e\x20\x01\x04\x70\x00\x00\x02\xc8\x00\x00" \
@@ -126,27 +138,27 @@ TEST_PKT='#define TEST \
 "\x00\x00\x00\x00\x00\x00"'
 
 # ICMPv6 tests
-echo "flow6 { icmp type 129; icmp code 0; };" | ./genrules.py
+echo "flow6 { icmp type 129; icmp code 0; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { icmp code != 0; };" | ./genrules.py
+echo "flow6 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { tcp flags 0x0/0x0; };" | ./genrules.py
+echo "flow6 { tcp flags 0x0/0x0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { port 42; };" | ./genrules.py
+echo "flow6 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { fragment is_fragment || first_fragment || last_fragment; };" | ./genrules.py
+echo "flow6 { fragment is_fragment || first_fragment || last_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
@@ -164,23 +176,23 @@ TEST_PKT='#define TEST \
 
 # Last frag ICMPv6 tests
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && !first_fragment && last_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && !first_fragment && last_fragment; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment || first_fragment || !last_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment || first_fragment || !last_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr?
-echo "flow6 { next header 44; };" | ./genrules.py
+echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
@@ -270,34 +282,34 @@ TEST_PKT='#define TEST \
 
 # First frag ICMPv6 tests
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && first_fragment && !last_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && first_fragment && !last_fragment; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment || !first_fragment || last_fragment; };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment !is_fragment || !first_fragment || last_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
-echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && first_fragment && !last_fragment; icmp code 0; icmp type 128 };" | ./genrules.py
+echo "flow6 { src 2620:6e:a007:233::1/128; dst 2001:470:0:503::2/128; fragment is_fragment && first_fragment && !last_fragment; icmp code 0; icmp type 128 };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr?
-echo "flow6 { next header 44; };" | ./genrules.py
+echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_DROP" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
 
 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr?
-echo "flow6 { next header 58; };" | ./genrules.py
+echo "flow6 { next header 58; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan
 echo "$TEST_PKT" >> rules.h
 echo "#define TEST_EXP XDP_PASS" >> rules.h
 clang -std=c99 -fsanitize=address -pedantic -Wall -Wextra -Wno-pointer-arith -Wno-unused-variable -O0 -g xdp.c -o xdp && ./xdp
diff --git a/xdp.c b/xdp.c
index 26a12313097539af3477af65dece5d8945016d98..669d3ebfa365f13feee331258df4b4434e3cc5ab 100644 (file)
--- a/xdp.c
+++ b/xdp.c
@@ -104,8 +104,8 @@ struct tcphdr {
 #define MASK6(pfxlen) HTON128(~((((uint128_t)1) << (128 - pfxlen)) - 1))
 #define MASK6_OFFS(offs, pfxlen) HTON128((~((((uint128_t)1) << (128 - pfxlen)) - 1)) & ((((uint128_t)1) << (128 - offs)) - 1))
 
-// Note rules.h may also define PARSE_8021Q and REQ_8021Q
-// Note rules.h may also define PARSE_IHL
+// PARSE is used as a preprocessor flag to indicate parsing fields
+#define PARSE 42
 #include "rules.h"
 
 #define unlikely(a) __builtin_expect(a, 0)
@@ -143,7 +143,7 @@ int xdp_drop_prog(struct xdp_md *ctx)
                        return XDP_DROP;
                const struct ethhdr *const eth = (void*)(size_t)ctx->data;
 
-#ifdef PARSE_8021Q
+#if PARSE_8021Q == PARSE
                if (likely(eth->h_proto == BE16(ETH_P_8021Q))) {
                        if (unlikely((void*)(size_t)ctx->data + sizeof(struct ethhdr_vlan) > data_end))
                                return XDP_DROP;
@@ -156,6 +156,10 @@ int xdp_drop_prog(struct xdp_md *ctx)
 
                        eth_proto = eth_vlan->h_proto;
                        pktdata = (const void *)(long)ctx->data + sizeof(struct ethhdr_vlan);
+#else
+               if (unlikely(eth->h_proto == BE16(ETH_P_8021Q))) {
+                       return PARSE_8021Q;
+#endif
                } else {
 #ifdef REQ_8021Q
                        return XDP_DROP;
@@ -164,10 +168,6 @@ int xdp_drop_prog(struct xdp_md *ctx)
                        eth_proto = eth->h_proto;
 #endif
                }
-#else
-               pktdata = (const void *)(long)ctx->data + sizeof(struct ethhdr);
-               eth_proto = eth->h_proto;
-#endif
        }
 
        const struct tcphdr *tcp = NULL;
@@ -183,13 +183,14 @@ int xdp_drop_prog(struct xdp_md *ctx)
                        return XDP_DROP;
                ip = (struct iphdr*) pktdata;
 
-#ifdef PARSE_IHL
+#if PARSE_IHL == PARSE
                if (unlikely(ip->ihl < 5)) return XDP_DROP;
                l4hdr = pktdata + ip->ihl * 4;
 #else
-               if (ip->ihl != 5) return XDP_DROP;
+               if (ip->ihl != 5) return PARSE_IHL;
                l4hdr = pktdata + 5*4;
 #endif
+
                if (ip->protocol == IP_PROTO_TCP) {
                        if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end))
                                return XDP_DROP;