Issue
I am trying to write a netfilter module. My first attempt.
My Makefile is:
obj-m += someModule.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I get compile time error clearly indicating that the typedefs
of the structs nf_hookfn
, nf_hook_ops
, etc Are not picked or wrongly picked.
I know that the hook function's argument list has changed in later kernel. Either way, I simply do not see any of the typedefs
I need in /usr/include/linux/netfilter.h
.
What have I tried?
I tried to update kernel headers:
sudo apt-get install linux-headers-$(uname -r)
[sudo] password for xxx:
Reading package lists... Done
Building dependency tree
Reading state information... Done
linux-headers-4.15.0-33-generic is already the newest version (4.15.0-33.36).
0 upgraded, 0 newly installed, 0 to remove and 397 not upgraded.
I see all the required defs in
/usr/src/linux-headers-4.15.0-33/include/linux/netfilter.h
Sure I can include this file instead or have a link to it.
Does not seem the right thing to do. What is the correct approach?
EDIT: Output of make -V 1 is:
gcc -Wp,-MD,/home/somedir/.someModule.o.d -nostdinc
-isystem /usr/lib/gcc/x86_64-linux-gnu/7/include
-I./arch/x86/include -I./arch/x86/include/generated
-I./include -I./arch/x86/include/uapi
-I./arch/x86/include/generated/uapi
-I./include/uapi
-I./include/generated/uapi -include ./include/linux/kconfig.h
-Iubuntu/include -D__KERNEL__ -Wall -Wundef
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
-fno-common -fshort-wchar -Werror-implicit-function-declaration
-Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2
-mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387
-mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup
-mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time
-DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1
-DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1
-DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1
-DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1
-DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe
-Wno-sign-compare -fno-asynchronous-unwind-tables
-mindirect-branch=thunk-extern -mindirect-branch-register
-DRETPOLINE -fno-delete-null-pointer-checks -Wno-frame-address
-Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2
--param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024
-fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable
-fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments
-pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign
-fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check
-fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time
-Werror=incompatible-pointer-types -Werror=designated-init -DMODULE -DKBUILD_BASENAME='"someModule"'
-DKBUILD_MODNAME='"someModule"' -c -o /home/somedir/someModule.o /home/somedir/someModule.c
EDIT: The mistake in my code was that I was following an example I came across on the net. The signature of the hook function and indeed a few function names too have changed. If you come across an example of the use of netfilter functions on the net, do make sure that you are using the correct version of the API.
Solution
If your kernel module is including the header from /usr/include/linux
, something is indeed going wrong there: the files in /usr/include/linux
are for use by userland applications (see What's the difference between /usr/include/linux and the include folder in linux kernel source?), not kernel modules.
Instead, your module should be including the header file in the kernel source.
For what it's worth, that seems to be the default on my system. If I compile this not-a-kernel-module:
#include <linux/netfilter.h>
void my_fn(void) {
struct nf_hook_ops ops;
}
with a Makefile identical to your snippet, it succeeds, and when I run make V=1
, make reports that it is calling gcc
with flags to skip the standard include directories, and add the include
directory at the correct location:
gcc ... -nostdinc ... -I./include ...
If yours does not, something is going wrong there, but it's hard to tell what without looking at the code.
Answered By - Wander Nauta