op-packages/mwan3-nft/Makefile
github-actions[bot] 201f770d7f 🛸 Sync 2026-07-22 03:40:22
2026-07-22 03:40:22 +08:00

254 lines
8.9 KiB
Makefile

#
# Copyright (C) 2006-2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mwan3-nft
PKG_VERSION:=3.6.9
PKG_RELEASE:=2
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
PKG_LICENSE:=GPL-2.0
PKG_CONFIG_DEPENDS:=CONFIG_IPV6
PKG_BUILD_DEPENDS:=libnetfilter_conntrack libmnl
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
DEPENDS:= \
+ip-full \
+libnetfilter-conntrack \
+kmod-nft-core \
+nftables-json \
+rpcd-mod-ucode \
+jshn \
+ucode \
+ucode-mod-rtnl \
+ucode-mod-uloop \
+ucode-mod-uci \
+ucode-mod-ubus \
+ucode-mod-fs \
+ucode-mod-socket
CONFLICTS:=mwan3
TITLE:=Multiwan hotplug script with connection tracking support (ucode rtmon)
MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
endef
define Package/$(PKG_NAME)/description
Hotplug script which makes configuration of multiple WAN interfaces simple
and manageable. With loadbalancing/failover support for up to 250 wan
interfaces, connection tracking and an easy to manage traffic ruleset.
mwan3rtmon now uses a ucode implementation leveraging ucode-mod-rtnl
for direct netlink access instead of forking ip commands.
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/mwan3
/etc/mwan3.user
endef
define Package/$(PKG_NAME)/preinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
# Stop mwan3evtd if present (older installs included this daemon). The
# pre-upgrade hook runs before APK removes files no longer in the
# package, so this must happen here to avoid leaving a running process
# with no init script or binary after the file swap.
/etc/init.d/mwan3evtd stop 2>/dev/null
/etc/init.d/mwan3evtd disable 2>/dev/null
# Record whether this is a fresh install so postinst can auto-enable
# without overriding an explicit disable by the user on upgrade.
[ -f /etc/init.d/mwan3 ] || touch /tmp/mwan3_first_install
# Stop mwan3 before APK replaces any files. This is critical for
# upgrades: if mwan3 is running when the init script is replaced,
# procd's inotify trigger restarts the service while the old ip rules
# are still installed, producing RTNETLINK "File exists" errors when
# start_service tries to re-add them. Stopping here puts the service
# into procd's "stopped" state before the init script changes, so
# procd does not auto-restart it.
/etc/init.d/mwan3 stop 2>/dev/null
fi
exit 0
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
# Safety-net stop in case preinst did not run or procd restarted the
# service between preinst and postinst.
/etc/init.d/mwan3 stop 2>/dev/null
# mwan3_prerouting/mwan3_output run at priority mangle + 1, backed by
# non-destructive vmap-dispatch save/restore so the placement is
# order-independent w.r.t. pbr. Older installs used mangle - 1.
# nftables rejects a base chain redeclaration at a different priority,
# so flush+delete the old chains before start recreates them.
for chain in mwan3_prerouting mwan3_output; do
if nft list chain inet fw4 "$$chain" 2>/dev/null | grep -q "priority mangle - 1"; then
nft flush chain inet fw4 "$$chain" 2>/dev/null
nft delete chain inet fw4 "$$chain" 2>/dev/null
fi
done
# Drop legacy ip->mark sticky maps (replaced by per-(rule,family,member)
# ip-only sets). Leftover legacy maps are unreferenced after upgrade
# but waste a name and confuse status.
for mapname in $$(nft list maps inet 2>/dev/null | \
awk '$$1=="map" && $$2 ~ /^mwan3_sticky_v[46]_/ { print $$2 }'); do
nft delete map inet fw4 "$$mapname" 2>/dev/null
done
# mwan3 now operates in table inet mwan3 rather than table inet fw4.
# fw4 uses flush-table (not delete-table) on reload, so any mwan3
# chains/sets left in fw4 survive fw4 reloads and must be explicitly
# removed.
for chain in mwan3_prerouting mwan3_output mwan3_postrouting \
mwan3_ifaces_in mwan3_rules mwan3_connected mwan3_custom mwan3_dynamic; do
nft flush chain inet fw4 "$$chain" 2>/dev/null
nft delete chain inet fw4 "$$chain" 2>/dev/null
done
for setname in mwan3_connected_v4 mwan3_connected_v6 \
mwan3_custom_v4 mwan3_custom_v6 \
mwan3_dynamic_v4 mwan3_dynamic_v6; do
nft delete set inet fw4 "$$setname" 2>/dev/null
done
for mapname in $$(nft list maps inet fw4 2>/dev/null | \
awk '$$1=="map" && $$2 ~ /^mwan3_sticky_/ { print $$2 }'); do
nft flush map inet fw4 "$$mapname" 2>/dev/null
nft delete map inet fw4 "$$mapname" 2>/dev/null
done
# Remove stale firewall.mwan3_reload UCI section if present and reload
# fw4 only if it was. An unconditional fw4 -q reload would trigger
# queued ifup hotplug events that race with mwan3_create_iface_rules
# in the init hotplug, producing RTNETLINK "File exists" errors.
if uci -q delete firewall.mwan3_reload; then
uci commit firewall
fw4 -q reload
fi
# Migrate any fw4-side set references in mwan3 rules to config ipset
# declarations in /etc/config/mwan3 (one-shot, idempotent).
/lib/mwan3/mwan3-migrate-ipset-v4.sh
rm -f /lib/mwan3/mwan3-migrate-ipset-v4.sh
/etc/init.d/rpcd restart
# Second stop immediately before start: procd may have auto-started mwan3
# when the init script was installed (the first stop above runs before that
# happens and is therefore a no-op). By this point the auto-start has
# completed, so this stop calls stop_service and removes its ip rules.
# Without this, mwan3 start below calls procd_close_service (which tells
# procd to replace the service instances) but never calls stop_service,
# so the ip rules from the auto-start are still present when the init
# hotplug events try to add them again.
# Auto-enable on fresh install so mwan3 starts at boot without requiring
# a manual /etc/init.d/mwan3 enable. On upgrade the flag is absent, so
# an explicit disable by the user is preserved.
if [ -f /tmp/mwan3_first_install ]; then
rm -f /tmp/mwan3_first_install
/etc/init.d/mwan3 enable
fi
/etc/init.d/mwan3 stop 2>/dev/null
/etc/init.d/mwan3 start
fi
exit 0
endef
define Package/$(PKG_NAME)/postrm
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
/etc/init.d/rpcd restart
for f in /tmp/dnsmasq.*.d/mwan3-nftsets.conf /tmp/dnsmasq.d/mwan3-nftsets.conf; do
[ -f "$$f" ] && rm -f "$$f"
done
/etc/init.d/dnsmasq restart 2>/dev/null
fi
exit 0
endef
define Build/Compile
$(TARGET_CC) $(CFLAGS) $(LDFLAGS) $(FPIC) \
-shared \
-o $(PKG_BUILD_DIR)/libwrap_mwan3_sockopt.so.1.0 \
$(if $(CONFIG_IPV6),-DCONFIG_IPV6) \
$(PKG_BUILD_DIR)/sockopt_wrap.c \
-ldl
$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \
-o $(PKG_BUILD_DIR)/mwan3ct \
$(PKG_BUILD_DIR)/mwan3ct.c \
-lnetfilter_conntrack -lmnl -lnfnetlink
$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \
-o $(PKG_BUILD_DIR)/mwan3ipcheck \
$(PKG_BUILD_DIR)/mwan3ipcheck.c
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/mwan3 \
$(1)/etc/config/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DATA) ./files/etc/hotplug.d/iface/25-mwan3 \
$(1)/etc/hotplug.d/iface/
$(INSTALL_DATA) ./files/etc/hotplug.d/iface/26-mwan3-user \
$(1)/etc/hotplug.d/iface/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/mwan3 \
$(1)/etc/init.d/
$(INSTALL_DIR) $(1)/lib/mwan3
$(INSTALL_DATA) ./files/lib/mwan3/common.sh \
$(1)/lib/mwan3/
$(INSTALL_DATA) ./files/lib/mwan3/mwan3.sh \
$(1)/lib/mwan3/
$(INSTALL_DATA) ./files/lib/mwan3/mwan3-skeleton.nft \
$(1)/lib/mwan3/
$(INSTALL_BIN) ./files/lib/mwan3/mwan3-migrate-ipset-v4.sh \
$(1)/lib/mwan3/
$(INSTALL_BIN) ./files/lib/mwan3/mwan3-get-addr.uc \
$(1)/lib/mwan3/
$(INSTALL_BIN) ./files/lib/mwan3/mwan3-manage-rules.uc \
$(1)/lib/mwan3/
$(INSTALL_BIN) ./files/lib/mwan3/mwan3-list-routes.uc \
$(1)/lib/mwan3/
$(INSTALL_BIN) ./files/lib/mwan3/mwan3-create-iface-route.uc \
$(1)/lib/mwan3/
$(INSTALL_DIR) $(1)/usr/share/rpcd/ucode/
$(INSTALL_BIN) ./files/usr/share/rpcd/ucode/mwan3 \
$(1)/usr/share/rpcd/ucode/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/usr/sbin/mwan3 \
$(1)/usr/sbin/
$(INSTALL_BIN) ./files/usr/sbin/mwan3rtmon \
$(1)/usr/sbin/
$(INSTALL_BIN) ./files/usr/sbin/mwan3track \
$(1)/usr/sbin/
$(INSTALL_BIN) ./files/usr/sbin/mwan3-lb-test \
$(1)/usr/sbin/
$(INSTALL_BIN) ./files/usr/sbin/mwan3-diag \
$(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc
$(INSTALL_BIN) ./files/etc/mwan3.user \
$(1)/etc/
$(CP) $(PKG_BUILD_DIR)/libwrap_mwan3_sockopt.so.1.0 $(1)/lib/mwan3/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mwan3ct $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mwan3ipcheck $(1)/usr/bin/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/etc/uci-defaults/mwan3-migrate-flush_conntrack \
$(1)/etc/uci-defaults/
$(INSTALL_DATA) ./files/etc/uci-defaults/mwan3-remove-firewall-include \
$(1)/etc/uci-defaults/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))