The Ubuntu Noble Linux image from https://github.com/frank-w/BPI-Router-Images doesn’t have the network packages installed needed for Netfilter SDK on the Banana PI BPI-R3. This means a custom kernel needs to be configured and built, and then used with the BPI-Router-Images repo to get a suitable SD card image.

Custom Kernel
On an Ubuntu 22.04 VPS install the required tools.
sudo apt update
sudo apt install git build-essential bc bison flex libncurses5-dev libssl-dev u-boot-tools ccache gcc-aarch64-linux-gnu
Clone the repository and switch to the matching branch (6.18).
git clone https://github.com/frank-w/BPI-Router-Linux.git
cd BPI-Router-Linux
git checkout 6.18-main
Import the Banana Pi R3 configuration.
./build.sh importconfig
Run menuconfig and enable needed modules.
./build.sh config
In the menuconfig interface, navigate to and enable the following options (set to =m for modules), you can also set everything to m to save having to rebuild the kernel incase something is missing, and the approach that was taken for this all to work.
Networking support
→ Networking options
→ Network packet filtering framework (Netfilter)
→ IP: Netfilter Configuration
[*] IP tables support (required for filtering/masquerading/NAT) → CONFIG_IP_NF_IPTABLES=m
<M> iptables filter target support → CONFIG_IP_NF_FILTER=m
<M> iptables NAT support → CONFIG_IP_NF_NAT=m
<M> iptables mangle target support → CONFIG_IP_NF_MANGLE=m
<M> iptables raw table support → CONFIG_IP_NF_RAW=m (recommended)
It is also advisable to enable additional common xt_ targets/matches under the same submenu (especially any that NetFilter SDK may use, such as XT_TARGET_REDIRECT, XT_MATCH_TCPMSS, etc.). You can search for them with / in menuconfig.
Build the kernel and modules.
./build.sh
This may take 30–60 minutes and produces bpi-r3_*.tar.gz in the current directory. Use this file with following instructions to build a custom SD card image.
Custom SD Card Image
Now from your VPS home directory, download the https://github.com/frank-w/BPI-Router-Images repo, then start screen so it can be left running. Now cd into the BPI-Router-Images repo main directory and create a file sourcefiles_bpi-r3.conf with the following contents – the last line needs editing to where the kernel image is on the VPS.
skipkerneldownload=1
kernelfile=/home/jools/SD/bpi-r3_6.18.23-main.tar.gz
Then we can build the SD card image as normal.
./buildimg.sh bpi-r3 noble
It can take a while to build – 2-3 hours on a VPS. When it is done scp the bpi-r3_noble_6.18.23-main_sdmmc.img.gz file from the VPS and burn it using Balena Etcher to an SD card. Then install and boot the router, connect to it with a USB-to-serial port cable with exposed UART 2.54mm pin connectors via TeraTerm.
We need to download Netfilter SDK on the router which should be connected via the serial port (115200 baud rate).
wget https://netfiltersdk.com/download/nfsdk/unix/nfsdk-unix-src-1.0.4.0.zip
Then we need to install iptables and build tools (it doesn’t use iptables-legacy).
apt install build-essential make iptables
Then we need to create a directory, copy the zip into it and extract it.
mkdir tmp
cd tmp
mv nfsdk-unix-src-1.0.4.0.zip .
unzip nfsdk-unix-src-1.0.4.0.zip
Then we need to cd into the build directory and make the demos, the protocol filter demos will fail but passthrough will be in ./build.
cd unix/linux
make
We also need to ensure there is a connection from the WAN port to the LAN ports.
cd ~
# Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-forward.conf
sudo sysctl -p /etc/sysctl.d/99-forward.conf
# Add NAT masquerading and forwarding rules
sudo iptables -t nat -A POSTROUTING -o wan -j MASQUERADE
sudo iptables -A FORWARD -i lanbr0 -o wan -j ACCEPT
sudo iptables -A FORWARD -i wan -o lanbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Save rules persistently
sudo apt install -y iptables-persistent
sudo iptables-save > /etc/iptables/rules.v4
From here if the WAN port is connected to the internet and a LAN port to a laptop or PC there should be an internet connection. Then the passthough demo can be ran and output should be shown when a browser is open on the lan port machine.
cd tmp/unix/linux/build
root@bpi-r3:~/tmp/unix/linux/build# sudo ./passthrough
Start
Press enter to stop...
threadStart
threadStart
threadStart
threadStart
tcpConnectRequest id=1, processId=0
tcpConnected id=1 processId=0
local=192.168.1.64:48192 remote=148.197.8.32:53 user 0: root
PID 0:
tcpSend id=1 len=44
tcpCanSend id=1
tcpReceive id=1 len=158
tcpCanReceive id=1
tcpConnectRequest id=3, processId=256
tcpConnected id=3 processId=256
local=192.168.1.64:33500 remote=34.107.221.82:80 user 0: root
PID 18446742999967727872:
tcpSend id=3 len=313
tcpCanSend id=3
tcpReceive id=3 len=298
tcpCanReceive id=3
tcpSend id=1 len=46
tcpCanSend id=1
tcpReceive id=1 len=78
tcpCanReceive id=1
tcpConnectRequest id=5, processId=32768
tcpConnected id=5 processId=32768
local=192.168.1.64:60410 remote=172.64.41.4:443 PID 432367554460155904:
tcpSend id=5 len=1911
tcpCanSend id=5
tcpReceive id=5 len=0
tcpSend id=5 len=0
tcpClosed id=5, conn.count=3
tcpConnectRequest id=7, processId=32768
tcpConnected id=7 processId=32768
local=192.168.1.64:60422 remote=172.64.41.4:443 PID 432367554460155904:
tcpSend id=7 len=678
tcpCanSend id=7
tcpReceive id=7 len=0
tcpSend id=7 len=0
Summary
The article has shown how to setup a custom kernel for the Banana PI BPI-R3 for use with Netfilter SDK, and then build a SD card image with Ubuntu Noble. And, lastly the configuration steps needed on the router to get the passthrough demo working.