From f3ab13623f45c42fd249098c247c81f44a6a63be Mon Sep 17 00:00:00 2001 From: OrangeBao Date: Thu, 7 Dec 2023 11:16:25 +0800 Subject: [PATCH] fix: support setting iptables mode Signed-off-by: OrangeBao --- go.mod | 2 +- go.sum | 4 +- pkg/clusterlink/network/iptables/iptables.go | 5 +- .../coreos/go-iptables/iptables/iptables.go | 85 ++++++++++++++++--- vendor/modules.txt | 2 +- 5 files changed, 83 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index a1e37983f..cadaa3ff4 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/bep/debounce v1.2.1 github.com/containerd/console v1.0.3 github.com/containerd/containerd v1.6.14 - github.com/coreos/go-iptables v0.6.0 + github.com/coreos/go-iptables v0.7.1-0.20231102141700-50d824baaa46 github.com/docker/docker v24.0.6+incompatible github.com/evanphx/json-patch v4.12.0+incompatible github.com/go-logr/logr v1.2.3 diff --git a/go.sum b/go.sum index d3d8936cd..2d14e37f2 100644 --- a/go.sum +++ b/go.sum @@ -643,8 +643,8 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= -github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.7.1-0.20231102141700-50d824baaa46 h1:AVVvARdGRuTtYO/DetrN9Z1G0kMbrqV7KLOH/J4byiM= +github.com/coreos/go-iptables v0.7.1-0.20231102141700-50d824baaa46/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= diff --git a/pkg/clusterlink/network/iptables/iptables.go b/pkg/clusterlink/network/iptables/iptables.go index 8209c6b25..8ce54f6da 100644 --- a/pkg/clusterlink/network/iptables/iptables.go +++ b/pkg/clusterlink/network/iptables/iptables.go @@ -22,6 +22,8 @@ limitations under the License. package iptables import ( + "os" + "github.com/coreos/go-iptables/iptables" "github.com/pkg/errors" ) @@ -60,7 +62,8 @@ func New(proto iptables.Protocol) (Interface, error) { return NewFunc() } - ipt, err := iptables.New(iptables.IPFamily(proto), iptables.Timeout(5)) + // IPTABLES_PATH: the path decision the model of iptable, /sbin/xtables-nft-multi => nf_tables + ipt, err := iptables.New(iptables.IPFamily(proto), iptables.Timeout(5), iptables.Path(os.Getenv("IPTABLES_PATH"))) if err != nil { return nil, errors.Wrap(err, "error creating IP tables") } diff --git a/vendor/github.com/coreos/go-iptables/iptables/iptables.go b/vendor/github.com/coreos/go-iptables/iptables/iptables.go index 85047e59d..6c5bbd707 100644 --- a/vendor/github.com/coreos/go-iptables/iptables/iptables.go +++ b/vendor/github.com/coreos/go-iptables/iptables/iptables.go @@ -45,14 +45,21 @@ func (e *Error) Error() string { return fmt.Sprintf("running %v: exit status %v: %v", e.cmd.Args, e.ExitStatus(), e.msg) } +var isNotExistPatterns = []string{ + "Bad rule (does a matching rule exist in that chain?).\n", + "No chain/target/match by that name.\n", + "No such file or directory", + "does not exist", +} + // IsNotExist returns true if the error is due to the chain or rule not existing func (e *Error) IsNotExist() bool { - if e.ExitStatus() != 1 { - return false + for _, str := range isNotExistPatterns { + if strings.Contains(e.msg, str) { + return true + } } - msgNoRuleExist := "Bad rule (does a matching rule exist in that chain?).\n" - msgNoChainExist := "No chain/target/match by that name.\n" - return strings.Contains(e.msg, msgNoRuleExist) || strings.Contains(e.msg, msgNoChainExist) + return false } // Protocol to differentiate between IPv4 and IPv6 @@ -105,23 +112,44 @@ func Timeout(timeout int) option { } } -// New creates a new IPTables configured with the options passed as parameter. -// For backwards compatibility, by default always uses IPv4 and timeout 0. +func Path(path string) option { + return func(ipt *IPTables) { + ipt.path = path + } +} + +// New creates a new IPTables configured with the options passed as parameters. +// Supported parameters are: +// +// IPFamily(Protocol) +// Timeout(int) +// Path(string) +// +// For backwards compatibility, by default New uses IPv4 and timeout 0. // i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing // the IPFamily and Timeout options as follow: +// // ip6t := New(IPFamily(ProtocolIPv6), Timeout(5)) func New(opts ...option) (*IPTables, error) { ipt := &IPTables{ proto: ProtocolIPv4, timeout: 0, + path: "", } for _, opt := range opts { opt(ipt) } - path, err := exec.LookPath(getIptablesCommand(ipt.proto)) + // if path wasn't preset through New(Path()), autodiscover it + cmd := "" + if ipt.path == "" { + cmd = getIptablesCommand(ipt.proto) + } else { + cmd = ipt.path + } + path, err := exec.LookPath(cmd) if err != nil { return nil, err } @@ -185,6 +213,26 @@ func (ipt *IPTables) Insert(table, chain string, pos int, rulespec ...string) er return ipt.run(cmd...) } +// Replace replaces rulespec to specified table/chain (in specified pos) +func (ipt *IPTables) Replace(table, chain string, pos int, rulespec ...string) error { + cmd := append([]string{"-t", table, "-R", chain, strconv.Itoa(pos)}, rulespec...) + return ipt.run(cmd...) +} + +// InsertUnique acts like Insert except that it won't insert a duplicate (no matter the position in the chain) +func (ipt *IPTables) InsertUnique(table, chain string, pos int, rulespec ...string) error { + exists, err := ipt.Exists(table, chain, rulespec...) + if err != nil { + return err + } + + if !exists { + return ipt.Insert(table, chain, pos, rulespec...) + } + + return nil +} + // Append appends rulespec to specified table/chain func (ipt *IPTables) Append(table, chain string, rulespec ...string) error { cmd := append([]string{"-t", table, "-A", chain}, rulespec...) @@ -219,6 +267,16 @@ func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) err return err } +// List rules in specified table/chain +func (ipt *IPTables) ListById(table, chain string, id int) (string, error) { + args := []string{"-t", table, "-S", chain, strconv.Itoa(id)} + rule, err := ipt.executeList(args) + if err != nil { + return "", err + } + return rule[0], nil +} + // List rules in specified table/chain func (ipt *IPTables) List(table, chain string) ([]string, error) { args := []string{"-t", table, "-S", chain} @@ -291,6 +349,11 @@ func (ipt *IPTables) Stats(table, chain string) ([][]string, error) { ipv6 := ipt.proto == ProtocolIPv6 + // Skip the warning if exist + if strings.HasPrefix(lines[0], "#") { + lines = lines[1:] + } + rows := [][]string{} for i, line := range lines { // Skip over chain name and field header @@ -510,7 +573,9 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error { syscall.Close(fmu.fd) return err } - defer ul.Unlock() + defer func() { + _ = ul.Unlock() + }() } var stderr bytes.Buffer @@ -619,7 +684,7 @@ func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool { return false } -//Checks if an iptablse version is after 1.6.0, when --wait support second +// Checks if an iptablse version is after 1.6.0, when --wait support second func iptablesWaitSupportSecond(v1 int, v2 int, v3 int) bool { if v1 > 1 { return true diff --git a/vendor/modules.txt b/vendor/modules.txt index c0d437cbe..6382b8dfd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -145,7 +145,7 @@ github.com/containerd/ttrpc # github.com/containerd/typeurl v1.0.2 ## explicit; go 1.13 github.com/containerd/typeurl -# github.com/coreos/go-iptables v0.6.0 +# github.com/coreos/go-iptables v0.7.1-0.20231102141700-50d824baaa46 ## explicit; go 1.16 github.com/coreos/go-iptables/iptables # github.com/coreos/go-semver v0.3.1