fix: adjust for the review and comments

This commit is contained in:
Auztin Zhai 2023-12-08 04:23:35 -05:00
parent 50b37861c0
commit 352d70194a
3 changed files with 62 additions and 75 deletions

4
go.sum
View File

@ -6,8 +6,6 @@ github.com/mdlayher/netlink v1.7.1 h1:FdUaT/e33HjEXagwELR8R3/KL1Fq5x3G5jgHLp/BTm
github.com/mdlayher/netlink v1.7.1/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ= github.com/mdlayher/netlink v1.7.1/go.mod h1:nKO5CSjE/DJjVhk/TNp6vCE1ktVxEA8VEh8drhZzxsQ=
github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw= github.com/mdlayher/socket v0.4.0 h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=
github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc= github.com/mdlayher/socket v0.4.0/go.mod h1:xxFqz5GRCUN3UEOm9CZqEJsAbe1C8OwSK46NlmWuVoc=
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4= github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@ -28,8 +26,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -46,57 +46,50 @@ const (
) )
var ( var (
monitorFlags map[MonitorAction]map[MonitorObject]uint32 monitorFlags = map[MonitorAction]map[MonitorObject]uint32{
MonitorActionAny: {
MonitorObjectAny: 0xffffffff,
MonitorObjectTables: 1<<unix.NFT_MSG_NEWTABLE | 1<<unix.NFT_MSG_DELCHAIN,
MonitorObjectChains: 1<<unix.NFT_MSG_NEWCHAIN | 1<<unix.NFT_MSG_DELCHAIN,
MonitorObjectRules: 1<<unix.NFT_MSG_NEWRULE | 1<<unix.NFT_MSG_DELRULE,
MonitorObjectSets: 1<<unix.NFT_MSG_NEWSET | 1<<unix.NFT_MSG_DELSET,
MonitorObjectElements: 1<<unix.NFT_MSG_NEWSETELEM | 1<<unix.NFT_MSG_DELSETELEM,
MonitorObjectRuleset: 1<<unix.NFT_MSG_NEWTABLE | 1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_NEWCHAIN | 1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_NEWRULE | 1<<unix.NFT_MSG_DELRULE |
1<<unix.NFT_MSG_NEWSET | 1<<unix.NFT_MSG_DELSET |
1<<unix.NFT_MSG_NEWSETELEM | 1<<unix.NFT_MSG_DELSETELEM |
1<<unix.NFT_MSG_NEWOBJ | 1<<unix.NFT_MSG_DELOBJ,
},
MonitorActionNew: {
MonitorObjectAny: 1<<unix.NFT_MSG_NEWTABLE |
1<<unix.NFT_MSG_NEWCHAIN |
1<<unix.NFT_MSG_NEWRULE |
1<<unix.NFT_MSG_NEWSET |
1<<unix.NFT_MSG_NEWSETELEM,
MonitorObjectTables: 1 << unix.NFT_MSG_NEWTABLE,
MonitorObjectChains: 1 << unix.NFT_MSG_NEWCHAIN,
MonitorObjectRules: 1 << unix.NFT_MSG_NEWRULE,
MonitorObjectSets: 1 << unix.NFT_MSG_NEWSET,
MonitorObjectRuleset: 1<<unix.NFT_MSG_NEWTABLE |
1<<unix.NFT_MSG_NEWCHAIN |
1<<unix.NFT_MSG_NEWRULE |
1<<unix.NFT_MSG_NEWSET |
1<<unix.NFT_MSG_NEWSETELEM |
1<<unix.NFT_MSG_NEWOBJ,
},
MonitorActionDel: {
MonitorObjectAny: 1<<unix.NFT_MSG_DELTABLE |
1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_DELRULE |
1<<unix.NFT_MSG_DELSET |
1<<unix.NFT_MSG_DELSETELEM |
1<<unix.NFT_MSG_DELOBJ,
},
}
monitorFlagsInitOnce sync.Once monitorFlagsInitOnce sync.Once
) )
// A lazy init function to define flags.
func lazyInit() {
monitorFlagsInitOnce.Do(func() {
monitorFlags = map[MonitorAction]map[MonitorObject]uint32{
MonitorActionAny: {
MonitorObjectAny: 0xffffffff,
MonitorObjectTables: 1<<unix.NFT_MSG_NEWTABLE | 1<<unix.NFT_MSG_DELCHAIN,
MonitorObjectChains: 1<<unix.NFT_MSG_NEWCHAIN | 1<<unix.NFT_MSG_DELCHAIN,
MonitorObjectRules: 1<<unix.NFT_MSG_NEWRULE | 1<<unix.NFT_MSG_DELRULE,
MonitorObjectSets: 1<<unix.NFT_MSG_NEWSET | 1<<unix.NFT_MSG_DELSET,
MonitorObjectElements: 1<<unix.NFT_MSG_NEWSETELEM | 1<<unix.NFT_MSG_DELSETELEM,
MonitorObjectRuleset: 1<<unix.NFT_MSG_NEWTABLE | 1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_NEWCHAIN | 1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_NEWRULE | 1<<unix.NFT_MSG_DELRULE |
1<<unix.NFT_MSG_NEWSET | 1<<unix.NFT_MSG_DELSET |
1<<unix.NFT_MSG_NEWSETELEM | 1<<unix.NFT_MSG_DELSETELEM |
1<<unix.NFT_MSG_NEWOBJ | 1<<unix.NFT_MSG_DELOBJ,
},
MonitorActionNew: {
MonitorObjectAny: 1<<unix.NFT_MSG_NEWTABLE |
1<<unix.NFT_MSG_NEWCHAIN |
1<<unix.NFT_MSG_NEWRULE |
1<<unix.NFT_MSG_NEWSET |
1<<unix.NFT_MSG_NEWSETELEM,
MonitorObjectTables: 1 << unix.NFT_MSG_NEWTABLE,
MonitorObjectChains: 1 << unix.NFT_MSG_NEWCHAIN,
MonitorObjectRules: 1 << unix.NFT_MSG_NEWRULE,
MonitorObjectSets: 1 << unix.NFT_MSG_NEWSET,
MonitorObjectRuleset: 1<<unix.NFT_MSG_NEWTABLE |
1<<unix.NFT_MSG_NEWCHAIN |
1<<unix.NFT_MSG_NEWRULE |
1<<unix.NFT_MSG_NEWSET |
1<<unix.NFT_MSG_NEWSETELEM |
1<<unix.NFT_MSG_NEWOBJ,
},
MonitorActionDel: {
MonitorObjectAny: 1<<unix.NFT_MSG_DELTABLE |
1<<unix.NFT_MSG_DELCHAIN |
1<<unix.NFT_MSG_DELRULE |
1<<unix.NFT_MSG_DELSET |
1<<unix.NFT_MSG_DELSETELEM |
1<<unix.NFT_MSG_DELOBJ,
},
}
})
}
type EventType int type EventType int
const ( const (
@ -131,12 +124,13 @@ type Monitor struct {
object MonitorObject object MonitorObject
monitorFlags uint32 monitorFlags uint32
// mtx covers eventCh and status conn *netlink.Conn
mtx sync.Mutex closer netlinkCloser
// mu covers eventCh and status
mu sync.Mutex
eventCh chan *Event eventCh chan *Event
status int status int
conn *netlink.Conn
closer netlinkCloser
} }
type MonitorOption func(*Monitor) type MonitorOption func(*Monitor)
@ -163,8 +157,6 @@ func WithMonitorObject(object MonitorObject) MonitorOption {
// NewMonitor returns a Monitor with options to be started. // NewMonitor returns a Monitor with options to be started.
func NewMonitor(opts ...MonitorOption) *Monitor { func NewMonitor(opts ...MonitorOption) *Monitor {
lazyInit()
monitor := &Monitor{ monitor := &Monitor{
status: monitorOK, status: monitorOK,
} }
@ -193,7 +185,7 @@ func (monitor *Monitor) monitor() {
break break
} }
for _, msg := range msgs { for _, msg := range msgs {
if got, want := msg.Header.Type&0xff00>>8, netlink.HeaderType(unix.NFNL_SUBSYS_NFTABLES); got != want { if msg.Header.Type&0xff00>>8 != netlink.HeaderType(unix.NFNL_SUBSYS_NFTABLES) {
continue continue
} }
msgType := msg.Header.Type & 0x00ff msgType := msg.Header.Type & 0x00ff
@ -249,27 +241,27 @@ func (monitor *Monitor) monitor() {
Error: err, Error: err,
} }
monitor.eventCh <- event monitor.eventCh <- event
case unix.NFT_MSG_TRACE:
} }
} }
} }
monitor.mtx.Lock() monitor.mu.Lock()
defer monitor.mu.Unlock()
if monitor.status != monitorClosed { if monitor.status != monitorClosed {
monitor.status = monitorClosed monitor.status = monitorClosed
monitor.closer() monitor.closer()
close(monitor.eventCh) close(monitor.eventCh)
} }
monitor.mtx.Unlock()
} }
func (monitor *Monitor) Close() { func (monitor *Monitor) Close() {
monitor.mtx.Lock() monitor.mu.Lock()
if monitor.status != monitorClosed { if monitor.status != monitorClosed {
monitor.status = monitorClosed monitor.status = monitorClosed
monitor.closer() monitor.closer()
close(monitor.eventCh) close(monitor.eventCh)
} }
monitor.mtx.Unlock() monitor.mu.Unlock()
} }
// AddMonitor to perform the monitor immediately. The channel will be closed after // AddMonitor to perform the monitor immediately. The channel will be closed after
@ -283,12 +275,10 @@ func (cc *Conn) AddMonitor(monitor *Monitor) (chan *Event, error) {
monitor.closer = closer monitor.closer = closer
if monitor.monitorFlags != 0 { if monitor.monitorFlags != 0 {
err = conn.JoinGroup(uint32(unix.NFNLGRP_NFTABLES)) if err = conn.JoinGroup(uint32(unix.NFNLGRP_NFTABLES)); err != nil {
if err != nil {
monitor.closer() monitor.closer()
return nil, err return nil, err
} }
conn.JoinGroup(uint32(unix.NFNLGRP_NFTRACE))
} }
go monitor.monitor() go monitor.monitor()

View File

@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"net" "net"
"sync" "sync"
"sync/atomic"
"testing" "testing"
"time"
"github.com/google/nftables" "github.com/google/nftables"
"github.com/google/nftables/expr" "github.com/google/nftables/expr"
@ -13,7 +13,6 @@ import (
) )
func TestMonitor(t *testing.T) { func TestMonitor(t *testing.T) {
// Create a new network namespace to test these operations, // Create a new network namespace to test these operations,
// and tear down the namespace at test completion. // and tear down the namespace at test completion.
c, newNS := nftest.OpenSystemConn(t, *enableSysTests) c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
@ -28,6 +27,7 @@ func TestMonitor(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer monitor.Close()
var gotTable *nftables.Table var gotTable *nftables.Table
var gotChain *nftables.Chain var gotChain *nftables.Chain
@ -36,6 +36,7 @@ func TestMonitor(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
count := int32(0)
for { for {
select { select {
case event, ok := <-events: case event, ok := <-events:
@ -49,10 +50,16 @@ func TestMonitor(t *testing.T) {
switch event.Type { switch event.Type {
case nftables.EventTypeNewTable: case nftables.EventTypeNewTable:
gotTable = event.Data.(*nftables.Table) gotTable = event.Data.(*nftables.Table)
atomic.AddInt32(&count, 1)
case nftables.EventTypeNewChain: case nftables.EventTypeNewChain:
gotChain = event.Data.(*nftables.Chain) gotChain = event.Data.(*nftables.Chain)
atomic.AddInt32(&count, 1)
case nftables.EventTypeNewRule: case nftables.EventTypeNewRule:
gotRule = event.Data.(*nftables.Rule) gotRule = event.Data.(*nftables.Rule)
atomic.AddInt32(&count, 1)
}
if atomic.LoadInt32(&count) == 3 {
return
} }
} }
} }
@ -97,13 +104,7 @@ func TestMonitor(t *testing.T) {
if err := c.Flush(); err != nil { if err := c.Flush(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// It takes time for the kernel to take effect
time.Sleep(time.Second)
monitor.Close()
wg.Wait() wg.Wait()
if err != nil {
t.Fatal(err)
}
if gotTable.Family != nat.Family || gotTable.Name != nat.Name { if gotTable.Family != nat.Family || gotTable.Name != nat.Name {
t.Fatal("no want table", gotTable.Family, gotTable.Name) t.Fatal("no want table", gotTable.Family, gotTable.Name)
} }