BACKPORT: netfilter: x_tables: speed up jump target validation

The dummy ruleset I used to test the original validation change was broken,
most rules were unreachable and were not tested by mark_source_chains().

In some cases rulesets that used to load in a few seconds now require
several minutes.

sample ruleset that shows the behaviour:

echo "*filter"
for i in $(seq 0 100000);do
        printf ":chain_%06x - [0:0]\n" $i
for i in $(seq 0 100000);do
   printf -- "-A INPUT -j chain_%06x\n" $i
   printf -- "-A INPUT -j chain_%06x\n" $i
   printf -- "-A INPUT -j chain_%06x\n" $i

[ pipe result into iptables-restore ]

This ruleset will be about 74mbyte in size, with ~500k searches
though all 500k[1] rule entries. iptables-restore will take forever
(gave up after 10 minutes)

Instead of always searching the entire blob for a match, fill an
array with the start offsets of every single ipt_entry struct,
then do a binary search to check if the jump target is present or not.

After this change ruleset restore times get again close to what one
gets when reverting 36472341017529e (~3 seconds on my workstation).

[1] every user-defined rule gets an implicit RETURN, so we get
300k jumps + 100k userchains + 100k returns -> 500k rule entries

TEST="emerge-lakitu sys-kernel/lakitu-kernel-4_4" succeeds.

Fixes: 36472341017529e ("netfilter: x_tables: validate targets of jumps")
Reported-by: Jeff Wu <>
Signed-off-by: Florian Westphal <>
Signed-off-by: Pablo Neira Ayuso <>
(cherry picked from commit f4dc77713f80 ("netfilter: x_tables: speed up
jump target validation"))
[backport: duprintf() statements in ip_tables.c, arp_tables.c, and
ip6_tables.c, removed in upstream version, result in context conflicts]
Signed-off-by: Amey Deshpande <>

Change-Id: I506779e6e782b6781b7e8b11720b3eeeff1df914
(cherry picked from commit 47439abcd286e86a3506315e243bc06ce43a9e03)
Reviewed-by: Guenter Roeck <>
Commit-Queue: Amey Deshpande <>
Tested-by: Amey Deshpande <>
5 files changed