Add parahub-speed-control script (nftables set + tc HTB) for per-IP speed shaping. Free tier 512kbps, paid tier unlimited. Heartbeat now parses paid_clients from API response and syncs nftables set. Replaced sqm-scripts/kmod-sched-cake/luci-app-sqm packages with tc-full/kmod-ifb/kmod-sched-htb. Section 8 of uci-defaults creates init.d service for speed control instead of SQM config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
217 lines
6.4 KiB
Bash
Executable File
217 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Parahub Mesh Firmware Builder
|
|
# Uses OpenWrt Image Builder to create custom firmware with mesh packages.
|
|
#
|
|
# Usage: ./scripts/build.sh <device>
|
|
# Example: ./scripts/build.sh axt1800
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
OPENWRT_VERSION="${OPENWRT_VERSION:-25.12.0-rc4}"
|
|
|
|
# ============================================================================
|
|
# Device Database (device → target/subtarget + Image Builder profile)
|
|
# ============================================================================
|
|
|
|
device_config() {
|
|
local device="$1"
|
|
case "$device" in
|
|
axt1800)
|
|
OPENWRT_TARGET="qualcommax/ipq60xx"
|
|
PROFILE="glinet_gl-axt1800"
|
|
FIRMWARE_ROLE="bumblebee"
|
|
;;
|
|
mt3000)
|
|
OPENWRT_TARGET="mediatek/filogic"
|
|
PROFILE="glinet_gl-mt3000"
|
|
FIRMWARE_ROLE="bumblebee"
|
|
;;
|
|
mt6000)
|
|
OPENWRT_TARGET="mediatek/filogic"
|
|
PROFILE="glinet_gl-mt6000"
|
|
FIRMWARE_ROLE="bumblebee"
|
|
;;
|
|
ax6s)
|
|
OPENWRT_TARGET="mediatek/filogic"
|
|
PROFILE="xiaomi_redmi-router-ax6s"
|
|
FIRMWARE_ROLE="bumblebee"
|
|
;;
|
|
ax53u)
|
|
OPENWRT_TARGET="ramips/mt7621"
|
|
PROFILE="asus_rt-ax53u"
|
|
FIRMWARE_ROLE="bumblebee"
|
|
;;
|
|
ar300m16)
|
|
OPENWRT_TARGET="ath79/generic"
|
|
PROFILE="glinet_gl-ar300m16"
|
|
FIRMWARE_ROLE="bee"
|
|
;;
|
|
wr3000)
|
|
OPENWRT_TARGET="mediatek/filogic"
|
|
PROFILE="cudy_wr3000-v1"
|
|
FIRMWARE_ROLE="bee"
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ============================================================================
|
|
# Packages
|
|
# ============================================================================
|
|
|
|
# Bee (L2 Transport): minimal mesh relay — no overlay, no guest isolation
|
|
PACKAGES_BEE=(
|
|
kmod-batman-adv
|
|
batctl-full
|
|
wpad-mesh-mbedtls
|
|
-wpad-basic-mbedtls
|
|
luci
|
|
curl
|
|
)
|
|
|
|
# Bumblebee (L3 Gateway): full stack — overlay, VPN, guest isolation, diagnostics
|
|
PACKAGES_BUMBLEBEE=(
|
|
kmod-batman-adv
|
|
batctl-full
|
|
wpad-mesh-mbedtls
|
|
-wpad-basic-mbedtls
|
|
yggdrasil
|
|
kmod-gre6
|
|
kmod-wireguard
|
|
wireguard-tools
|
|
luci-proto-wireguard
|
|
https-dns-proxy
|
|
tc-full
|
|
kmod-ifb
|
|
kmod-sched-htb
|
|
luci
|
|
tcpdump
|
|
iperf3
|
|
iwinfo
|
|
curl
|
|
)
|
|
|
|
# ============================================================================
|
|
# Functions
|
|
# ============================================================================
|
|
|
|
usage() {
|
|
echo "Usage: $0 <device>"
|
|
echo ""
|
|
echo "Devices: Role"
|
|
echo " axt1800 GL.iNet GL-AXT1800 (Slate AX) qualcommax/ipq60xx Bumblebee"
|
|
echo " mt3000 GL.iNet GL-MT3000 (Beryl AX) mediatek/filogic Bumblebee"
|
|
echo " mt6000 GL.iNet GL-MT6000 (Flint 2) mediatek/filogic Bumblebee"
|
|
echo " ax6s Xiaomi Redmi AX6S mediatek/filogic Bumblebee"
|
|
echo " ax53u Asus RT-AX53U ramips/mt7621 Bumblebee"
|
|
echo " ar300m16 GL.iNet GL-AR300M16-EXT (16MB) ath79/generic Bee"
|
|
echo " wr3000 Cudy AX3000 (WR3000) mediatek/filogic Bee"
|
|
echo ""
|
|
echo "Roles:"
|
|
echo " Bumblebee L3 Gateway — full stack (yggdrasil, VPN, guest isolation, SQM, DoH)"
|
|
echo " Bee L2 Transport — minimal mesh relay (batman-adv, luci, heartbeat)"
|
|
echo ""
|
|
echo "OpenWrt version: ${OPENWRT_VERSION} (override with OPENWRT_VERSION env var)"
|
|
echo ""
|
|
echo "Environment variables:"
|
|
echo " OPENWRT_VERSION OpenWrt release (default: ${OPENWRT_VERSION})"
|
|
echo " PACKAGES_EXTRA Additional packages (space-separated)"
|
|
exit 1
|
|
}
|
|
|
|
builder_dir() {
|
|
echo "${PROJECT_DIR}/imagebuilder-${OPENWRT_VERSION}-${OPENWRT_TARGET//\//-}"
|
|
}
|
|
|
|
download_builder() {
|
|
local dir
|
|
dir="$(builder_dir)"
|
|
|
|
if [ -d "$dir" ]; then
|
|
echo "Image Builder already downloaded at ${dir##*/}, skipping..."
|
|
return
|
|
fi
|
|
|
|
# OpenWrt 25.x uses .tar.zst, older uses .tar.xz
|
|
local base_url="https://downloads.openwrt.org/releases/${OPENWRT_VERSION}/targets/${OPENWRT_TARGET}/openwrt-imagebuilder-${OPENWRT_VERSION}-${OPENWRT_TARGET//\//-}.Linux-x86_64"
|
|
echo "Downloading OpenWrt Image Builder ${OPENWRT_VERSION} for ${OPENWRT_TARGET}..."
|
|
mkdir -p "$dir"
|
|
|
|
if wget -q --spider "${base_url}.tar.zst" 2>/dev/null; then
|
|
wget -q --show-progress -O- "${base_url}.tar.zst" | zstd -d | tar -x --strip-components=1 -C "$dir"
|
|
else
|
|
wget -q --show-progress -O- "${base_url}.tar.xz" | tar -xJ --strip-components=1 -C "$dir"
|
|
fi
|
|
}
|
|
|
|
build_firmware() {
|
|
local dir
|
|
dir="$(builder_dir)"
|
|
|
|
# Select package list by role
|
|
local packages
|
|
if [ "$FIRMWARE_ROLE" = "bee" ]; then
|
|
packages="${PACKAGES_BEE[*]} ${PACKAGES_EXTRA:-}"
|
|
else
|
|
packages="${PACKAGES_BUMBLEBEE[*]} ${PACKAGES_EXTRA:-}"
|
|
fi
|
|
|
|
# Create temp FILES dir with role marker
|
|
local tmpfiles
|
|
tmpfiles=$(mktemp -d)
|
|
cp -a "${PROJECT_DIR}/files/"* "$tmpfiles/"
|
|
mkdir -p "$tmpfiles/etc/parahub"
|
|
echo "$FIRMWARE_ROLE" > "$tmpfiles/etc/parahub/role"
|
|
|
|
echo "Building firmware for profile: ${PROFILE}"
|
|
echo "Role: ${FIRMWARE_ROLE}"
|
|
echo "Packages: ${packages}"
|
|
echo "Custom files: ${tmpfiles}"
|
|
|
|
make -C "$dir" image \
|
|
PROFILE="$PROFILE" \
|
|
PACKAGES="$packages" \
|
|
FILES="$tmpfiles" \
|
|
BIN_DIR="${PROJECT_DIR}/output"
|
|
|
|
rm -rf "$tmpfiles"
|
|
|
|
echo ""
|
|
echo "Build complete! Firmware images:"
|
|
ls -lh "${PROJECT_DIR}/output/"*.bin 2>/dev/null || true
|
|
ls -lh "${PROJECT_DIR}/output/"*.img* 2>/dev/null || true
|
|
ls -lh "${PROJECT_DIR}/output/"*.itb 2>/dev/null || true
|
|
}
|
|
|
|
# ============================================================================
|
|
# Main
|
|
# ============================================================================
|
|
|
|
if [ $# -lt 1 ]; then
|
|
usage
|
|
fi
|
|
|
|
INPUT="$1"
|
|
|
|
if ! device_config "$INPUT"; then
|
|
echo "Error: Unknown device '${INPUT}'"
|
|
echo ""
|
|
usage
|
|
fi
|
|
|
|
echo "=== Parahub Mesh Firmware Builder ==="
|
|
echo "Device: ${INPUT}"
|
|
echo "Role: ${FIRMWARE_ROLE}"
|
|
echo "OpenWrt: ${OPENWRT_VERSION}"
|
|
echo "Target: ${OPENWRT_TARGET}"
|
|
echo "Profile: ${PROFILE}"
|
|
echo ""
|
|
|
|
download_builder
|
|
build_firmware
|