From ee6596e21c311c5fa83eb2b7ff08d87d8e98d266 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Thu, 1 Dec 2016 17:17:03 +0000 Subject: [PATCH] Run iptables commands in a loop in case they get "temporarily unavailable" exit --- net/veth.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/net/veth.go b/net/veth.go index d0c81d0b..a95553e8 100644 --- a/net/veth.go +++ b/net/veth.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "strings" + "syscall" "time" "github.com/coreos/go-iptables/iptables" @@ -272,19 +273,37 @@ func subnets(addrs []netlink.Addr) map[string]struct{} { return subnets } +func addNatRule(ipt *iptables.IPTables, rulespec ...string) error { + // Loop until we get an exit code other than "temporarily unavailable" + for { + if err := ipt.AppendUnique("nat", "WEAVE", rulespec...); err != nil { + if ierr, ok := err.(*iptables.Error); ok { + if status, ok := ierr.ExitError.Sys().(syscall.WaitStatus); ok { + // (magic exit code 4 found in iptables source code; undocumented) + if status.ExitStatus() == 4 { + continue + } + } + } + return err + } + return nil + } +} + func ExposeNAT(ipnet net.IPNet) error { ipt, err := iptables.New() if err != nil { return err } cidr := ipnet.String() - if err := ipt.AppendUnique("nat", "WEAVE", "-s", cidr, "-d", "224.0.0.0/4", "-j", "RETURN"); err != nil { + if err := addNatRule(ipt, "-s", cidr, "-d", "224.0.0.0/4", "-j", "RETURN"); err != nil { return err } - if err := ipt.AppendUnique("nat", "WEAVE", "-d", cidr, "!", "-s", cidr, "-j", "MASQUERADE"); err != nil { + if err := addNatRule(ipt, "-d", cidr, "!", "-s", cidr, "-j", "MASQUERADE"); err != nil { return err } - if err := ipt.AppendUnique("nat", "WEAVE", "-s", cidr, "!", "-d", cidr, "-j", "MASQUERADE"); err != nil { + if err := addNatRule(ipt, "-s", cidr, "!", "-d", cidr, "-j", "MASQUERADE"); err != nil { return err } return nil