Here, I tried to write a program(kprobe) to include the enum tcp mib like @tcp_states in the book BPF Performance Tools bpftrace. The enum tcp mib is in '/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);
}
And when I tried to run it the output was:
the index 94779518808448 is out of bounds for array of size 16
Then I tried to instead of TCP_MIB_MAX, to put specific array positions e.g 5, (I modify the above code):
$mib_s = $ib->mibs[5];
And when I tried to run it, the output was:
...
-----------------------------
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:
...
Why does not show TCP mib? and shows nothing in the output? How can I use the array properly to show @mib?
TCP_MIB_MAX
and__TCP_MIB_MAX
are equal to 16, which is equal to the size of thestruct tcp_mib
in the kernel:and
(include/uapi/linux/snmp.h and include/net/snmp.h)
But because arrays are indexed from 0, you can go only up to
TCP_MIB_MAX - 1
when indexing$ib->mibs
. This is why you get a complaint about the out-of-bound index.Then when you select a smaller index, you can access to the array item as expected. But I'm not sure what you are trying to do with:
To me it looks like you are reading the value from the MIB (
$ib->mibs[TCP_MIB_ACTIVEOPENS]
), which may supply any value, possibly big, and likely null (I suspect this is the case here). Then you use that value as... an index in@mib
? So if the counter is at 10k, you try to take the 10,000th cell of a 16-sized array? I suppose in your case the value is 0, so you are doing$mib_str = @mib[0]
, which is likely an empty string because you never set a value for@mib[0]
.To fix all of this I would start by using the correct indices (from 0 to 15) for the
@mib
array, to avoid any confusion. Then you probably need to rethink what you are trying to print exactly, but I'm not sure that the two lines above is what you want.