2

My attempt at compiling a kernel module failed. Missing a header file pulled from include/net/netfilter/br_netfilter.h. Its just not there. I do not see how it possibly could.

What I expected to see:

filename:       /var/.../module/minrep.ko
license: GPL
name: minrep

What I did see:

  CC [M]  /var/lib/dkms/minrep/0.1/build/minrep.o
In file included from /var/lib/dkms/minrep/0.1/build/minrep.c:2:
./include/net/netfilter/br_netfilter.h:7:10: fatal error: ../../../net/bridge/br_private.h: No such file or directory
modinfo: ERROR: Module /var/lib/dkms/minrep/0.1/5.19.0-41-generic/x86_64/module/minrep.ko not found.

Reproduction for Linux 5.19 @ amd64 using Ubuntu 22.04.2

sudo apt install "linux-headers-$(uname -r)" dkms
sudo mkdir /usr/src/minrep-0.1
sudo tee /usr/src/minrep-0.1/dkms.conf <<'EOF'
PACKAGE_NAME=minrep
PACKAGE_VERSION=0.1
DEST_MODULE_LOCATION=/updates/dkms/
BUILT_MODULE_NAME=minrep
AUTOINSTALL=no
REMAKE_INITRD=no
EOF
sudo tee /usr/src/minrep-0.1/minrep.c <<'EOF'
#include <net/ipv6.h>
#include <net/netfilter/br_netfilter.h>

struct sk_buff skb;
static int __init minrep_init(void)
{
    printk(KERN_NOTICE "Conditional nf_bridge_info %d\n",
        nf_bridge_alloc(&skb) ? "on": "off" );
    return 0;
}
module_init(minrep_init);
MODULE_LICENSE("GPL");
EOF
echo "obj-m += minrep.o" | sudo tee /usr/src/minrep-0.1/Makefile
sudo dkms build -m minrep -v 0.1 -k "$(uname -r)" --verbose
cat /var/lib/dkms/minrep/0.1/build/make.log
modinfo "/var/lib/dkms/minrep/0.1/$(uname -r)/x86_64/module/minrep.ko"

Must be a more general misunderstanding, this is not just a peculiarity of the one header I happened to try first:

grep -R '#include "\.\.' "/usr/src/linux-headers-$(uname -r)/" | wc -l
15

How are such kernel headers meant to be used in separately built modules? Surely not by collecting per-kernel-version copies of all referenced definitions?

user
  • 21
  • 1
  • @MarcusMüller DKMS gives me that same error if I just feed it the primary consumer of that file as-is: the modules at `net/bridge/` (copied from a currently running kernel, anywhere from 5.4 to 6.4). Being *in-tree* and *in-use*, I have high confidence that even if my minimal repro was flawed or version-specific in other ways, I would still be stuck at the above question. – user Jun 10 '23 at 21:33
  • 1
    It seems that all the `.h` files in `net/bridge` are "private" (e.g. see [the kernel sources](https://github.com/torvalds/linux/tree/master/net/bridge)), and are not included in the kernel headers package. It seems weird that one is included from a "public" `.h` file. Not sure that helps much, but a point of reference. – pmacfarlane Jun 10 '23 at 22:00
  • 1
    I mean, they don't just have "private" in the name, but they are not in `include/`, they live alongside the `.c` files. I'd say this was a flaw in the kernel code, specifically the public `.h` file that includes the private header. – pmacfarlane Jun 10 '23 at 22:05
  • 1
    Broken to fix a different build problem. https://github.com/torvalds/linux/commit/230ac490f7fba2aea52914c69d14b15dd515e49c – stark Jun 11 '23 at 11:53
  • So your answer would be something along the line of "find someone sufficiently experienced with kernel development to send a patch upstream that removes that special case entirely by more clearly distinguishing private and public headers"? – user Jun 11 '23 at 12:47
  • The `include/net/netfilter/br_netfilter.h` is not public to the user side programming. So, it's internal to the kernel and all those hacks like DKMS needs to follow all changes made in the kernel. It's hard and not always working as you already found. – 0andriy Jun 11 '23 at 20:25

0 Answers0