# # 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 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 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)))