Files
op-packages/isp-split/Makefile
T

176 lines
7.9 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
include $(TOPDIR)/rules.mk
PKG_NAME:=isp-split
PKG_VERSION:=0.4.1
PKG_RELEASE:=7
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
include $(INCLUDE_DIR)/package.mk
# 线路体检(linecheck)自 0.3.0 起随包发货,默认 1。
# 1 = 完整功能(默认,正式发行版走这条路径);
# 0 = 构建期物理剥离:实现、CLI、conf 键、LuCI 页/菜单、socat 依赖全部不进包。
# 小闪存 / 特殊渠道的可选剥离版,必须显式指定 FEATURE_LINECHECK=0。
# 这是构建期开关,不是运行时开关:0 的产物里没有可被重新打开的代码。
FEATURE_LINECHECK?=1
define Package/isp-split
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
TITLE:=ISP-aware policy routing for mwan3 (nftables)
# 注意:这里故意不写 +mwan3 依赖。
# 官方 feed 的 mwan3 是 iptables 版(2.12.5),写 +mwan3 会错误地拉进它;
# Kwrt 源里 nft 版的包名是 mwan3-nft,与其他源命名不一致。
# nftables 版 mwan3 是硬性前提,由 install.sh 与 router-preflight 检查,
# 并在 description 里说明。
DEPENDS:=+nftables +curl +mwan3-nft $(if $(filter 1,$(FEATURE_LINECHECK)),+socat)
PKGARCH:=all
endef
define Package/isp-split/description
Route traffic by the ISP that owns the destination address.
Builds mutually exclusive nftables sets from daily-updated
Chinese ISP CIDR data and wires them into mwan3-nft rules.
REQUIRES the nftables port of mwan3 (>= 3.6.0):
- Kwrt: apk add mwan3-nft (软件源里自带)
- 上游: 用 https://github.com/dl12345/mwan3 替换官方 feed 的
iptables 版 mwan3 (2.12.5),或从 Release 下载
endef
define Build/Prepare
rm -rf $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./files $(PKG_BUILD_DIR)/files
# 只调用仓库里那一份 strip-linecheck.sh(随包内 strip-linecheck.sh 逐字节
# 一致),不再手抄 sed:F7 的泄漏就是 SDK 侧另抄一份、覆盖不全造成的。
# 脚本自己会做标记配对、零残留、CSS `.lc-*` 与 sh -n 断言。
if [ "$(FEATURE_LINECHECK)" != "1" ]; then \
sh $(CURDIR)/strip-linecheck.sh $(PKG_BUILD_DIR)/files; \
fi
endef
define Build/Compile
endef
define Package/isp-split/conffiles
/etc/isp-split.conf
endef
# opkg 升级会以 prerm upgrade 调用;apk 的 prerm 只映射到 pre-deinstall。
# 升级时绝不能 uninstall:数据目录、mwan3 规则都必须保留。
define Package/isp-split/prerm
#!/bin/sh
[ -n "$${IPKG_INSTROOT}" ] && exit 0
case "$${1:-}" in
upgrade|pre-upgrade|*upgrade*) exit 0 ;;
esac
if [ -x /usr/sbin/isp-split ]; then
/usr/sbin/isp-split uninstall >/dev/null 2>&1 || true
fi
exit 0
endef
# 卸载后的兜底清理。正常路径是 prerm 里的 `isp-split uninstall`(它调
# /usr/lib/isp-split/teardown.sh,与 scripts/install.sh --uninstall 同一份实现)。
# 但 opkg/apk 会先删包文件再跑 postrm,那时 teardown.sh 已经不在盘上,
# 所以这里必须自带一份等价的内联清单 —— 这是"三条路径同源"的唯一例外,
# 由 tools/selftest.sh 第 21 节做锚点双向核对:teardown.sh 的 runtime 锚点
# 必须逐条出现在本块里,本块也不许出现清单外的清理动作。
define Package/isp-split/postrm
#!/bin/sh
[ -n "$${IPKG_INSTROOT}" ] && exit 0
case "$${1:-}" in
upgrade|pre-upgrade|*upgrade*) exit 0 ;;
esac
# 共享实现在盘上就用它(少数包管理器/强制删除会在删文件前跑 postrm)。
if [ -f /usr/lib/isp-split/teardown.sh ]; then
sh /usr/lib/isp-split/teardown.sh all
exit $$?
fi
if [ -f /etc/crontabs/root ]; then
# mktemp 而不是固定 /tmp 名:PID 可预测,符号链接能抢占(SEC-1)
_cron_tmp=$$(mktemp /etc/.isp-split-cron.XXXXXX) || _cron_tmp=""
if [ -n "$$_cron_tmp" ]; then
grep -v 'isp-split' /etc/crontabs/root > "$$_cron_tmp" 2>/dev/null || true
mv -f "$$_cron_tmp" /etc/crontabs/root 2>/dev/null || rm -f "$$_cron_tmp"
fi
/etc/init.d/cron restart >/dev/null 2>&1 || true
fi
nft delete counter inet mwan3 isp_fallback >/dev/null 2>&1 || true
# B-5:状态文件已改名 dnsmasq.confdir.migrated(记的是迁移后的清理值)。
# 旧名 dnsmasq.confdir.orig 兼容读一次。
_state=/etc/isp-split/state/dnsmasq.confdir.migrated
[ -f "$$_state" ] || _state=/etc/isp-split/state/dnsmasq.confdir.orig
if [ -f "$$_state" ]; then
_orig=$$(head -1 "$$_state" 2>/dev/null)
if [ -n "$$_orig" ]; then
uci -q set "dhcp.@dnsmasq[0].confdir=$$_orig" 2>/dev/null || true
else
uci -q delete dhcp.@dnsmasq[0].confdir 2>/dev/null || true
fi
uci -q commit dhcp 2>/dev/null || true
rm -f /etc/isp-split/state/dnsmasq.confdir.migrated \
/etc/isp-split/state/dnsmasq.confdir.orig 2>/dev/null || true
fi
# BUG-6:OpenClash 接管时 dnsmasq 实际加载的是 /var/etc/dnsmasq.conf.*
# 里 conf-dir= 指向的目录,必须按同一来源清理,不能只删 /tmp/dnsmasq.d。
for _f in /var/etc/dnsmasq.conf.*; do
[ -f "$$_f" ] || continue
sed -n 's/^[[:space:]]*conf-dir=//p' "$$_f" 2>/dev/null |
while IFS= read -r _line; do
for _d in $$_line; do
_d=$${_d%%,*}
while [ "$$_d" != "/" ] && [ "$${_d%/}" != "$$_d" ]; do
_d=$${_d%/}
done
[ -n "$$_d" ] && rm -f "$$_d/isp-split.conf" 2>/dev/null || true
done
done
done
rm -f /tmp/dnsmasq.d/isp-split.conf /etc/isp-split/dnsmasq.d/isp-split.conf 2>/dev/null || true
# F-14:install.sh 留下的 /etc/isp-split.conf.bak.* 与主配置一并清掉(与 teardown.sh
# 同策略:默认删,逐条打印由 teardown.sh 负责;这里只兜底)。
rm -f /etc/isp-split.conf /etc/isp-split.conf.bak.* 2>/dev/null || true
rm -rf /etc/isp-split 2>/dev/null || true
exit 0
endef
# 显式指定权限,不依赖源文件的权限位——固件里脚本不可执行会很难查
define Package/isp-split/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/lib/isp-split
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/isp-split/data
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/usr/sbin/isp-split $(1)/usr/sbin/isp-split
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/init.d/isp-split $(1)/etc/init.d/isp-split
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/build.sh $(1)/usr/lib/isp-split/build.sh
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/uci-defaults/99-isp-split $(1)/etc/uci-defaults/99-isp-split
# F-14:卸载清理的唯一实现。prerm(isp-split uninstall)与
# scripts/install.sh --uninstall 都调它;postrm 在二进制先被删掉时
# 用内联等价清单兜底(锚点由 selftest 第 21 节双向核对)。
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/teardown.sh $(1)/usr/lib/isp-split/teardown.sh
# 环境体检的判据实现(doctor 子命令与 tools/router-preflight.sh 共用一份)。
# 与 teardown.sh 同理:漏装 = 设备上 `isp-split doctor` 直接拒绝运行。
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/doctor.sh $(1)/usr/lib/isp-split/doctor.sh
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/cidr2range.awk $(1)/usr/lib/isp-split/cidr2range.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/merge.awk $(1)/usr/lib/isp-split/merge.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/exclude.awk $(1)/usr/lib/isp-split/exclude.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/range2cidr.awk $(1)/usr/lib/isp-split/range2cidr.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/rules-splice.awk $(1)/usr/lib/isp-split/rules-splice.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/badcidr.awk $(1)/usr/lib/isp-split/badcidr.awk
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/ispdiff.awk $(1)/usr/lib/isp-split/ispdiff.awk
if [ -f $(PKG_BUILD_DIR)/files/usr/lib/isp-split/lc-run ]; then \
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/usr/lib/isp-split/lc-run $(1)/usr/lib/isp-split/lc-run; \
fi
$(INSTALL_CONF) $(PKG_BUILD_DIR)/files/etc/isp-split.conf $(1)/etc/isp-split.conf
endef
$(eval $(call BuildPackage,isp-split))