-
feat(kill): Added nss-switch kill command to forcibly flush conntrack entries matching a rule ID or custom criteria (--proto, --src-ip, --dst-ip, --src-port, --dst-port, --iface). Removes the rule automatically when ID is given.
-
feat(nft): Added mangle_output hook to apply bypass rules to locally generated traffic (router-originated DNS, NTP, WireGuard, etc...).
-
fix(interface display): Improved
nss-ct-dumpto show real output interface (pppoe-wan, etc.) instead of lo for router-originated traffic by checking local IPs and using dst_ip for route lookup. -
fix(conntrack flush): Enhanced interface handling in kill command to derive IP/subnet from interface name for both input (iifname) and output (oifname/local:) cases.
-
fix(paths):
- Relocated all package files to standard FHS paths:
/usr/lib/nss-switch/for binaries/libraries,/etc/config/nss-switch-conffor configuration,/etc/nss-switch/rules.conffor persistent rules, and/etc/firewall.d/nss-bypass-rulesfor firewall hooks. - Fixed Makefile installation paths to match new directory structure.
- Removed hardcoded interface names (
lan2,lan3, etc.) from_normalize_iface_rule(); now only strips direction prefixes (out:,in:,local:).
- Relocated all package files to standard FHS paths:
-
fix(nft):
- IPv4/IPv6 support:
_nft_emit_rule()now detects IP version and usesip saddr/daddrfor IPv4,ip6 saddr/daddrfor IPv6. - Port rules: No longer generates invalid syntax when
proto=anywith port macthes; ports only added when protocol is specified. - Comment escaping: User-provided comments sanitised to prevent nftables syntax errors and command injection.
- Interface direction:
local:prefix now correctly maps tooifname(router-originated traffic), while unprefixed interfaces map toiifname(normal ingress).
- IPv4/IPv6 support:
-
fix(interface validation):
nft_validate_iface()now strips direction prefixes (out:,in:,local:) before validating interface existance withip link show.
-
fix(conntrack clearing):
ct_clear_rule_marks()no longer appends duplicate-sfilter when--src-ipis already specified; interface-derived subnet is only added when no source IP is provided.
-
fix(UCI integration):
- Replaced direct config file editing (
sed/printf >>) with properucicommands for adding and removing firewall include sections (_nft_ensure_uci_include,_nft_remove_uci_include). - Fixed
prermUCI existence check: now usesuci -q get firewall.nss_bypass_include.typeinstead of invaliduci get firewall.nss_bypass_include.
- Replaced direct config file editing (
-
fix(debug logging):
DEBUG_LOG(/tmp/nss-switch.log) is now only created when debug is explicitly enabled vianss-switch debug logmenu.dbg()function no longer writes to log unless debug is active AND log file exists.nft_apply()only redirects firewall reload output to debug log when debug is enabled.
-
fix(cursor restoration):
- Corrected
ui_cursor_show-->ui_cursor_hideincmd_watch()(comment said hide, code was showing).
- Corrected
-
fix(dependencies):
- Removed unnecessary
conntrackddependency from Makefile (onlyconntrackis required).
- Removed unnecessary
-
fix(port extraction in UI):
ui_conn_row()now correctly extracts destination port fromip:port,[ipv6]:port, andip#portformats usingcasestatement.
-
fix(comment validation):
- Added
nft_validate_comment()to reject forbidden characters (;,",',\,$,|, control chars) in rule comments.
- Added
-
fix(input validation in
pick):ui_ask_input()now supports type validation:ip,port,proto,string. Invalid inputs are rejected and retried.
-
fix(
ui_ask_yn):- Now strictly accepts
y/Y/yes/YESorn/N/no/NO; any other input (including garbage) is rejected and reprompts.q/Qcancels the entire operation.
- Now strictly accepts
-
fix(rule listing UI alignment):
- Implemented dynamic column width calculation in
rules_list()to avoid hardcoded widths that broke layout; colours preserved for ID, PERSIST, and COMMENT fields.
- Implemented dynamic column width calculation in
-
fix(nss-ct-dump binary performance):
get_nss_state()now cachesaccess()results for debugfs paths (ecm_nss_ipv4,ecm_sfe_ipv4), eliminating redundant syscalls on every conntrack line (optimisation for large connection tables).
-
fix(C interface resolution):
get_iface_for_ip()simplified: no longer attempts to parse MAC addresses or bridge names; returnslofor router-local IPs, otherwise passes throughip route getoutput unchanged.- Removed
normalize_iface()hardcoded transformations (pppoe-wan->wan,br-lan->lan); interface names now appear as-is.
-
fix(protocol display):
- Expanded protocol number-to-name mapping in C binary to include all common protocols (GRE, ESP, AH, SCTP, etc.) using data from
/etc/protocolsfor visual display while preserving numeric values for nftables rules.
- Expanded protocol number-to-name mapping in C binary to include all common protocols (GRE, ESP, AH, SCTP, etc.) using data from
-
feat(offload engine compatibility):
- Complete rewrite of
ecm.shto support multiple offload engines:- NSS --> Qualcomm NSS hardware offload (ECM debugfs)
- SFE_ECM --> Qualcomm SFE as ECM frontend
- SFE --> Qualcomm SFE standalone (
/dev/sfe,shortcut_femodule) - MTK_PPE --> MediaTek PPE/HNAT hardware offload (
/sys/kernel/debug/ppe0) - SW_FLOW --> Linux
nf_flow_tablesoftware flow offload
- Unified API (
ecm_frontend,ecm_defunct_all,ecm_restart,ecm_connections,ecm_stats) works across all engines. - Added
offload_detect()with result caching to avoid redundant detection. detect_check_all()now shows engine-specific information and warnings.
- Complete rewrite of
-
feat(UI improvements):
ui_ask_inputnow validates IP addresses, ports, and protocols in real-time.debug logcommand now interactive: shows status, last lines, and prompts to enable/disable logging.- Better coloured output in
nss-switch list.
-
feat(ECM connections parser):
ecm_connections()now parses connection data directly from engine sources (ecm_dump.sh, /dev/sfe, PPE debugfs, conntrack) without external dependencies.
-
refactor(build system):
- Restructured package directories to follow OpenWrt and FHS standards.
- Makefile now explicitly lists all library scripts (no wildcards).
preinstdetects offload engine type and reports to user during installation.
- Architecture: native aarch64 support for Qualcomm IPQ807x / NSS platform
- Performance:
ct_dump_all_full()fully migrated from shell to C- Speed improvement: ~30s -> <100ms for 1000+ connections
- Hybrid design: UI remains in shell , heavy parsing in C (fast)
- APK: aarch64-only, includes both shell scripts and compiled binary, ccompiled with GitHub Actions for transparency
- feat(ui):
- Added PROTO name mapping for common ports (SSH, HTTP, HTTPS, DNS, WG, MYSQL, PG, MONGO, REDIS, etc...) max 6 chars.
- Implemented terminal width check (
ui_check_width), requires minimum 120 columns for proper UI display. - Improved spinner with colour cycling animation.
- feat(conntrack):
- Added interface normalisation functions
_normalize_iface_displayand_normalize_iface_rule. - Normalised interface names:
local:pppoe-wan/pppoe-wan->wan,local:br-lan/br-lan->lan, etc.
- Added interface normalisation functions
- fix(cleanup):
- Fixed cursor not restoring after exit in
cmd_watch()andcmd_pick()commands. - Fixed cleanup for orphaned
/tmp/nss-iface.*files on trap and exit. - Unified temporary file cleanup in
_clean_tmp().
- Fixed cursor not restoring after exit in
- fix(nft):
- Added interface normalisation for rule validation and emission, now
wan,wan.20,pppoe-wan,wan_6all belong topppoe-wanfor nftables rules.
- Added interface normalisation for rule validation and emission, now
- fix(ui):
- Adjusted and fixed column widths to a strict
45/45/6layout. - Disabled
alt_screenbuffer to enable native terminal scrolling. - Integrated a visual loading indicator.
- Corrected colour palette rendering issues specifically for the
ashshell environment.
- Adjusted and fixed column widths to a strict
- fix(watch):
- Added
printf "\033[2J\033[3J"to clear both screen and scrollback buffer on eachwatchrefresh. - Eliminated garbage/artifacts left behind after terminal scroll or PgUp/PgDown.
- Unified header bar, hint bar, separator lines and footer messages to match exact table width.
- Added
ui_table_width()function to calculate total table width dynamically.
- Added
- fix(pick):
- Removed pagination, now shows ALL connections at once with native terminal scroll.
- Fixed tmpfile persistence issue that caused "Connection X not found" errors.
- Disabled alt_screen for proper PgUp/PgDown support.
- fix(colours):
- Finalised ANSI colour pattern using
ESC=$(printf '\033')for ash/BusyBox v1.1+ compatibility.
- Finalised ANSI colour pattern using
- feat:
- Introduced initial IPv6 support.
- Added a dedicated real-time debug monitor (
nss-switch debug monitor). - Added debug subcommands:
env,ecm,nft,conntrack,mark,defunct-all,frontend-stop,frontend-restart,log,log-clear,rules-raw,script-raw. - Resolved underlying issues within the
pickcommand execution logic. - Unified the connection tracking dump tool (
ct_dump). - Optimised network rule validation routines and post-execution cleanup processes.
- fix: Corrected IPv6 compression logic and standardised bracketed notation
[]:for address configurations.
- feat:
- Extended IPv6 operational support.
- Introduced
ct_mark_all_fulllogic designed for robust Local Loopback (lo) and Wide Area Network (wan) boundary management. - Patched and stabilised the Command Line Interface (CLI) UI layout.
- fix/feat:
- Refactored multiple instances of legacy syntax to strictly comply with
ashshell constraints. - Rolled out comprehensive
conntrackfiltering support across parameters: interfaces (iface), source IPs (src_ip), destination IPs (dst_ip), destination ports, protocols, and auxiliary variables. - Drafted and committed Blueprint 1 for the NSS Switch Test Tool.
- Refactored multiple instances of legacy syntax to strictly comply with