Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure iptables initialization only happens once #1676

Merged
merged 1 commit into from
Mar 10, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 32 additions & 19 deletions iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ var (
bestEffortLock sync.Mutex
// ErrIptablesNotFound is returned when the rule is not found.
ErrIptablesNotFound = errors.New("Iptables not found")
probeOnce sync.Once
firewalldOnce sync.Once
initOnce sync.Once
)

// ChainInfo defines the iptables chain.
Expand Down Expand Up @@ -86,22 +85,32 @@ func initFirewalld() {
}
}

func detectIptables() {
path, err := exec.LookPath("iptables")
if err != nil {
return
}
iptablesPath = path
supportsXlock = exec.Command(iptablesPath, "--wait", "-L", "-n").Run() == nil
mj, mn, mc, err := GetVersion()
if err != nil {
logrus.Warnf("Failed to read iptables version: %v", err)
return
}
supportsCOpt = supportsCOption(mj, mn, mc)
}

func initIptables() {
probe()
initFirewalld()
detectIptables()
}

func initCheck() error {
initOnce.Do(initIptables)

if iptablesPath == "" {
probeOnce.Do(probe)
firewalldOnce.Do(initFirewalld)
path, err := exec.LookPath("iptables")
if err != nil {
return ErrIptablesNotFound
}
iptablesPath = path
supportsXlock = exec.Command(iptablesPath, "--wait", "-L", "-n").Run() == nil
mj, mn, mc, err := GetVersion()
if err != nil {
logrus.Warnf("Failed to read iptables version: %v", err)
return nil
}
supportsCOpt = supportsCOption(mj, mn, mc)
return ErrIptablesNotFound
}
return nil
}
Expand Down Expand Up @@ -373,7 +382,11 @@ func exists(native bool, table Table, chain string, rule ...string) bool {
table = Filter
}

initCheck()
if err := initCheck(); err != nil {
// The exists() signature does not allow us to return an error, but at least
// we can skip the (likely invalid) exec invocation.
return false
}

if supportsCOpt {
// if exit status is 0 then return true, the rule exists
Expand Down Expand Up @@ -456,9 +469,9 @@ func ExistChain(chain string, table Table) bool {
return false
}

// GetVersion reads the iptables version numbers
// GetVersion reads the iptables version numbers during initialization
func GetVersion() (major, minor, micro int, err error) {
out, err := Raw("--version")
out, err := exec.Command(iptablesPath, "--version").CombinedOutput()
if err == nil {
major, minor, micro = parseVersionNumbers(string(out))
}
Expand Down