func (runner *runner) FlushChain(table Table, chain Chain) error {
	fullArgs := makeFullArgs(table, chain)
	runner.mu.Lock()
	defer runner.mu.Unlock()
	out, err := runner.run(opFlushChain, fullArgs)
	if err != nil {
		return fmt.Errorf("error flushing chain %q: %v: %s", chain, err, out)
	}
	return nil
}
FlushChain is part of Interface.
package iptables
import (
	"bytes"
	"context"
	"fmt"
	"regexp"
	"strings"
	"sync"
	"time"
	godbus "github.com/godbus/dbus"
	"github.com/golang/glog"
	"k8s.io/apimachinery/pkg/util/sets"
	utiltrace "k8s.io/apiserver/pkg/util/trace"
	utildbus "k8s.io/kubernetes/pkg/util/dbus"
	utilversion "k8s.io/kubernetes/pkg/util/version"
	utilexec "k8s.io/utils/exec"
)
type RulePosition string
const (
	Prepend RulePosition = "-I"
	Append  RulePosition = "-A"
)
type Interface interface {
	GetVersion() (string, error)
	EnsureChain(table Table, chain Chain) (bool, error)
	FlushChain(table Table, chain Chain) error
	DeleteChain(table Table, chain Chain) error
	EnsureRule(position RulePosition, table Table, chain Chain, args ...string) (bool, error)
	DeleteRule(table Table, chain Chain, args ...string) error
	IsIpv6() bool
	SaveInto(table Table, buffer *bytes.Buffer) error
	Restore(table Table, data []byte, flush FlushFlag, counters RestoreCountersFlag) error
	RestoreAll(data []byte, flush FlushFlag, counters RestoreCountersFlag) error
	AddReloadFunc(reloadFunc func())
	Destroy()
}
type Protocol byte
const (
	ProtocolIpv4 Protocol = iota + 1
	ProtocolIpv6
)
type Table string
const (
	TableNAT    Table = "nat"
	TableFilter Table = "filter"
	TableMangle Table = "mangle"
)
type Chain string
const (
	ChainPostrouting Chain = "POSTROUTING"
	ChainPrerouting  Chain = "PREROUTING"
	ChainOutput      Chain = "OUTPUT"
	ChainInput       Chain = "INPUT"
	ChainForward     Chain = "FORWARD"
)
const (
	cmdIPTablesSave     string = "iptables-save"
	cmdIPTablesRestore  string = "iptables-restore"
	cmdIPTables         string = "iptables"
	cmdIP6TablesRestore string = "ip6tables-restore"
	cmdIP6TablesSave    string = "ip6tables-save"
	cmdIP6Tables        string = "ip6tables"
)
type RestoreCountersFlag bool
const RestoreCounters RestoreCountersFlag = true
const NoRestoreCounters RestoreCountersFlag = false
type FlushFlag bool
const FlushTables FlushFlag = true
const NoFlushTables FlushFlag = false
const MinCheckVersion = "1.4.11"
const WaitMinVersion = "1.4.20"
const WaitSecondsMinVersion = "1.4.22"
const WaitString = "-w"
const WaitSecondsValue = "5"
const LockfilePath16x = "/run/xtables.lock"
type runner struct {
	mu              sync.Mutex
	exec            utilexec.Interface
	dbus            utildbus.Interface
	protocol        Protocol
	hasCheck        bool
	hasListener     bool
	waitFlag        []string
	restoreWaitFlag []string
	lockfilePath    string
	reloadFuncs []func()
	signal      chan *godbus.Signal
}
func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol, lockfilePath string) Interface {
	vstring, err := getIPTablesVersionString(exec, protocol)
	if err != nil {
		glog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err)
		vstring = MinCheckVersion
	}
	if lockfilePath == "" {
		lockfilePath = LockfilePath16x
	}
	runner := &runner{
		exec:            exec,
		dbus:            dbus,
		protocol:        protocol,
		hasCheck:        getIPTablesHasCheckCommand(vstring),
		hasListener:     false,
		waitFlag:        getIPTablesWaitFlag(vstring),
		restoreWaitFlag: getIPTablesRestoreWaitFlag(exec, protocol),
		lockfilePath:    lockfilePath,
	}
	return runner
}
func New(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol) Interface {
	return newInternal(exec, dbus, protocol, "")
}
func (runner *runner) Destroy() {
	if runner.signal != nil {
		runner.signal <- nil
	}
}
const (
	firewalldName      = "org.fedoraproject.FirewallD1"
	firewalldPath      = "/org/fedoraproject/FirewallD1"
	firewalldInterface = "org.fedoraproject.FirewallD1"
)
func (runner *runner) connectToFirewallD() {
	bus, err := runner.dbus.SystemBus()
	if err != nil {
		glog.V(1).Infof("Could not connect to D-Bus system bus: %s", err)
		return
	}
	runner.hasListener = true
	rule := fmt.Sprintf("type='signal',sender='%s',path='%s',interface='%s',member='Reloaded'", firewalldName, firewalldPath, firewalldInterface)
	bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule)
	rule = fmt.Sprintf("type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus',sender='org.freedesktop.DBus',arg0='%s'", firewalldName)
	bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule)
	runner.signal = make(chan *godbus.Signal, 10)
	bus.Signal(runner.signal)
	go runner.dbusSignalHandler(bus)
}
func (runner *runner) GetVersion() (string, error) {
	return getIPTablesVersionString(runner.exec, runner.protocol)
}
func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) {
	fullArgs := makeFullArgs(table, chain)
	runner.mu.Lock()
	defer runner.mu.Unlock()
	out, err := runner.run(opCreateChain, fullArgs)
	if err != nil {
		if ee, ok := err.(utilexec.ExitError); ok {
			if ee.Exited() && ee.ExitStatus() == 1 {
				return true, nil
			}
		}
		return false, fmt.Errorf("error creating chain %q: %v: %s", chain, err, out)
	}
	return false, nil
}