Use iptables.InsertUnique() instead of iptables.Insert()

This commit is contained in:
Alex Stockinger 2022-09-15 09:43:53 +02:00
parent f62989fff7
commit 485e22e1b6
7 changed files with 39 additions and 21 deletions

2
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/campoy/embedmd v1.0.0 github.com/campoy/embedmd v1.0.0
github.com/containernetworking/cni v1.0.1 github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.1.1 github.com/containernetworking/plugins v1.1.1
github.com/coreos/go-iptables v0.6.0 github.com/coreos/go-iptables v0.6.1-0.20220901214115-d2b8608923d1
github.com/go-kit/kit v0.9.0 github.com/go-kit/kit v0.9.0
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a

4
go.sum
View File

@ -106,8 +106,8 @@ github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNG
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= github.com/coreos/go-iptables v0.6.1-0.20220901214115-d2b8608923d1 h1:zSiUKnogKeEwIIeUQP/WPH7m0BJ/IvW0VyL4muaauUY=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-iptables v0.6.1-0.20220901214115-d2b8608923d1/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=

View File

@ -46,7 +46,7 @@ type fakeClient struct {
var _ Client = &fakeClient{} var _ Client = &fakeClient{}
func (f *fakeClient) Insert(table, chain string, pos int, spec ...string) error { func (f *fakeClient) InsertUnique(table, chain string, pos int, spec ...string) error {
atomic.AddUint64(&f.calls, 1) atomic.AddUint64(&f.calls, 1)
exists, err := f.Exists(table, chain, spec...) exists, err := f.Exists(table, chain, spec...)
if err != nil { if err != nil {

View File

@ -84,7 +84,7 @@ func GetProtocol(ip net.IP) Protocol {
// Client represents any type that can administer iptables rules. // Client represents any type that can administer iptables rules.
type Client interface { type Client interface {
AppendUnique(table string, chain string, rule ...string) error AppendUnique(table string, chain string, rule ...string) error
Insert(table string, chain string, pos int, rule ...string) error InsertUnique(table, chain string, pos int, rule ...string) error
Delete(table string, chain string, rule ...string) error Delete(table string, chain string, rule ...string) error
Exists(table string, chain string, rule ...string) (bool, error) Exists(table string, chain string, rule ...string) (bool, error)
List(table string, chain string) ([]string, error) List(table string, chain string) ([]string, error)
@ -129,16 +129,7 @@ func NewIPv6Rule(table, chain string, spec ...string) Rule {
} }
func (r *rule) Prepend(client Client) error { func (r *rule) Prepend(client Client) error {
// TODO There's already a PR to implement InsertUnique() in go-iptables. Once that hopefully gets merged this should be replaced. if err := client.InsertUnique(r.table, r.chain, 1, r.spec...); err != nil {
// https://github.com/coreos/go-iptables/pull/92
exists, err := client.Exists(r.table, r.chain, r.spec...)
if err != nil {
return err
}
if exists {
return nil
}
if err := client.Insert(r.table, r.chain, 1, r.spec...); err != nil {
return fmt.Errorf("failed to add iptables rule: %v", err) return fmt.Errorf("failed to add iptables rule: %v", err)
} }
return nil return nil

View File

@ -51,13 +51,13 @@ func (m *metricsClientWrapper) AppendUnique(table string, chain string, rule ...
return m.client.AppendUnique(table, chain, rule...) return m.client.AppendUnique(table, chain, rule...)
} }
func (m *metricsClientWrapper) Insert(table string, chain string, pos int, rule ...string) error { func (m *metricsClientWrapper) InsertUnique(table, chain string, pos int, rule ...string) error {
m.operationCounter.With(prometheus.Labels{ m.operationCounter.With(prometheus.Labels{
"operation": "Insert", "operation": "InsertUnique",
"table": table, "table": table,
"chain": chain, "chain": chain,
}).Inc() }).Inc()
return m.client.Insert(table, chain, pos, rule...) return m.client.InsertUnique(table, chain, pos, rule...)
} }
func (m *metricsClientWrapper) Delete(table string, chain string, rule ...string) error { func (m *metricsClientWrapper) Delete(table string, chain string, rule ...string) error {

View File

@ -109,6 +109,7 @@ func Timeout(timeout int) option {
// For backwards compatibility, by default always uses IPv4 and timeout 0. // For backwards compatibility, by default always uses IPv4 and timeout 0.
// i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing // i.e. you can create an IPv6 IPTables using a timeout of 5 seconds passing
// the IPFamily and Timeout options as follow: // the IPFamily and Timeout options as follow:
//
// ip6t := New(IPFamily(ProtocolIPv6), Timeout(5)) // ip6t := New(IPFamily(ProtocolIPv6), Timeout(5))
func New(opts ...option) (*IPTables, error) { func New(opts ...option) (*IPTables, error) {
@ -185,6 +186,20 @@ func (ipt *IPTables) Insert(table, chain string, pos int, rulespec ...string) er
return ipt.run(cmd...) 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 // Append appends rulespec to specified table/chain
func (ipt *IPTables) Append(table, chain string, rulespec ...string) error { func (ipt *IPTables) Append(table, chain string, rulespec ...string) error {
cmd := append([]string{"-t", table, "-A", chain}, rulespec...) cmd := append([]string{"-t", table, "-A", chain}, rulespec...)
@ -219,6 +234,16 @@ func (ipt *IPTables) DeleteIfExists(table, chain string, rulespec ...string) err
return 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 // List rules in specified table/chain
func (ipt *IPTables) List(table, chain string) ([]string, error) { func (ipt *IPTables) List(table, chain string) ([]string, error) {
args := []string{"-t", table, "-S", chain} args := []string{"-t", table, "-S", chain}
@ -510,7 +535,9 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
syscall.Close(fmu.fd) syscall.Close(fmu.fd)
return err return err
} }
defer ul.Unlock() defer func() {
_ = ul.Unlock()
}()
} }
var stderr bytes.Buffer var stderr bytes.Buffer
@ -619,7 +646,7 @@ func iptablesHasWaitCommand(v1 int, v2 int, v3 int) bool {
return false 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 { func iptablesWaitSupportSecond(v1 int, v2 int, v3 int) bool {
if v1 > 1 { if v1 > 1 {
return true return true

2
vendor/modules.txt vendored
View File

@ -39,7 +39,7 @@ github.com/containernetworking/plugins/pkg/ns
github.com/containernetworking/plugins/pkg/utils/sysctl github.com/containernetworking/plugins/pkg/utils/sysctl
github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend
github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator
# github.com/coreos/go-iptables v0.6.0 # github.com/coreos/go-iptables v0.6.1-0.20220901214115-d2b8608923d1
## explicit; go 1.16 ## explicit; go 1.16
github.com/coreos/go-iptables/iptables github.com/coreos/go-iptables/iptables
# github.com/davecgh/go-spew v1.1.1 # github.com/davecgh/go-spew v1.1.1