繁体   English   中英

如何在 kprobe 程序中使用 enum tcp mib 定义?

[英]How can I use the enum tcp mib definitions in a kprobe program?

在这里,我尝试编写一个程序(kprobe),以在 BPF Performance Tools bpftrace 一书中包含像 @tcp_states 这样的 enum tcp mib。 枚举 tcp mib 位于“/include/uapi/linux/snmp.h”中:

#!/usr/local/bin/bpftrace

#include <net/net_namespace.h>
#include <net/netns/mib.h>
#include <net/snmp.h>
#include <uapi/linux/snmp.h>

#define TCP_MIB_MAX              __TCP_MIB_MAX

kprobe:sk_alloc
{
        $net = (struct net *)arg0;
        $mi = (struct netns_mib *)$net->mib;
        $ib = (struct tcp_mib *)$mi;
        
        @mib[1] = "TCP_MIB_NUM";
        @mib[2] = "TCP_MIB_RTOALGORITHM";
        @mib[3] = "TCP_MIB_RTOMIN";
        @mib[4] = "TCP_MIB_RTOMAX;
        @mib[5] = "TCP_MIB_MAXCONN";        
        @mib[6] = "TCP_MIB_ACTIVEOPENS";
        @mib[7] = "TCP_MIB_PASSIVEOPENS";
        @mib[8] = "TCP_MIB_ATTEMPTFAILS";
        @mib[9] = "TCP_MIB_ESTABRESETS";
        @mib[10] = "TCP_MIB_CURRESTAB";
        @mib[11] = "TCP_MIB_INSEGS";
        @mib[12] = "TCP_MIB_OUTSEGS";
        @mib[13] = "TCP_MIB_RETRANSSEGS";
        @mib[14] = "TCP_MIB_INERRS";
        @mib[15] = "TCP_MIB_OUTRSTS";
        @mib[16] = "TCP_MIB_CSUMERRORS";

        printf("-------------------------------\n");
        time();
        printf("sk_alloc: %s pid: %d\n", comm, pid);
        printf("\n");
        printf("$ib: %u\n", $ib->miss[6]);

        $mib_s = $ib->mibs[TCP_MIB_MAX];
        $mib_str = @mib[$mib_s];

        printf("TCP mib is: %s\n", $mib_str);

        clear(@mib);
}
      

当我尝试运行它时,输出是:

the index 94779518808448 is out of bounds for array of size 16

然后我尝试代替 TCP_MIB_MAX,放置特定的数组位置,例如 5,(我修改了上面的代码):

$mib_s = $ib->mibs[5];

当我尝试运行它时,输出是:

...

-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920

$ib: 1516359680
TCP mib is:

-----------------------------
21:40:15
sk_alloc: systemd-logind pid: 920

$ib: 1516359680
TCP mib is:

...

为什么不显示 TCP mib? 并且在输出中什么都不显示? 如何正确使用数组来显示@mib?

TCP_MIB_MAX__TCP_MIB_MAX等于16,等于内核中struct tcp_mib的大小:

enum
{
    TCP_MIB_NUM = 0,
    TCP_MIB_RTOALGORITHM,           /* RtoAlgorithm */
    TCP_MIB_RTOMIN,             /* RtoMin */
    TCP_MIB_RTOMAX,             /* RtoMax */
    TCP_MIB_MAXCONN,            /* MaxConn */
    TCP_MIB_ACTIVEOPENS,            /* ActiveOpens */
    TCP_MIB_PASSIVEOPENS,           /* PassiveOpens */
    TCP_MIB_ATTEMPTFAILS,           /* AttemptFails */
    TCP_MIB_ESTABRESETS,            /* EstabResets */
    TCP_MIB_CURRESTAB,          /* CurrEstab */
    TCP_MIB_INSEGS,             /* InSegs */
    TCP_MIB_OUTSEGS,            /* OutSegs */
    TCP_MIB_RETRANSSEGS,            /* RetransSegs */
    TCP_MIB_INERRS,             /* InErrs */
    TCP_MIB_OUTRSTS,            /* OutRsts */
    TCP_MIB_CSUMERRORS,         /* InCsumErrors */   // == 15
    __TCP_MIB_MAX                                    // == 16
};

#define TCP_MIB_MAX __TCP_MIB_MAX
struct tcp_mib {
    unsigned long   mibs[TCP_MIB_MAX];
};

(包含/uapi/linux/snmp.h 和包含/net/snmp.h)

但是因为数组是从 0 开始索引的,所以在索引$ib->mibs时你只能达到TCP_MIB_MAX - 1 这就是为什么您会收到有关越界索引的投诉。

然后当您选择较小的索引时,您可以按预期访问数组项。 但我不确定你想做什么:

        $mib_s = $ib->mibs[5];
        $mib_str = @mib[$mib_s];

对我来说,您似乎正在从 MIB ( $ib->mibs[TCP_MIB_ACTIVEOPENS] ) 读取值,它可能提供任何值,可能很大,也可能为 null(我怀疑这里就是这种情况)。 然后您将该值用作... @mib的索引? 因此,如果计数器为 10k,您尝试获取 16 大小数组的第 10,000 个单元格? 我想在您的情况下,该值为 0,因此您正在执行$mib_str = @mib[0] ,这可能是一个空字符串,因为您从未为@mib[0]设置值。

为了解决所有这些问题,我将首先为@mib数组使用正确的索引(从 0 到 15),以避免任何混淆。 然后您可能需要重新考虑您要准确打印的内容,但我不确定上面的两行是否是您想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM