From: Matt Corallo Date: Sun, 4 Apr 2021 00:00:51 +0000 (-0400) Subject: Make v6 frag parsing optional X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=bcf836638563135278efe7d0476ece5772ff465a;p=flowspec-xdp Make v6 frag parsing optional --- diff --git a/genrules.py b/genrules.py index 82b8d82..6c8411b 100755 --- a/genrules.py +++ b/genrules.py @@ -238,6 +238,7 @@ if (!( {ast.write("((((uint32_t)(ip6->flow_lbl[0] & 0xf)) << 2*8) | (((uint32_t) with open("rules.h", "w") as out: parse = argparse.ArgumentParser() parse.add_argument("--ihl", dest="ihl", required=True, choices=["drop-options","accept-options","parse-options"]) + parse.add_argument("--v6frag", dest="v6frag", required=True, choices=["drop-frags","ignore","parse-frags","ignore-parse-if-rule"]) 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:]) @@ -249,6 +250,13 @@ with open("rules.h", "w") as out: elif args.ihl == "parse-options": out.write("#define PARSE_IHL PARSE\n") + if args.v6frag == "drop-frags": + out.write("#define PARSE_V6_FRAG XDP_DROP\n") + elif args.v6frag == "ignore": + pass + elif args.v6frag == "parse-frags": + out.write("#define PARSE_V6_FRAG PARSE\n") + if args.vlan == "drop-vlan": out.write("#define PARSE_8021Q XDP_DROP\n") elif args.vlan == "accept-vlan": @@ -263,6 +271,7 @@ with open("rules.h", "w") as out: use_v4 = False use_v6 = False + use_v6_frags = False out.write("#define RULES \\\n") @@ -318,6 +327,8 @@ with open("rules.h", "w") as out: elif step.strip().startswith("label"): write_rule(flow_label_to_rule(step.strip()[6:])) elif step.strip().startswith("fragment"): + if proto == 6: + use_v6_frags = True write_rule(fragment_to_rule(proto, step.strip()[9:])) elif step.strip() == "": pass @@ -331,3 +342,6 @@ with open("rules.h", "w") as out: out.write("#define NEED_V4_PARSE\n") if use_v6: out.write("#define NEED_V6_PARSE\n") + if args.v6frag == "ignore-parse-if-rule": + if use_v6_frags: + out.write("#define PARSE_V6_FRAG PARSE\n") diff --git a/test.sh b/test.sh index f25fffa..a64c829 100755 --- 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 --ihl=accept-options --8021q=accept-vlan +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 --v6frag=ignore 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 --ihl=drop-options --8021q=drop-vlan +echo "flow4 { port = 4242; icmp code = 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 # Some port tests... -echo "flow4 { port = 4242 && = 56733; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan +echo "flow4 { port = 4242 && = 56733; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore 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 --ihl=accept-options --8021q=accept-vlan +echo "flow4 { port = 4242 || 1; sport = 56733 };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore 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 --ihl=drop-options --8021q=drop-vlan +echo "flow4 { port = 4242 && 1 };" | ./genrules.py --ihl=drop-options --8021q=drop-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 -echo "flow4 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan +echo "flow4 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 @@ -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 --ihl=accept-options --8021q=accept-vlan +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 --v6frag=ignore 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 --ihl=accept-options --8021q=accept-vlan +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 --v6frag=ignore 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 --ihl=drop-options --8021q=drop-vlan +echo "flow6 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 @@ -80,37 +80,37 @@ 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 --ihl=accept-options --8021q=parse-vlan +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 --v6frag=ignore 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 --ihl=drop-options --8021q=parse-vlan +echo "flow4 { icmp type 8; icmp code > 0; };" | ./genrules.py --ihl=drop-options --8021q=parse-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 -echo "flow4 { icmp type 9; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan +echo "flow4 { icmp type 9; };" | ./genrules.py --ihl=drop-options --8021q=parse-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 -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 "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 --v6frag=ignore 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 --ihl=accept-options --8021q=parse-vlan --require-8021q=4 +echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py --ihl=accept-options --8021q=parse-vlan --require-8021q=4 --v6frag=ignore 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 --ihl=drop-options --8021q=parse-vlan --require-8021q=3 +echo "flow4 { src 0.0.0.0/32; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan --require-8021q=3 --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 -echo "flow4 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=parse-vlan +echo "flow4 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=parse-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 @@ -138,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 --ihl=accept-options --8021q=accept-vlan +echo "flow6 { icmp type 129; icmp code 0; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore 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 --ihl=drop-options --8021q=drop-vlan +echo "flow6 { icmp code != 0; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 -echo "flow6 { tcp flags 0x0/0x0; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan +echo "flow6 { tcp flags 0x0/0x0; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 -echo "flow6 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan +echo "flow6 { port 42; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 -echo "flow6 { fragment is_fragment || first_fragment || last_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan +echo "flow6 { fragment is_fragment || first_fragment || last_fragment; };" | ./genrules.py --ihl=drop-options --8021q=drop-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 @@ -176,27 +176,43 @@ 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 --ihl=accept-options --8021q=accept-vlan +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 --v6frag=parse-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 "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 "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 --v6frag=parse-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 -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 "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 --v6frag=parse-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 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr? -echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan +echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=parse-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 +# Test the --v6frag options (ignore-parse-if-rule is tested below) +echo "flow6 { tcp flags 42/42; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=parse-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 + +echo "flow6 { tcp flags 42/42; };" | ./genrules.py --ihl=accept-options --8021q=accept-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 "flow6 { tcp flags 42/42; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore +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\x17\x10\x95\xe8\x96\x00\x0d\xb9\x50\x11\x4c\x86\xdd\x60\x0a" \ "\x18\xa7\x04\xd8\x2c\x3e\x26\x20\x00\x6e\xa0\x07\x02\x33\x00\x00" \ @@ -282,34 +298,50 @@ 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 --ihl=accept-options --8021q=accept-vlan +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 --v6frag=parse-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 "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 "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 --v6frag=parse-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 -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 "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 --v6frag=parse-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 -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 "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 --v6frag=parse-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 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr? -echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan +echo "flow6 { next header 44; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=parse-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 #TODO Is nextheader frag correct to match on here? Should we support matching on any nexthdr? -echo "flow6 { next header 58; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan +echo "flow6 { next header 58; };" | ./genrules.py --ihl=drop-options --8021q=drop-vlan --v6frag=parse-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 accept-parse-if-rule +echo "flow6 { icmp code 0; icmp type 128; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore-parse-if-rule +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 { icmp code 0; icmp type 128; fragment is_fragment; };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore-parse-if-rule +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; icmp type 128; fragment !is_fragment };" | ./genrules.py --ihl=accept-options --8021q=accept-vlan --v6frag=ignore-parse-if-rule 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 b93b169..10ed78b 100644 --- a/xdp.c +++ b/xdp.c @@ -221,16 +221,21 @@ int xdp_drop_prog(struct xdp_md *ctx) l4hdr = pktdata + 40; - uint8_t v6nexthdr; + uint8_t v6nexthdr = ip6->nexthdr; +#ifdef PARSE_V6_FRAG +#if PARSE_V6_FRAG == PARSE if (ip6->nexthdr == IP6_PROTO_FRAG) { if (unlikely(l4hdr + sizeof(struct ip6_fraghdr) > data_end)) return XDP_DROP; frag6 = (struct ip6_fraghdr*) l4hdr; l4hdr = l4hdr + sizeof(struct ip6_fraghdr); v6nexthdr = frag6->nexthdr; - } else { - v6nexthdr = ip6->nexthdr; +#else + if (unlikely(ip6->nexthdr == IP6_PROTO_FRAG)) { + return PARSE_V6_FRAG; +#endif } +#endif if (v6nexthdr == IP_PROTO_TCP) { if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end))