performance: network namespace ID is a 32-bit quantity

This shrinks some data-structures slightly.

Citation: https://github.com/torvalds/linux/blob/6f0d349d922b/include/linux/ns_common.h#L10
This commit is contained in:
Bryan Boreham
2019-10-04 13:11:25 +00:00
parent c6ce47f87d
commit 23d8a418e1
6 changed files with 22 additions and 20 deletions

View File

@@ -190,7 +190,7 @@ func (t *connectionTracker) performEbpfTrack(rpt *report.Report, hostNodeID stri
return nil
}
func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft fourTuple, namespaceID uint64, extraFromNode, extraToNode map[string]string) {
func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft fourTuple, namespaceID uint32, extraFromNode, extraToNode map[string]string) {
if incoming {
ft = reverse(ft)
extraFromNode, extraToNode = extraToNode, extraFromNode
@@ -207,7 +207,7 @@ func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft
t.addDNS(rpt, toAddr.String())
}
func (t *connectionTracker) makeEndpointNode(namespaceID uint64, addr net.IP, port uint16, extra map[string]string) report.Node {
func (t *connectionTracker) makeEndpointNode(namespaceID uint32, addr net.IP, port uint16, extra map[string]string) report.Node {
node := report.MakeNodeWith(report.MakeEndpointNodeIDB(t.conf.HostID, namespaceID, addr, port), nil)
if extra != nil {
node = node.WithLatests(extra)
@@ -240,7 +240,7 @@ func (t *connectionTracker) Stop() error {
return nil
}
func connectionTuple(conn *procspy.Connection, seenTuples map[string]fourTuple) (fourTuple, uint64, bool) {
func connectionTuple(conn *procspy.Connection, seenTuples map[string]fourTuple) (fourTuple, uint32, bool) {
tuple := makeFourTuple(conn.LocalAddress, conn.RemoteAddress, conn.LocalPort, conn.RemotePort)
// If we've already seen this connection, we should know the direction

View File

@@ -25,7 +25,7 @@ import (
// An ebpfConnection represents a TCP connection
type ebpfConnection struct {
tuple fourTuple
networkNamespace uint64
networkNamespace uint32
incoming bool
pid int
}
@@ -173,7 +173,7 @@ func (t *EbpfTracker) TCPEventV4(e tracer.TcpV4) {
t.handleFdInstall(e.Type, int(e.Pid), int(e.Fd))
} else {
tuple := makeFourTuple(e.SAddr, e.DAddr, e.SPort, e.DPort)
t.handleConnection(e.Type, tuple, int(e.Pid), uint64(e.NetNS))
t.handleConnection(e.Type, tuple, int(e.Pid), e.NetNS)
}
}
@@ -198,7 +198,7 @@ func (t *EbpfTracker) LostV6(count uint64) {
// TODO: IPv6 not supported in Scope
}
func tupleFromPidFd(pid int, fd int) (tuple fourTuple, netns uint64, ok bool) {
func tupleFromPidFd(pid int, fd int) (tuple fourTuple, netns uint32, ok bool) {
// read /proc/$pid/ns/net
//
// probe/endpoint/procspy/proc_linux.go supports Linux < 3.8 but we
@@ -268,7 +268,7 @@ func (t *EbpfTracker) handleFdInstall(ev tracer.EventType, pid int, fd int) {
}
}
func (t *EbpfTracker) handleConnection(ev tracer.EventType, tuple fourTuple, pid int, networkNamespace uint64) {
func (t *EbpfTracker) handleConnection(ev tracer.EventType, tuple fourTuple, pid int, networkNamespace uint32) {
t.Lock()
defer t.Unlock()

View File

@@ -53,7 +53,7 @@ func TestHandleConnection(t *testing.T) {
fromPort: ClientPort,
toPort: ServerPort,
},
networkNamespace: uint64(NetNS),
networkNamespace: NetNS,
incoming: false,
pid: int(ClientPid),
}
@@ -89,7 +89,7 @@ func TestHandleConnection(t *testing.T) {
fromPort: ServerPort,
toPort: ClientPort,
},
networkNamespace: uint64(NetNS),
networkNamespace: NetNS,
incoming: true,
pid: int(ServerPid),
}
@@ -110,14 +110,14 @@ func TestHandleConnection(t *testing.T) {
mockEbpfTracker := newMockEbpfTracker()
tuple := fourTuple{ClientAddr, ServerAddr, uint16(IPv4ConnectEvent.SPort), uint16(IPv4ConnectEvent.DPort)}
mockEbpfTracker.handleConnection(IPv4ConnectEvent.Type, tuple, int(IPv4ConnectEvent.Pid), uint64(NetNS))
mockEbpfTracker.handleConnection(IPv4ConnectEvent.Type, tuple, int(IPv4ConnectEvent.Pid), NetNS)
if !reflect.DeepEqual(mockEbpfTracker.openConnections[tuple], IPv4ConnectEbpfConnection) {
t.Errorf("Connection mismatch connect event\nTarget connection:%v\nParsed connection:%v",
IPv4ConnectEbpfConnection, mockEbpfTracker.openConnections[tuple])
}
tuple = fourTuple{ClientAddr, ServerAddr, uint16(IPv4ConnectCloseEvent.SPort), uint16(IPv4ConnectCloseEvent.DPort)}
mockEbpfTracker.handleConnection(IPv4ConnectCloseEvent.Type, tuple, int(IPv4ConnectCloseEvent.Pid), uint64(NetNS))
mockEbpfTracker.handleConnection(IPv4ConnectCloseEvent.Type, tuple, int(IPv4ConnectCloseEvent.Pid), NetNS)
if len(mockEbpfTracker.openConnections) != 0 {
t.Errorf("Connection mismatch close event\nConnection to close:%v",
mockEbpfTracker.openConnections[tuple])
@@ -126,14 +126,14 @@ func TestHandleConnection(t *testing.T) {
mockEbpfTracker = newMockEbpfTracker()
tuple = fourTuple{ServerAddr, ClientAddr, uint16(IPv4AcceptEvent.SPort), uint16(IPv4AcceptEvent.DPort)}
mockEbpfTracker.handleConnection(IPv4AcceptEvent.Type, tuple, int(IPv4AcceptEvent.Pid), uint64(NetNS))
mockEbpfTracker.handleConnection(IPv4AcceptEvent.Type, tuple, int(IPv4AcceptEvent.Pid), NetNS)
if !reflect.DeepEqual(mockEbpfTracker.openConnections[tuple], IPv4AcceptEbpfConnection) {
t.Errorf("Connection mismatch connect event\nTarget connection:%v\nParsed connection:%v",
IPv4AcceptEbpfConnection, mockEbpfTracker.openConnections[tuple])
}
tuple = fourTuple{ServerAddr, ClientAddr, uint16(IPv4AcceptCloseEvent.SPort), uint16(IPv4AcceptCloseEvent.DPort)}
mockEbpfTracker.handleConnection(IPv4AcceptCloseEvent.Type, tuple, int(IPv4AcceptCloseEvent.Pid), uint64(NetNS))
mockEbpfTracker.handleConnection(IPv4AcceptCloseEvent.Type, tuple, int(IPv4AcceptCloseEvent.Pid), NetNS)
if len(mockEbpfTracker.openConnections) != 0 {
t.Errorf("Connection mismatch close event\nConnection to close:%v",

View File

@@ -146,7 +146,7 @@ func readProcessConnections(buf *bytes.Buffer, namespaceProcs []*process.Process
}
// walkNamespace does the work of walk for a single namespace
func (w pidWalker) walkNamespace(namespaceID uint64, buf *bytes.Buffer, sockets map[uint64]*Proc, namespaceProcs []*process.Process) error {
func (w pidWalker) walkNamespace(namespaceID uint32, buf *bytes.Buffer, sockets map[uint64]*Proc, namespaceProcs []*process.Process) error {
if found, err := readProcessConnections(buf, namespaceProcs); err != nil || !found {
return err
@@ -216,7 +216,7 @@ func (w pidWalker) walkNamespace(namespaceID uint64, buf *bytes.Buffer, sockets
}
// ReadNetnsFromPID gets the netns inode of the specified pid
func ReadNetnsFromPID(pid int) (uint64, error) {
func ReadNetnsFromPID(pid int) (uint32, error) {
var statT syscall.Stat_t
dirName := strconv.Itoa(pid)
@@ -225,7 +225,9 @@ func ReadNetnsFromPID(pid int) (uint64, error) {
return 0, err
}
return statT.Ino, nil
// Although Inode is a 64-bit field, namespaces have 32-bit IDs
// see https://github.com/torvalds/linux/blob/6f0d349d922b/include/linux/ns_common.h#L10
return uint32(statT.Ino), nil
}
// walk walks over all numerical (PID) /proc entries. It reads
@@ -235,7 +237,7 @@ func ReadNetnsFromPID(pid int) (uint64, error) {
func (w pidWalker) walk(buf *bytes.Buffer) (map[uint64]*Proc, error) {
var (
sockets = map[uint64]*Proc{} // map socket inode -> process
namespaces = map[uint64][]*process.Process{} // map network namespace id -> processes
namespaces = map[uint32][]*process.Process{} // map network namespace id -> processes
)
// We do two process traversals: One to group processes by namespace and

View File

@@ -30,7 +30,7 @@ type Connection struct {
type Proc struct {
PID uint
Name string
NetNamespaceID uint64
NetNamespaceID uint32
}
// ConnIter is returned by Connections().

View File

@@ -35,10 +35,10 @@ func MakeEndpointNodeID(hostID, namespaceID, address, port string) string {
}
// MakeEndpointNodeIDB produces an endpoint node ID from its composite parts in binary, not strings.
func MakeEndpointNodeIDB(hostID string, namespaceID uint64, addressIP net.IP, port uint16) string {
func MakeEndpointNodeIDB(hostID string, namespaceID uint32, addressIP net.IP, port uint16) string {
namespace := ""
if namespaceID > 0 {
namespace = strconv.FormatUint(namespaceID, 10)
namespace = strconv.FormatUint(uint64(namespaceID), 10)
}
return makeAddressID(hostID, namespace, addressIP.String(), addressIP) + ScopeDelim + strconv.Itoa(int(port))
}