Skip to content

Instantly share code, notes, and snippets.

@lathiat
Last active August 10, 2023 01:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lathiat/1624723ceef8d17239ae450f03c8eb3b to your computer and use it in GitHub Desktop.
Save lathiat/1624723ceef8d17239ae450f03c8eb3b to your computer and use it in GitHub Desktop.
bpftrace script to check the MTU passed on bridge creation
#!/usr/bin/env bpftrace
// Probe br_dev_newlink and see if IFLA_MTU was passed in at creation
docker run -ti -v /usr/src:/usr/src:ro \
-v /lib/modules/:/lib/modules:ro \
-v /root:/root:ro \
-v /sys/kernel/debug/:/sys/kernel/debug:rw \
--net=host --pid=host --privileged \
quay.io/iovisor/bpftrace:latest \
bpftrace /root/newlink.bt
#include <linux/if_link.h>
#include <linux/netlink.h>
BEGIN
{
printf("Started\n");
}
kprobe:br_dev_newlink
{
$nd = (struct net_device *) arg1;
$tb = (struct nlattr **) arg2;
$nlattr_size = sizeof(struct nlattr);
// At each stage we use print() because it automatically formats the value, this helps check we are doing the right thing
// bpftrace doesn't support non-constant integer array indexe
// so we can't use $tb[IFLA_MTU]
$mtu0 = $tb + IFLA_MTU;
print(("mtu0", $mtu0));
$mtu1 = *($mtu0);
print(("mtu1", $mtu1));
$nla_hdr = *($mtu1);
print(("nla_hdr", $nla_hdr));
// Now we need to convince bpftrace this isn't a struct, as it will refuse to cast from a struct to an integer
$nla_pre1 = *(uint64*) ($mtu0);
print(("nla_pre1", $nla_pre1));
$x = NLA_HDRLEN;
//Emulate nla_data()
//
// (from include/uapi/linux/netlink.h)
// #define NLA_ALIGNTO 4
// #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
// #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
//
// For some reason bpftrace can't cope with the NLA_HDRLEN macro and throws an error,
// so we poorly emulate it by substituing sizeof(struct nlattr) instead.
//
// IFLA_MTU is stored as a uint32
$nla_data = *(uint32)($nla_pre1 + $nlattr_size);
print(("nla_data(mtu)", $nla_data));
printf("IFLA_MTU: nlattr_size:%u tb:%lx mtu0:%lx mtu1:%lx nla_pre1:%lx nla_data:%u nd_mtu=%u\n", $nlattr_size, $tb, $mtu0, $mtu1, $nla_pre1, $nla_data, $nd->mtu);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment