From 3afc528c888df88f405c5fa2db27c9abf3ea5137 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 13 Feb 2017 14:37:16 +0000 Subject: [PATCH 1/2] Reference-count ipset entries --- npc/ipset/ipset.go | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/npc/ipset/ipset.go b/npc/ipset/ipset.go index 5fbdb3db..38b343cd 100644 --- a/npc/ipset/ipset.go +++ b/npc/ipset/ipset.go @@ -27,10 +27,11 @@ type Interface interface { } type ipset struct { + refCount } func New() Interface { - return &ipset{} + return &ipset{refCount: newRefCount()} } func (i *ipset) Create(ipsetName Name, ipsetType Type) error { @@ -38,10 +39,16 @@ func (i *ipset) Create(ipsetName Name, ipsetType Type) error { } func (i *ipset) AddEntry(ipsetName Name, entry string) error { + if i.inc(ipsetName, entry) > 1 { // already in the set + return nil + } return doExec("add", string(ipsetName), entry) } func (i *ipset) DelEntry(ipsetName Name, entry string) error { + if i.dec(ipsetName, entry) > 0 { // still needed + return nil + } return doExec("del", string(ipsetName), entry) } @@ -67,3 +74,30 @@ func doExec(args ...string) error { } return nil } + +// Reference-counting +type key struct { + ipsetName Name + entry string +} + +// note no locking is required as all operations are serialised in the controller +type refCount struct { + ref map[key]int +} + +func newRefCount() refCount { + return refCount{ref: make(map[key]int)} +} + +func (rc *refCount) inc(ipsetName Name, entry string) int { + k := key{ipsetName, entry} + rc.ref[k]++ + return rc.ref[k] +} + +func (rc *refCount) dec(ipsetName Name, entry string) int { + k := key{ipsetName, entry} + rc.ref[k]-- + return rc.ref[k] +} From 201321f3909e4c66cf0905140cbe45100f43b5cd Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 14 Feb 2017 10:36:18 +0000 Subject: [PATCH 2/2] Remove refcounts on destroy and flush --- npc/ipset/ipset.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/npc/ipset/ipset.go b/npc/ipset/ipset.go index 38b343cd..3a27327b 100644 --- a/npc/ipset/ipset.go +++ b/npc/ipset/ipset.go @@ -53,18 +53,22 @@ func (i *ipset) DelEntry(ipsetName Name, entry string) error { } func (i *ipset) Flush(ipsetName Name) error { + i.removeSet(ipsetName) return doExec("flush", string(ipsetName)) } func (i *ipset) FlushAll() error { + i.refCount = newRefCount() return doExec("flush") } func (i *ipset) Destroy(ipsetName Name) error { + i.removeSet(ipsetName) return doExec("destroy", string(ipsetName)) } func (i *ipset) DestroyAll() error { + i.refCount = newRefCount() return doExec("destroy") } @@ -101,3 +105,11 @@ func (rc *refCount) dec(ipsetName Name, entry string) int { rc.ref[k]-- return rc.ref[k] } + +func (rc *refCount) removeSet(ipsetName Name) { + for k := range rc.ref { + if k.ipsetName == ipsetName { + delete(rc.ref, k) + } + } +}