We learned in Jool issue #214 that ip6tables can be a bit of a bottleneck when it's heavily populated.
I also conjecture that most ip6tables configurations will look somewhat like this when paired with Jool:
ip6tables -t mangle -A PREROUTING --source 2001:db8::1 -j MARK --set-mark 1
ip6tables -t mangle -A PREROUTING --source 2001:db8::2 -j MARK --set-mark 2
ip6tables -t mangle -A PREROUTING --source 2001:db8::3 -j MARK --set-mark 3
...
ip6tables -t mangle -A PREROUTING --source 2001:db8::<N> -j MARK --set-mark <N>
MARKSRCRANGE is an ip6tables plugin target that condenses, and therefore optimizes, this configuration.
For example, this:
ip6tables -t mangle -A PREROUTING --source 2001:db8::/120 -j MARKSRCRANGE
Is equivalent to this:
ip6tables -t mangle -A PREROUTING --source 2001:db8::0 -j MARK --set-mark 0
ip6tables -t mangle -A PREROUTING --source 2001:db8::1 -j MARK --set-mark 1
ip6tables -t mangle -A PREROUTING --source 2001:db8::2 -j MARK --set-mark 2
...
ip6tables -t mangle -A PREROUTING --source 2001:db8::FF -j MARK --set-mark 255
And this:
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:a00::/56 -j MARKSRCRANGE --mark-offset 0 --sub-prefix-len 64
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:b00::/56 -j MARKSRCRANGE --mark-offset 256 --sub-prefix-len 64
Is the same as this:
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:a00::/64 -j MARK --set-mark 0
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:a01::/64 -j MARK --set-mark 1
...
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:aff::/64 -j MARK --set-mark 255
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:b00::/64 -j MARK --set-mark 256
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:b01::/64 -j MARK --set-mark 257
...
ip6tables -t mangle -A PREROUTING --source 2001:db8:0:bff::/64 -j MARK --set-mark 511
Kbuild only and no configuration script yet; sorry.
# apt-get install iptables-dev
$ cd src
$ make
# make install
ip6tables -t mangle -A PREROUTING --source <PREFIX> -j MARKSRCRANGE [--mark-offset <OFFSET>] [--sub-prefix-len <SUB>]
Will distribute longer sub-prefixes of length /<SUB> taken from the shorter <PREFIX> across marks <OFFSET> through <OFFSET> + [number of /<SUB> prefixes in <PREFIX>] - 1. (<PREFIX> is an IPv6 CIDR prefix, <OFFSET> is an unsigned 32-bit integer that defaults to zero and <SUB> is a prefix length that defaults to 128.)
The table must be mangle and the chain must be PREROUTING, otherwise ip6tables will be unable to find MARKSRCRANGE. You should be able to include more match logic but --source must be present. If you get cryptic errors, try running dmesg | tail.
This is otherwise standard ip6tables fare. You can, for example, see your rules via the usual ip6tables -t mangle -L PREROUTING:
# ip6tables -t mangle -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARKSRCRANGE all 2001:db8::/112 anywhere marks 0-65535 (0x0-0xffff) /112/128
MARKSRCRANGE all 2001:db8:1::/112 anywhere marks 65536-131071 (0x10000-0x1ffff) /112/128
MARKSRCRANGE all 2001:db8:2::/112 anywhere marks 524288-589823 (0x80000-0x8ffff) /112/128
Particularly since --sub-prefix-len can complicate things, you can find in the test folder the source code for a small binary that can help you review the marks your rules are expected to generate.
All the binary does is print the mark/prefix combinations that will result from a MARKSRCRANGE rule. You must invoke it using the same --source, --mark-offset and --sub-prefix-len arguments from your rule. For example,
$ cd <MARKSRCRANGE>/test
$ make
$ ./test.out --source 2001:db8:1234:5600::/56 --mark-offset 256 --sub-prefix-len 64
Mark Prefix
256 0x100 2001:db8:1234:5600::/64
257 0x101 2001:db8:1234:5601::/64
258 0x102 2001:db8:1234:5602::/64
259 0x103 2001:db8:1234:5603::/64
260 0x104 2001:db8:1234:5604::/64
...
510 0x1fe 2001:db8:1234:56fe::/64
511 0x1ff 2001:db8:1234:56ff::/64
The above output states that a rule that would use the given configuration should mark clients matching 2001:db8:1234:5600::/64 as 256, clients matching 2001:db8:1234:5601::/64 as 257, etc.
A more involved and bulletproof method to tell whether your rules are doing what you want is to enable debugging on the kernel module:
$ # Obtain a debugging-enabled binary.
$ cd <MARKSRCRANGE>/mod
$ make MARKSRCRANGE_FLAGS=-DDEBUG
$ sudo make install
$
$ # Make sure the old binary will not interfere.
$ sudo ip6tables -t mangle -F
$ sudo modprobe -r xt_MARKSRCRANGE
$
$ # Reinsert your rules, since you just removed them.
$ sudo ip6tables -t mangle -A PREROUTING -j MARKSRCRANGE ...
$
$ # Read the kernel log.
$ dmesg -t
MARKSRCRANGE: Packet from 2001:db8:1234:560f::2 was marked 15.
MARKSRCRANGE: Packet from 2001:db8:1234:560f::2 was marked 15.
MARKSRCRANGE: Packet from 2001:db8:1234:56ff::2 was marked 255.
MARKSRCRANGE: Packet from 2001:db8:1234:56ff::2 was marked 255.
Remember to revert this when you're done testing to avoid heavy logging. (You will have to ip6tables -F and modprobe -r the module again!)
- Test in environments other than Ubuntu 14.04, kernel 3.13.
- Add configuration script and DKMS.