Server IP : 184.154.167.98 / Your IP : 18.191.72.220 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/libexec/pcp/pmdas/bcc/modules/ |
Upload File : |
# # Copyright (C) 2018 Andreas Gerstmayr <andreas@gerstmayr.me> # Based on the tcpretrans BCC tool by Brendan Gregg: # https://github.com/iovisor/bcc/blob/master/tools/tcpretrans.py # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # """ PCP BCC PMDA tcpretrans module """ # pylint: disable=invalid-name, too-few-public-methods, too-many-instance-attributes import ctypes as ct from socket import inet_ntop, AF_INET, AF_INET6 from struct import pack from bcc import BPF from pcp.pmapi import pmUnits from cpmapi import PM_TYPE_U64, PM_SEM_COUNTER, PM_COUNT_ONE from cpmda import PMDA_FETCH_NOVALUES from modules.pcpbcc import PCPBCCBase # # BPF program # bpf_src = "modules/tcpretrans_count.bpf" # # PCP BCC PMDA constants # MODULE = 'tcpretrans' BASENS = 'io.net.tcp.retrans.' units_none = pmUnits(0, 0, 0, 0, 0, 0) units_count = pmUnits(0, 0, 1, 0, 0, PM_COUNT_ONE) class Data_ipv4(ct.Structure): """ IPv4 data struct """ _fields_ = [ ("pid", ct.c_ulonglong), ("ip", ct.c_ulonglong), ("saddr", ct.c_ulonglong), ("daddr", ct.c_ulonglong), ("lport", ct.c_ulonglong), ("dport", ct.c_ulonglong), ("state", ct.c_ulonglong), ("type", ct.c_ulonglong) ] class Data_ipv6(ct.Structure): """ IPv6 data struct """ _fields_ = [ ("pid", ct.c_ulonglong), ("ip", ct.c_ulonglong), ("saddr", (ct.c_ulonglong * 2)), ("daddr", (ct.c_ulonglong * 2)), ("lport", ct.c_ulonglong), ("dport", ct.c_ulonglong), ("state", ct.c_ulonglong), ("type", ct.c_ulonglong) ] # # PCP BCC Module # class PCPBCCModule(PCPBCCBase): """ PCP BCC tcpretrans module """ def __init__(self, config, log, err, _): """ Constructor """ PCPBCCBase.__init__(self, MODULE, config, log, err) self.include_tlp = False self.flow_count = 20 self.buffer_page_count = 64 for opt in self.config.options(MODULE): if opt == 'include_tlp': self.include_tlp = self.config.getboolean(MODULE, opt) if opt == 'flow_count': self.flow_count = int(self.config.get(MODULE, opt)) if opt == 'buffer_page_count': self.buffer_page_count = int(self.config.get(MODULE, opt)) if not self.buffer_page_count or \ self.buffer_page_count & (self.buffer_page_count - 1): raise RuntimeError("Buffer page count is not power of two.") self.cache = {} self.insts = {} self.log("Initialized.") def metrics(self): """ Get metric definitions """ name = BASENS self.items = ( # Name - reserved - type - semantics - units - help (name + 'count', None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, 'retransmits'), ) return True, self.items def compile(self): """ Compile BPF """ try: self.bpf = BPF(src_file=bpf_src) self.bpf.attach_kprobe(event="tcp_retransmit_skb", fn_name="trace_retransmit") if self.include_tlp: self.bpf.attach_kprobe(event="tcp_send_loss_probe", fn_name="trace_tlp") self.log("Compiled.") except Exception as error: # pylint: disable=broad-except self.bpf = None self.err(str(error)) self.err("Module NOT active!") raise def cumulate_count_table(self, bcc_table, ip_version): """ Cumulate counts from BPF tables """ counts = self.bpf[bcc_table] for k, v in counts.items(): if ip_version == 4: saddr = inet_ntop(AF_INET, pack('I', k.saddr)) daddr = inet_ntop(AF_INET, pack('I', k.daddr)) else: saddr = inet_ntop(AF_INET6, k.saddr) daddr = inet_ntop(AF_INET6, k.daddr) key = '%s:%d::%s:%d' % (saddr, k.lport, daddr, k.dport) value = v.value if key not in self.cache else v.value + self.cache[key] self.cache[key] = value self.insts[key] = ct.c_int(1) counts.clear() def refresh(self): """ Refresh BPF data """ if self.bpf is None: return None self.cumulate_count_table("ipv4_count", 4) self.cumulate_count_table("ipv6_count", 6) return self.insts def bpfdata(self, item, inst): """ Return BPF data as PCP metric value """ try: key = self.pmdaIndom.inst_name_lookup(inst) return [self.cache[key], 1] except Exception: # pylint: disable=broad-except return [PMDA_FETCH_NOVALUES, 0]