sockstat improvements:

+ Fixes issues with netlink sockets for older kernels, supporting now kernels < 3.7.10
+ Fixes issue with network namespace id for older kernels.
This commit is contained in:
Gustavo Moreira
2023-05-06 14:21:58 +02:00
parent 2d922a8cd6
commit a09f77897b
2 changed files with 44 additions and 6 deletions
@@ -28,7 +28,11 @@ class SockHandlers(interfaces.configuration.VersionableInterface):
self._vmlinux = vmlinux
self._task = task
netns_id = task.nsproxy.net_ns.get_inode()
try:
netns_id = task.nsproxy.net_ns.get_inode()
except AttributeError:
netns_id = NotAvailableValue()
self._netdevices = self._build_network_devices_map(netns_id)
self._sock_family_handlers = {
@@ -61,7 +65,7 @@ class SockHandlers(interfaces.configuration.VersionableInterface):
self._vmlinux.symbol_table_name + constants.BANG + "net_device"
)
for net_dev in net.dev_base_head.to_list(net_device_symname, "dev_list"):
if net.get_inode() != netns_id:
if isinstance(netns_id, NotAvailableValue) or net.get_inode() != netns_id:
continue
dev_name = utility.array_to_string(net_dev.name)
netdevices_map[net_dev.ifindex] = dev_name
@@ -227,14 +231,22 @@ class SockHandlers(interfaces.configuration.VersionableInterface):
if netlink_sock.groups:
groups_bitmap = netlink_sock.groups.dereference()
src_addr = f"groups:0x{groups_bitmap:08x}"
src_port = netlink_sock.portid
try:
# Kernel >= 3.7.10
src_port = netlink_sock.get_portid()
except AttributeError:
src_port = NotAvailableValue()
dst_addr = f"group:0x{netlink_sock.dst_group:08x}"
module = netlink_sock.module
if module and module.name:
module_name_str = utility.array_to_string(module.name)
dst_addr = f"{dst_addr},lkm:{module_name_str}"
dst_port = netlink_sock.dst_portid
try:
dst_port = netlink_sock.get_dst_portid()
except AttributeError:
dst_port = NotAvailableValue()
state = netlink_sock.get_state()
@@ -518,7 +530,11 @@ class Sockstat(plugins.PluginInterface):
protocol = child_sock.get_protocol()
net = task.nsproxy.net_ns
netns_id = net.get_inode()
try:
netns_id = net.get_inode()
except AttributeError:
netns_id = NotAvailableValue()
yield task, netns_id, fd_num, family, sock_type, protocol, sock_fields
def _format_fields(self, sock_stat, protocol):
@@ -1028,10 +1028,13 @@ class mnt_namespace(objects.StructType):
class net(objects.StructType):
def get_inode(self):
if self.has_member("proc_inum"):
# 3.8.13 <= kernel < 3.19.8
return self.proc_inum
elif self.ns.has_member("inum"):
elif self.has_member("ns") and self.ns.has_member("inum"):
# kernel >= 3.19.8
return self.ns.inum
else:
# kernel < 3.8.13
raise AttributeError("Unable to find net_namespace inode")
@@ -1239,6 +1242,25 @@ class netlink_sock(objects.StructType):
# Return the generic socket state
return self.sk.sk_socket.get_state()
def get_portid(self):
if self.has_member("pid"):
# kernel < 3.7.10
return self.pid
if self.has_member("portid"):
# kernel >= 3.7.10
return self.portid
else:
raise AttributeError("Unable to find a source port id")
def get_dst_portid(self):
if self.has_member("dst_pid"):
# kernel < 3.7.10
return self.dst_pid
if self.has_member("dst_portid"):
# kernel >= 3.7.10
return self.dst_portid
else:
raise AttributeError("Unable to find a destination port id")
class vsock_sock(objects.StructType):
def get_protocol(self):