2d96ec74c9c0e0b05cfe842cae19491cb9d1f58b
[flowspec-xdp] / README.md
1 FlowSpec -> XDP Conversion Utility
2 ==================================
3
4 This utility allows you to convert flowspec rules (extracted from a local BIRD instance with birdc)
5 to an XDP program. It currently supports the entire flowspec match grammar, rate limits, traffic
6 action packet match counting (sample bit) and terminal bit, and traffic marking. The redirect
7 community is not supported.
8
9 Note that correctly sorting rules is *not* implemented as it requires implementing the flowspec
10 wire serialization format and it may better be done inside bird/birdc. Thus, be vary careful using
11 the terminal bit in the traffict action community.
12
13 In addition to the communities specified in RFC 8955, two additional communities are supported which
14 provide rate-limiting on a per-source basis. When the upper two bytes in an extended community are
15 0x8306 (rate in bytes) or 0x830c (rate in packets), we rate limit the same as 0x8006 or 0x800c
16 except that the rate limit is applied per source address. The encoding mirrors the non-per-source
17 encoding in that the last 4 octets are the floating-point rate limit. Instead of a 2 octet
18 AS/ignored value, the third octet is the maximum number of source IPs tracked (plus one, times 1024)
19 and the fourth octet is a prefix length mask, which is applied to the source IP before rate-limiting.
20
21 `install.sh` provides a simple example script which will compile and install a generated XDP program
22 from the rules in bird's `flowspec4` and `flowspec6` routing tables. It will drop any packets which
23 match any flowspec filter.
24
25 `genrules.py` will accept birdc output on stdin and generate a rules.h file which is included in
26 xdp.c to check individual rules. The specific behavior of some less-common parsing options can be
27 controlled by parameters to `genrules.py` -
28  * --8021q can be either "drop-vlan", "accept-vlan" or "parse-vlan" to either drop all traffic with
29    a VLAN tag, accept all traffic with a VLAN tag (without comparing it against any flowspec rules),
30    or parse VLAN traffic and compare it against flowspec rules just like any other traffic.
31  * If --8021q is set to "parse-vlan", --require-8021q can be set to a specific VLAN tag, and all
32    traffic with different VLAN tags is dropped.
33  * --ihl can be set to "drop-options", "accept-options", or "parse-options" to drop all traffic with
34    extra IPv4 option fields, accept all traffic with extra IPv4 options fields (without comparing it
35    to any flowspec rules), or parse IPv4 traffic with option fields like normal.
36  * --v6frag can be set to "drop-frags","ignore","parse-frags","ignore-parse-if-rule" to:
37    * drop all IPv6 fragments,
38    * ignore IPv6 fragments, matching only the IPv6 header but no ICMP/TCP/UDP options,
39    * parse IPv6 fragments, matching ICMP/TCP/UDP options if relevant (eg often only in the first
40      fragment), or
41    * ignore IPv6 fragments as above, unless a flow6 rule specifies the "fragment" keyword, in which
42      case parse all IPv6 fragments as above for all rules.
43
44 Note that if all of the above options are set to their "drop" or "ignore" variants, the parsing can
45 avoid all offset calculation, using static offsets for all fields.
46
47 Drop counts are tracked in XDP per-CPU arrays, and can be viewed with `dropcount.sh`.
48
49 Note that rate limiting is currently tracked under a single per-rule spinlock, which may be a
50 bottleneck for high speed NICs with many RX queues. Adapting this to per-RX-queue/CPU limits would
51 be trivial but is left as a future project.