summaryrefslogtreecommitdiffstats
path: root/libxtables
diff options
context:
space:
mode:
authorSerhey Popovych <serhe.popovych@gmail.com>2018-03-07 11:10:43 +0200
committerFlorian Westphal <fw@strlen.de>2018-04-27 18:56:27 +0200
commit12a52ff9cc9944345204d3e429dd4414448fbcd2 (patch)
tree9867a87e5f90e7dbd804e64febf535188f9acf96 /libxtables
parent1197c5e35c16ab9a6be7d6a0c2283a213430ce16 (diff)
xtables: Fix rules print/save after iptables update
Updating iptables from 1.4.x to 1.6.x brokes rules print/save output and causes rules load after reboot to fail. Here is example from iptables-save(8) output after update: -A CHAIN1 -m set [unsupported revision] -j DROP -A CHAIN1 -m set [unsupported revision] -j DROP Similar output could be obtained via iptables -L CHAIN1. While issue reproduced with xt_set match it is not specific to any match or target module: it is related on how xtables handles revisions. In this particular case we have following situation: 1) Kernel supports revisions from 1 to 4. 2) Rules configured with iptables 1.4.x supporting only revisions from 1 to 3. Choosen highest possible revision 3. 3) Rules printed/saved with iptables 1.6.x supporting revisions from 1 to 4. 4) Xtables registers matches/targets with highest supported revision by the kernel. This is 4 in our case after update to iptables 1.6.x. 5) When printing/saving kernel submits match/target with revision it is configured (3), while iptables thinks that rules configured with highest supported (4). That's causes revision mismatch in during print and "[unsupported revision]" output. To fix this issue we now store all supported by kernel and xtables revisions in xt_matches/xt_targets list sorted in descending order. Introduce helper routines to find match/target with given revision and use them to find right revision to print submitted by kernel entry. Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com> Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'libxtables')
-rw-r--r--libxtables/xtables.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index ebdcc512..c5e86f38 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -709,6 +709,27 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
return ptr;
}
+struct xtables_match *
+xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
+ struct xtables_match *match, int revision)
+{
+ if (!match) {
+ match = xtables_find_match(name, tryload, NULL);
+ if (!match)
+ return NULL;
+ }
+
+ while (1) {
+ if (match->revision == revision)
+ return match;
+ match = match->next;
+ if (!match)
+ return NULL;
+ if (!extension_cmp(name, match->name, match->family))
+ return NULL;
+ }
+}
+
struct xtables_target *
xtables_find_target(const char *name, enum xtables_tryload tryload)
{
@@ -769,6 +790,27 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
return ptr;
}
+struct xtables_target *
+xtables_find_target_revision(const char *name, enum xtables_tryload tryload,
+ struct xtables_target *target, int revision)
+{
+ if (!target) {
+ target = xtables_find_target(name, tryload);
+ if (!target)
+ return NULL;
+ }
+
+ while (1) {
+ if (target->revision == revision)
+ return target;
+ target = target->next;
+ if (!target)
+ return NULL;
+ if (!extension_cmp(name, target->name, target->family))
+ return NULL;
+ }
+}
+
int xtables_compatible_revision(const char *name, uint8_t revision, int opt)
{
struct xt_get_revision rev;