diff --git a/iptables/iptables.go b/iptables/iptables.go index b058995..cbe09e9 100644 --- a/iptables/iptables.go +++ b/iptables/iptables.go @@ -194,7 +194,12 @@ func (ipt *IPTables) Exists(table, chain string, rulespec ...string) (bool, erro return ipt.existsForOldIptables(table, chain, rulespec) } - cmd := append([]string{"-t", table, "-C", chain}, rulespec...) + spec := rulespec + // truncate "-A " if present since -A collides with -C + if len(spec) > 1 && spec[0] == "-A" { + spec = spec[2:] + } + cmd := append([]string{"-t", table, "-C", chain}, spec...) err := ipt.run(cmd...) eerr, eok := err.(*Error) switch { @@ -255,7 +260,12 @@ func (ipt *IPTables) AppendUnique(table, chain string, rulespec ...string) error // Delete removes rulespec in specified table/chain func (ipt *IPTables) Delete(table, chain string, rulespec ...string) error { - cmd := append([]string{"-t", table, "-D", chain}, rulespec...) + spec := rulespec + // truncate "-A " if present since -A collides with -D + if len(spec) > 1 && spec[0] == "-A" { + spec = spec[2:] + } + cmd := append([]string{"-t", table, "-D", chain}, spec...) return ipt.run(cmd...) } diff --git a/iptables/iptables_test.go b/iptables/iptables_test.go index cfe4baf..4ecb04a 100644 --- a/iptables/iptables_test.go +++ b/iptables/iptables_test.go @@ -522,6 +522,22 @@ func runRulesTests(t *testing.T, ipt *IPTables) { t.Fatalf("DeleteIfExists failed for non-existing rule: %v", err) } + // Verify DeleteIfExists is compatible with rules returned from List + err = ipt.Append("filter", chain, "-s", address3, "-d", subnet2, "-j", "ACCEPT") + if err != nil { + t.Fatalf("Append failed: %v", err) + } + + rules, err = ipt.List("filter", chain) + if err != nil { + t.Fatalf("List failed: %v", err) + } + + err = ipt.DeleteIfExists("filter", chain, rules[0]) + if err != nil { + t.Fatalf("Delete failed: %v", err) + } + // Clear the chain that was created. err = ipt.ClearChain("filter", chain) if err != nil {