From 3ed103c5434b5332f33a45e5008cac4d789e010f Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Thu, 10 Jul 2014 00:22:01 -0400 Subject: [PATCH] Fix duplicate iptables rules If iptables version is < 1.4.11, try to delete the rule vs. checking if it exists. Fixes #6831. Docker-DCO-1.1-Signed-off-by: Jessica Frazelle (github: jfrazelle) --- iptables/iptables.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/iptables/iptables.go b/iptables/iptables.go index 748b69a..88d8b5f 100644 --- a/iptables/iptables.go +++ b/iptables/iptables.go @@ -6,6 +6,7 @@ import ( "net" "os" "os/exec" + "regexp" "strconv" "strings" ) @@ -141,10 +142,27 @@ func (c *Chain) Remove() error { // Check if an existing rule exists func Exists(args ...string) bool { - if _, err := Raw(append([]string{"-C"}, args...)...); err != nil { - return false + // iptables -C, --check option was added in v.1.4.11 + // http://ftp.netfilter.org/pub/iptables/changes-iptables-1.4.11.txt + + // try -C + // if exit status is 0 then return true, the rule exists + if _, err := Raw(append([]string{"-C"}, args...)...); err == nil { + return true } - return true + + // parse iptables-save for the rule + rule := strings.Replace(strings.Join(args, " "), "-t nat ", "", -1) + existingRules, _ := exec.Command("iptables-save").Output() + + // regex to replace ips in rule + // because MASQUERADE rule will not be exactly what was passed + re := regexp.MustCompile(`[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}`) + + return strings.Contains( + re.ReplaceAllString(string(existingRules), "?"), + re.ReplaceAllString(rule, "?"), + ) } func Raw(args ...string) ([]byte, error) {