Merge pull request #12318 from aarondav/best-effort-iptables-lock
Do our best not to invoke iptables concurrently if --wait is unsupported
This commit is contained in:
commit
88c612a22d
2 changed files with 48 additions and 2 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -25,8 +26,10 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
iptablesPath string
|
iptablesPath string
|
||||||
supportsXlock = false
|
supportsXlock = false
|
||||||
|
// used to lock iptables commands if xtables lock is not supported
|
||||||
|
bestEffortLock sync.Mutex
|
||||||
ErrIptablesNotFound = errors.New("Iptables not found")
|
ErrIptablesNotFound = errors.New("Iptables not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -289,6 +292,9 @@ func Raw(args ...string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
if supportsXlock {
|
if supportsXlock {
|
||||||
args = append([]string{"--wait"}, args...)
|
args = append([]string{"--wait"}, args...)
|
||||||
|
} else {
|
||||||
|
bestEffortLock.Lock()
|
||||||
|
defer bestEffortLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("%s, %v", iptablesPath, args)
|
logrus.Debugf("%s, %v", iptablesPath, args)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -168,6 +169,45 @@ func TestOutput(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConcurrencyWithWait(t *testing.T) {
|
||||||
|
RunConcurrencyTest(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConcurrencyNoWait(t *testing.T) {
|
||||||
|
RunConcurrencyTest(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs 10 concurrent rule additions. This will fail if iptables
|
||||||
|
// is actually invoked simultaneously without --wait.
|
||||||
|
// Note that if iptables does not support the xtable lock on this
|
||||||
|
// system, then allowXlock has no effect -- it will always be off.
|
||||||
|
func RunConcurrencyTest(t *testing.T, allowXlock bool) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
if !allowXlock && supportsXlock {
|
||||||
|
supportsXlock = false
|
||||||
|
defer func() { supportsXlock = true }()
|
||||||
|
}
|
||||||
|
|
||||||
|
ip := net.ParseIP("192.168.1.1")
|
||||||
|
port := 1234
|
||||||
|
dstAddr := "172.17.0.1"
|
||||||
|
dstPort := 4321
|
||||||
|
proto := "tcp"
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
err := natChain.Forward(Append, ip, port, proto, dstAddr, dstPort)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestCleanup(t *testing.T) {
|
func TestCleanup(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
var rules []byte
|
var rules []byte
|
||||||
|
|
Loading…
Reference in a new issue