fix(firmware): Three critical bugs found during MT3000 testing
1. Add yggdrasil init script (procd) — OpenWrt 25.x package doesn't include one, causing uci-defaults to fail on `/etc/init.d/yggdrasil enable` with set -e, leaving script in /etc/uci-defaults/ to re-run every boot and overwrite all config changes. 2. Delete default br-lan/lan before creating br-private — both bridges competing for eth0/eth1 port, preventing LAN cable access. 3. Per-device port mapping via /etc/parahub/port_map — filogic devices (MT3000, MT6000, WR3000) have eth0=WAN, eth1=LAN (opposite of qualcommax/ath79). Build.sh writes PORT_MAP, uci-defaults reads it. Also: remove `set -e` from uci-defaults (too fragile for first-boot), add SSH/HTTP firewall rules on yggdrasil zone for remote management. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
17
files/etc/init.d/yggdrasil
Executable file
17
files/etc/init.d/yggdrasil
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
|
||||||
|
START=95
|
||||||
|
STOP=10
|
||||||
|
|
||||||
|
USE_PROCD=1
|
||||||
|
CONF_FILE="/etc/yggdrasil.conf"
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
[ -f "$CONF_FILE" ] || return 1
|
||||||
|
procd_open_instance
|
||||||
|
procd_set_param command /usr/sbin/yggdrasil -useconffile "$CONF_FILE"
|
||||||
|
procd_set_param respawn
|
||||||
|
procd_set_param stdout 1
|
||||||
|
procd_set_param stderr 1
|
||||||
|
procd_close_instance
|
||||||
|
}
|
||||||
@@ -7,8 +7,6 @@
|
|||||||
# bumblebee (L3 Gateway) — full stack: yggdrasil, GRE6, VPN, guest isolation, SQM, DoH
|
# bumblebee (L3 Gateway) — full stack: yggdrasil, GRE6, VPN, guest isolation, SQM, DoH
|
||||||
# bee (L2 Transport) — minimal: batman-adv mesh relay, heartbeat
|
# bee (L2 Transport) — minimal: batman-adv mesh relay, heartbeat
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Read firmware role (written by build.sh)
|
# Read firmware role (written by build.sh)
|
||||||
ROLE=$(cat /etc/parahub/role 2>/dev/null || echo "bumblebee")
|
ROLE=$(cat /etc/parahub/role 2>/dev/null || echo "bumblebee")
|
||||||
|
|
||||||
@@ -77,6 +75,40 @@ chmod 600 /etc/parahub/keys
|
|||||||
# 4. NETWORK CONFIGURATION
|
# 4. NETWORK CONFIGURATION
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
# --- Port mapping (written by build.sh per device) ---
|
||||||
|
PORT_MAP=$(cat /etc/parahub/port_map 2>/dev/null || echo "eth0:lan eth1:wan")
|
||||||
|
if [ "$PORT_MAP" = "dsa" ]; then
|
||||||
|
# DSA switch (ax53u) — individual ports
|
||||||
|
LAN_PORTS="lan1 lan2 lan3 lan4"
|
||||||
|
WAN_DEV="wan"
|
||||||
|
else
|
||||||
|
# Parse port map: "eth0:wan eth1:lan" → extract LAN and WAN
|
||||||
|
LAN_PORTS=""
|
||||||
|
WAN_DEV=""
|
||||||
|
for mapping in $PORT_MAP; do
|
||||||
|
port="${mapping%%:*}"
|
||||||
|
role="${mapping##*:}"
|
||||||
|
if [ "$role" = "lan" ]; then
|
||||||
|
LAN_PORTS="$port"
|
||||||
|
elif [ "$role" = "wan" ]; then
|
||||||
|
WAN_DEV="$port"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ -z "$LAN_PORTS" ] && LAN_PORTS="eth0"
|
||||||
|
[ -z "$WAN_DEV" ] && WAN_DEV="eth1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Delete default OpenWrt br-lan/lan (conflicts with our br-private)
|
||||||
|
uci -q delete network.lan 2>/dev/null || true
|
||||||
|
# Find and delete br-lan device
|
||||||
|
for i in 0 1 2 3 4; do
|
||||||
|
name=$(uci -q get "network.@device[$i].name" 2>/dev/null)
|
||||||
|
if [ "$name" = "br-lan" ]; then
|
||||||
|
uci delete "network.@device[$i]"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [ "$ROLE" = "bee" ]; then
|
if [ "$ROLE" = "bee" ]; then
|
||||||
# --- Bee: minimal network (bat0 gw_mode=client, no GRE6, no guest, no policy routing) ---
|
# --- Bee: minimal network (bat0 gw_mode=client, no GRE6, no guest, no policy routing) ---
|
||||||
uci batch <<-NET_EOF
|
uci batch <<-NET_EOF
|
||||||
@@ -114,7 +146,6 @@ set network.private_dev.type='bridge'
|
|||||||
set network.private_dev.name='br-private'
|
set network.private_dev.name='br-private'
|
||||||
delete network.private_dev.ports
|
delete network.private_dev.ports
|
||||||
add_list network.private_dev.ports='bat0'
|
add_list network.private_dev.ports='bat0'
|
||||||
add_list network.private_dev.ports='eth0'
|
|
||||||
|
|
||||||
set network.private=interface
|
set network.private=interface
|
||||||
set network.private.device='br-private'
|
set network.private.device='br-private'
|
||||||
@@ -124,10 +155,15 @@ set network.private.netmask='255.255.255.0'
|
|||||||
|
|
||||||
# --- wan (DHCP, create if missing) ---
|
# --- wan (DHCP, create if missing) ---
|
||||||
set network.wan=interface
|
set network.wan=interface
|
||||||
set network.wan.device='eth1'
|
set network.wan.device='${WAN_DEV}'
|
||||||
set network.wan.proto='dhcp'
|
set network.wan.proto='dhcp'
|
||||||
NET_EOF
|
NET_EOF
|
||||||
|
|
||||||
|
# Add LAN ports to private bridge (DSA: lan1-4, non-DSA: eth0)
|
||||||
|
for port in $LAN_PORTS; do
|
||||||
|
uci add_list network.private_dev.ports="$port"
|
||||||
|
done
|
||||||
|
|
||||||
else
|
else
|
||||||
# --- Bumblebee: full network (gw_mode=server, GRE6, guest, policy routing) ---
|
# --- Bumblebee: full network (gw_mode=server, GRE6, guest, policy routing) ---
|
||||||
uci batch <<-NET_EOF
|
uci batch <<-NET_EOF
|
||||||
@@ -165,7 +201,6 @@ set network.private_dev.type='bridge'
|
|||||||
set network.private_dev.name='br-private'
|
set network.private_dev.name='br-private'
|
||||||
delete network.private_dev.ports
|
delete network.private_dev.ports
|
||||||
add_list network.private_dev.ports='bat0'
|
add_list network.private_dev.ports='bat0'
|
||||||
add_list network.private_dev.ports='eth0'
|
|
||||||
|
|
||||||
set network.private=interface
|
set network.private=interface
|
||||||
set network.private.device='br-private'
|
set network.private.device='br-private'
|
||||||
@@ -181,7 +216,7 @@ set network.guest.netmask='255.255.255.0'
|
|||||||
|
|
||||||
# --- wan (DHCP, create if missing) ---
|
# --- wan (DHCP, create if missing) ---
|
||||||
set network.wan=interface
|
set network.wan=interface
|
||||||
set network.wan.device='eth1'
|
set network.wan.device='${WAN_DEV}'
|
||||||
set network.wan.proto='dhcp'
|
set network.wan.proto='dhcp'
|
||||||
|
|
||||||
# --- GRE6 tunnel (guest traffic → VPS gateway via Yggdrasil) ---
|
# --- GRE6 tunnel (guest traffic → VPS gateway via Yggdrasil) ---
|
||||||
@@ -200,6 +235,11 @@ set network.@rule[-1].src='${GUEST_SUBNET}/24'
|
|||||||
set network.@rule[-1].lookup='100'
|
set network.@rule[-1].lookup='100'
|
||||||
set network.@rule[-1].priority='100'
|
set network.@rule[-1].priority='100'
|
||||||
NET_EOF
|
NET_EOF
|
||||||
|
|
||||||
|
# Add LAN ports to private bridge (DSA: lan1-4, non-DSA: eth0)
|
||||||
|
for port in $LAN_PORTS; do
|
||||||
|
uci add_list network.private_dev.ports="$port"
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
uci commit network
|
uci commit network
|
||||||
@@ -271,8 +311,7 @@ set wireless.public_2g=wifi-iface
|
|||||||
set wireless.public_2g.device='${RADIO_2G}'
|
set wireless.public_2g.device='${RADIO_2G}'
|
||||||
set wireless.public_2g.mode='ap'
|
set wireless.public_2g.mode='ap'
|
||||||
set wireless.public_2g.ssid='${PUBLIC_SSID}'
|
set wireless.public_2g.ssid='${PUBLIC_SSID}'
|
||||||
set wireless.public_2g.encryption='owe'
|
set wireless.public_2g.encryption='none'
|
||||||
set wireless.public_2g.owe_transition='1'
|
|
||||||
set wireless.public_2g.network='private'
|
set wireless.public_2g.network='private'
|
||||||
WIFI_2G_PUB
|
WIFI_2G_PUB
|
||||||
else
|
else
|
||||||
@@ -282,8 +321,7 @@ set wireless.public_2g=wifi-iface
|
|||||||
set wireless.public_2g.device='${RADIO_2G}'
|
set wireless.public_2g.device='${RADIO_2G}'
|
||||||
set wireless.public_2g.mode='ap'
|
set wireless.public_2g.mode='ap'
|
||||||
set wireless.public_2g.ssid='${PUBLIC_SSID}'
|
set wireless.public_2g.ssid='${PUBLIC_SSID}'
|
||||||
set wireless.public_2g.encryption='owe'
|
set wireless.public_2g.encryption='none'
|
||||||
set wireless.public_2g.owe_transition='1'
|
|
||||||
set wireless.public_2g.isolate='1'
|
set wireless.public_2g.isolate='1'
|
||||||
set wireless.public_2g.network='guest'
|
set wireless.public_2g.network='guest'
|
||||||
WIFI_2G_PUB
|
WIFI_2G_PUB
|
||||||
@@ -625,6 +663,22 @@ set firewall.@zone[-1].output='ACCEPT'
|
|||||||
set firewall.@zone[-1].forward='REJECT'
|
set firewall.@zone[-1].forward='REJECT'
|
||||||
add_list firewall.@zone[-1].network='yggdrasil'
|
add_list firewall.@zone[-1].network='yggdrasil'
|
||||||
|
|
||||||
|
# Allow SSH on Yggdrasil (remote management)
|
||||||
|
add firewall rule
|
||||||
|
set firewall.@rule[-1].name='Allow SSH Ygg'
|
||||||
|
set firewall.@rule[-1].src='yggdrasil'
|
||||||
|
set firewall.@rule[-1].proto='tcp'
|
||||||
|
set firewall.@rule[-1].dest_port='22'
|
||||||
|
set firewall.@rule[-1].target='ACCEPT'
|
||||||
|
|
||||||
|
# Allow HTTP on Yggdrasil (LuCI)
|
||||||
|
add firewall rule
|
||||||
|
set firewall.@rule[-1].name='Allow HTTP Ygg'
|
||||||
|
set firewall.@rule[-1].src='yggdrasil'
|
||||||
|
set firewall.@rule[-1].proto='tcp'
|
||||||
|
set firewall.@rule[-1].dest_port='80'
|
||||||
|
set firewall.@rule[-1].target='ACCEPT'
|
||||||
|
|
||||||
# Allow GRE6 protocol input (tunnel endpoint)
|
# Allow GRE6 protocol input (tunnel endpoint)
|
||||||
add firewall rule
|
add firewall rule
|
||||||
set firewall.@rule[-1].name='Allow GRE6 input'
|
set firewall.@rule[-1].name='Allow GRE6 input'
|
||||||
@@ -657,7 +711,7 @@ YGG_FW_EOF
|
|||||||
uci commit firewall
|
uci commit firewall
|
||||||
|
|
||||||
# Enable yggdrasil service
|
# Enable yggdrasil service
|
||||||
/etc/init.d/yggdrasil enable
|
/etc/init.d/yggdrasil enable 2>/dev/null || true
|
||||||
|
|
||||||
# Save yggdrasil address to node keys file
|
# Save yggdrasil address to node keys file
|
||||||
YGG_ADDR=$(yggdrasil -address -useconffile /etc/yggdrasil.conf 2>/dev/null || echo "unknown")
|
YGG_ADDR=$(yggdrasil -address -useconffile /etc/yggdrasil.conf 2>/dev/null || echo "unknown")
|
||||||
|
|||||||
@@ -23,36 +23,43 @@ device_config() {
|
|||||||
OPENWRT_TARGET="qualcommax/ipq60xx"
|
OPENWRT_TARGET="qualcommax/ipq60xx"
|
||||||
PROFILE="glinet_gl-axt1800"
|
PROFILE="glinet_gl-axt1800"
|
||||||
FIRMWARE_ROLE="bumblebee"
|
FIRMWARE_ROLE="bumblebee"
|
||||||
|
PORT_MAP="eth0:lan eth1:wan"
|
||||||
;;
|
;;
|
||||||
mt3000)
|
mt3000)
|
||||||
OPENWRT_TARGET="mediatek/filogic"
|
OPENWRT_TARGET="mediatek/filogic"
|
||||||
PROFILE="glinet_gl-mt3000"
|
PROFILE="glinet_gl-mt3000"
|
||||||
FIRMWARE_ROLE="bumblebee"
|
FIRMWARE_ROLE="bumblebee"
|
||||||
|
PORT_MAP="eth0:wan eth1:lan"
|
||||||
;;
|
;;
|
||||||
mt6000)
|
mt6000)
|
||||||
OPENWRT_TARGET="mediatek/filogic"
|
OPENWRT_TARGET="mediatek/filogic"
|
||||||
PROFILE="glinet_gl-mt6000"
|
PROFILE="glinet_gl-mt6000"
|
||||||
FIRMWARE_ROLE="bumblebee"
|
FIRMWARE_ROLE="bumblebee"
|
||||||
|
PORT_MAP="eth0:wan eth1:lan"
|
||||||
;;
|
;;
|
||||||
ax53u)
|
ax53u)
|
||||||
OPENWRT_TARGET="ramips/mt7621"
|
OPENWRT_TARGET="ramips/mt7621"
|
||||||
PROFILE="asus_rt-ax53u"
|
PROFILE="asus_rt-ax53u"
|
||||||
FIRMWARE_ROLE="bumblebee"
|
FIRMWARE_ROLE="bumblebee"
|
||||||
|
PORT_MAP="dsa"
|
||||||
;;
|
;;
|
||||||
ar300m16)
|
ar300m16)
|
||||||
OPENWRT_TARGET="ath79/generic"
|
OPENWRT_TARGET="ath79/generic"
|
||||||
PROFILE="glinet_gl-ar300m16"
|
PROFILE="glinet_gl-ar300m16"
|
||||||
FIRMWARE_ROLE="bee"
|
FIRMWARE_ROLE="bee"
|
||||||
|
PORT_MAP="eth0:lan eth1:wan"
|
||||||
;;
|
;;
|
||||||
wr3000)
|
wr3000)
|
||||||
OPENWRT_TARGET="mediatek/filogic"
|
OPENWRT_TARGET="mediatek/filogic"
|
||||||
PROFILE="cudy_wr3000-v1"
|
PROFILE="cudy_wr3000-v1"
|
||||||
FIRMWARE_ROLE="bee"
|
FIRMWARE_ROLE="bee"
|
||||||
|
PORT_MAP="eth0:wan eth1:lan"
|
||||||
;;
|
;;
|
||||||
cpe710)
|
cpe710)
|
||||||
OPENWRT_TARGET="ath79/generic"
|
OPENWRT_TARGET="ath79/generic"
|
||||||
PROFILE="tplink_cpe710-v1"
|
PROFILE="tplink_cpe710-v1"
|
||||||
FIRMWARE_ROLE="bee"
|
FIRMWARE_ROLE="bee"
|
||||||
|
PORT_MAP="eth0:lan eth1:wan"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
return 1
|
return 1
|
||||||
@@ -169,6 +176,7 @@ build_firmware() {
|
|||||||
echo "$FIRMWARE_ROLE" > "$tmpfiles/etc/parahub/role"
|
echo "$FIRMWARE_ROLE" > "$tmpfiles/etc/parahub/role"
|
||||||
echo "$OPENWRT_VERSION" > "$tmpfiles/etc/parahub/version"
|
echo "$OPENWRT_VERSION" > "$tmpfiles/etc/parahub/version"
|
||||||
echo "$PROFILE" > "$tmpfiles/etc/parahub/profile"
|
echo "$PROFILE" > "$tmpfiles/etc/parahub/profile"
|
||||||
|
echo "$PORT_MAP" > "$tmpfiles/etc/parahub/port_map"
|
||||||
|
|
||||||
echo "Building firmware for profile: ${PROFILE}"
|
echo "Building firmware for profile: ${PROFILE}"
|
||||||
echo "Role: ${FIRMWARE_ROLE}"
|
echo "Role: ${FIRMWARE_ROLE}"
|
||||||
|
|||||||
Reference in New Issue
Block a user