Run iptables commands in a loop

in case they get  "temporarily unavailable" exit
This commit is contained in:
Bryan Boreham committed 2016-12-05 11:11:20 +00:00
1 parent 46e4f047de
commit ee6596e21c
1 file changed
+22 -3
+22 -3
View File
@@ -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