OpenWrt 22.03 build - kernel modules compiling BUT missing in install image

Hello,

I am building my own OpenWrt based on 22.03 branch. I noticed a strange behavior that seems like a bug…

In kernel_menuconfig, I do enable the netfilter nftables modules dup (nft_dup_netdev, nft_dup_ipv4 and nft_dup_ipv6) and the supporting drivers (nf_dup_netdev, nf_dup_ipv4 and nf_dup_ipv6).

I do see that these files are indeed compiled and produce the kernel modules in the build directory, but only dup_netdev is making it to the staging dir (and therefore to the produced image); dup_ipv4 and dup_ipv6 modules are missing.
Here is a search result for the libraries nf_dup in the openwrt folder on my building machine (the result is similar with nft_dup):

ubuntu@OpenWrt:~/openwrt$ find ./ -name *nf_dup*
./build_dir/target-x86_64_musl/root-x86/lib/modules/5.10.159/nf_dup_netdev.ko
./build_dir/target-x86_64_musl/linux-x86_64/packages/.pkgdir/kmod-nft-netdev/lib/modules/5.10.159/nf_dup_netdev.ko
./build_dir/target-x86_64_musl/linux-x86_64/packages/ipkg-x86_64/kmod-nft-netdev/lib/modules/5.10.159/nf_dup_netdev.ko
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/.nf_dup_ipv4.mod.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.ko
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.mod.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.mod.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.mod
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/.nf_dup_ipv4.mod.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/.nf_dup_ipv4.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv4/netfilter/.nf_dup_ipv4.ko.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/.nf_dup_ipv6.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/.nf_dup_ipv6.mod.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.mod.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.mod.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/.nf_dup_ipv6.ko.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.ko
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/.nf_dup_ipv6.mod.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.mod
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.mod
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.mod.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/.nf_dup_netdev.ko.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.c
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.mod.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/.nf_dup_netdev.mod.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.o
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/nf_dup_netdev.ko
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/.nf_dup_netdev.mod.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/net/netfilter/.nf_dup_netdev.o.cmd
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/include/net/netfilter/ipv4/nf_dup_ipv4.h
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/include/net/netfilter/ipv6/nf_dup_ipv6.h
./build_dir/target-x86_64_musl/linux-x86_64/linux-5.10.159/include/net/netfilter/nf_dup_netdev.h
./build_dir/target-x86_64_musl/root.orig-x86/lib/modules/5.10.159/nf_dup_netdev.ko
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/net/ipv4/netfilter/nf_dup_ipv4.c
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/net/ipv6/netfilter/nf_dup_ipv6.c
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/net/netfilter/nf_dup_netdev.c
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/include/net/netfilter/ipv4/nf_dup_ipv4.h
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/include/net/netfilter/ipv6/nf_dup_ipv6.h
./build_dir/toolchain-x86_64_gcc-11.2.0_musl/linux-5.10.159/include/net/netfilter/nf_dup_netdev.h
./staging_dir/target-x86_64_musl/root-x86/lib/modules/5.10.159/nf_dup_netdev.ko

The resulting config in the running kernel does show the correct values:

root@openwrt:~# zcat /proc/config.gz | grep -ie dup
CONFIG_NF_DUP_NETDEV=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NF_DUP_IPV4=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NF_DUP_IPV6=m

BUT as stated earlier, the ipv4 and ipv6 modules are not there, only the netdev one is present:

root@openwrt:~# ls -l /lib/modules/5.10.159/*dup*
-rw-r--r-- 1 root root 4136 Dec 15 01:26 /lib/modules/5.10.159/nf_dup_netdev.ko
-rw-r--r-- 1 root root 4824 Dec 15 01:26 /lib/modules/5.10.159/nft_dup_netdev.ko

Why are the modules missing? A bug somewhere between the compilation itself and the staging before generating the final image?

I will copy the missing modules from the building directory in my building system into my router and see if the compiled modules are working and report here.

I did copy the compiled modules in the building directory into the /lib/modules/(…)/ in the running openwrt on my router.
I was successfully able to load them with insmod, then use some nftables rules with dup without any error:

root@openwrt:~# lsmod | grep -e dup
nft_dup_ipv6           16384  0
nft_dup_ipv4           16384  0
nf_dup_ipv6            16384  1 nft_dup_ipv6
nf_dup_ipv4            16384  1 nft_dup_ipv4
nft_dup_netdev         16384  0
nf_dup_netdev          16384  2 nft_dup_netdev,nft_fwd_netdev
root@openwrt:~# nft list table ip bolemo
table ip bolemo {
	chain ids {
		dup to 8.8.8.8
	}
}

So it seems that there is no reason for those modules to be missing, and there is definitively a bug during the building process…

Please, can you fix this? Thank you :slight_smile:

1 Like

Hey,

I think the NF (NetFilter iptables) module tee(old one FW3) witch is the same as NFT DUP we need in FW4.

root@wrt3200acm:/lib/modules/5.10.146# lsmod|grep -i dup
nf_dup_ipv4 12288 1 xt_TEE
nf_dup_ipv6 12288 1 xt_TEE

I was able to load
nft_dup_ipv4
nft_dup_ipv6

