summaryrefslogtreecommitdiffstats
path: root/iptables-xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables-xml.c')
-rw-r--r--iptables-xml.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/iptables-xml.c b/iptables-xml.c
index ce3049c..71d5288 100644
--- a/iptables-xml.c
+++ b/iptables-xml.c
@@ -359,6 +359,18 @@ isTarget(char *arg)
|| strcmp((arg), "--goto") == 0));
}
+// is it a terminating target like -j ACCEPT, etc
+// (or I guess -j SNAT in nat table, but we don't check for that yet
+static int
+isTerminatingTarget(char *arg)
+{
+ return ((arg)
+ && (strcmp((arg), "ACCEPT") == 0
+ || strcmp((arg), "DROP") == 0
+ || strcmp((arg), "QUEUE") == 0
+ || strcmp((arg), "RETURN") == 0));
+}
+
// part=-1 means do conditions, part=1 means do rules, part=0 means do both
static void
do_rule_part(char *leveltag1, char *leveltag2, int part, int argc,
@@ -536,7 +548,19 @@ compareRules()
while (new < newargc && old < oldargc) {
if (isTarget(oldargv[old]) && isTarget(newargv[new])) {
- compare = 1;
+ /* if oldarg was a terminating action then it makes no sense
+ * to combine further actions into the same xml */
+ if (((strcmp((oldargv[old]), "-j") == 0
+ || strcmp((oldargv[old]), "--jump") == 0)
+ && old+1 < oldargc
+ && isTerminatingTarget(oldargv[old+1]) )
+ || strcmp((oldargv[old]), "-g") == 0
+ || strcmp((oldargv[old]), "--goto") == 0 ) {
+ /* Previous rule had terminating action */
+ compare = 0;
+ } else {
+ compare = 1;
+ }
break;
}
// break when old!=new