root@wrt3200acm:~/dup# lsmod |grep -i nft_dup
nf_dup_ipv4 12288 2 nft_dup_ipv4,xt_TEE
nf_dup_ipv6 12288 2 nft_dup_ipv6,xt_TEE
nf_tables 143360881 nft_dup_ipv6,nft_dup_ipv4,nft_redir,nft_nat,nft_masq,nft_flow_offload,nft_fib_inet,nft_ct,nft_chain_nat,nf_flow_table_ipv6,nf_flow_table_ipv4,nf_flow_table_inet,nft_reject_ipv6,nft_reject_ipv4,nft_reject_inet,nft_reject,nft_quota,nft_objref,nft_numgen,nft_log,nft_limit,nft_hash,nft_fib_ipv6,nft_fib_ipv4,nft_fib,nft_counter
nft_dup_ipv4 12288 0 [permanent]
nft_dup_ipv6 12288 0 [permanent]

but nft_dup_netdev failed
root@wrt3200acm:~/dup# insmod nft_dup_netdev
failed to insert /lib/modules/5.10.146/nft_dup_netdev.ko

Maybe the but was the kernel version... stable is 146 and git is 159.

How did you run your dup ?
I try this but I have the following error
root@wrt3200acm:~/dup# nft add rule mangle prerouting dup to 8.8.8.8
Error: No such file or directory; did you mean table ‘fw4’ in family inet?
add rule mangle prerouting dup to 8.8.8.8

Because they are modules, rather than built-in, the build system needs to be told to include them.
Have a look at the file that defines the netfilter packages:

You want to define a new KernelPackage for nf-dup using these two files, then select that newly added kmod-nf-dup package in your OpenWrt config. Have a look through the history of netfilter.mk to find an example of another netfilter module being added as a starter.

Let us know if you get stuck, or want more hints.

Cheers

1 Like

I'd say space is not an issue on x64 so you should opt for the builtin approach (y) rather than modules (m)

1 Like

I believe the module has to be compiled on the same build system for the same exact target, kernel version and configs. If you mixed modules of 159 with kernel 146, this is why it does not load properly.

As for how I run dup… There are 3 different dup:

  • 1 for for the netdev family only, that duplicates to devices.
  • 1 for the ip family only, that duplicates to an IPv4 address (with possibility to define on which device).
  • 1 for the ip6 family only, that duplicates to an IPv6 address (with possibility to define on which device).

The dup rule do not work on the inet family, it has to be one of netdev, ip or ip6 (which the appropriate modules loaded in kernel).

For your example, this should work for you:

add table ip my_mangle
add chain ip my_mangle my_prerouting { type filter hook prerouting priority -1; }
add rule ip my_mangle my_prerouting dup to 8.8.8.8

Please, note that this create a table outside of fw4 (that is inet family).
If you have rules in fw4, this dup one will be read before, after or in between the fw4 ones depending on the hook priority you set for the chain my_mangle in comparison to the priorities set in fw4 for the prerouting hook.

1 Like

Thank you, this is interesting…

I thought that enabling or disabling modules in the kernel_menuconfig was what telling the build system what is going to be compiled and included or not in the final build.

So I discover this other stage with kernel packages.
And indeed, there is, as for now, absolutely no package that includes nf*_dup_ipv(4|6).ko

I will probably start with the way @maurer suggested as it is an instant solution, but I might define a new KernelPackage as you described, particularly if it is to be included in future releases for all to benefit from it and solve this issue (because that means that at this point, the only way to use dup_ipv4 and/or dup_ipv6 is either to compile them builtin, or to manually add the modules in the final build (and also include them somewhere in /etc/modules.d/ for them to autoload at startup).

Thank's

I change the source code to production (git checkout v22.03.2)

add this to target/linux/generic/config-5.10
CONFIG_NFT_DUP_NETDEV=y
CONFIG_NFT_DUP_IPV4=y
CONFIG_NFT_DUP_IPV6=y

Build

Copy
openwrt/build_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/linux-mvebu_cortexa9/linux-5.10.146/net/netfilter/nft_dup_netdev.ko
openwrt/build_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/linux-mvebu_cortexa9/linux-5.10.146/net/ipv6/netfilter/nft_dup_ipv6.ko
openwrt/build_dir/target-arm_cortex-a9+vfpv3-d16_musl_eabi/linux-mvebu_cortexa9/linux-5.10.146/net/ipv4/netfilter/nft_dup_ipv4.ko

to /lib/modules/5.10.146/

no need to run insmod.
Only add the dup rule and the module will be loaded automatically

1 Like

A little update on this topic, while closing it:

I did use the method suggested by @maurer, and it works right away.
For that it is the easiest and simplest way of solving the problem, without further work, I will mark it as the solution.

However, I really want to thank @johnth for his detailed explanation on why is was not working, and how to solve it the kernel module way. This hopefully will help anyone reading this thread and looking up for explanations (and me in the future if I encounter such an issue again).

To finish, I wanted to precise that unlike what @nicdesrochers experienced, I had to use insmod to use the modules when I was going this way, they would not load automatically for me.

Happy Holidays to all :slight_smile:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.