Commit Graph
33858 Commits
Author SHA1 Message Date
Sander van Deijck a7ff947712 ovpn-dco: update to version 0.2.20251017
Update the ovpn-dco package to the latest version

Signed-off-by: Sander van Deijck <sander@vandeijck.com>
(cherry picked from commit a5f69cdc41)
Signed-off-by: Sander van Deijck <sander@vandeijck.com>
2026-03-19 19:54:48 +02:00
Sander van Deijck a158e964d8 openvpn: update to 2.6.19
Update the openvpn package to the latest version in
the 2.6.x branch while development of the 2.7.x branch
become stable enough to merge.

Signed-off-by: Sander van Deijck <sander@vandeijck.com>
(cherry picked from commit e0ab7d0dfa)
Signed-off-by: Sander van Deijck <sander@vandeijck.com>
2026-03-19 19:54:48 +02:00
Hannu Nyman ef7746c5e9 nano: improve uci coloring of unterminated strings
Improve the uci file coloring with nano-full.
Show unterminated strings more clearly (lightmagenta vs. white)

Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
(cherry picked from commit a268b500d9)
2026-03-14 09:53:35 +02:00
Stan Grishin 005b8390ba pbr: update to 1.2.2-r10
* add support for OpenVPN netifd detection (thanks @egc112)
* add support for disable LAN->WAN forwarding when `strict_enforcement` is
  set on start and restart (thanks @egc112)
* fix: always create marking chains for interfaces
* fix: insert DSCP/ICMP-related nft rules after marking chains
* fix: shellcheck-related improvements

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit e799f47439)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-03-08 17:48:13 -07:00
Stan Grishin 2250a412b8 adblock-fast: update to 1.2.2-r10
* bugfix: always print errors/warnings on non-quiet start
* bugfix: return proper enabled status in RPCD
* bugfix: return stupped status in RPCD when procd data is empty
* bugfix: correctly process verbosity=0
* delete LICENSE file and only keep it upstream

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit 0058dd1233)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-03-08 17:47:35 -07:00
Stan Grishin 277b476a73 adblock-fast: update to 1.2.2-r8
* bugfix: support TMP and final block-list destination on different
  partitions
* update pause-related code/defaults/validation

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit 5ad634eac9)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-03-04 12:22:29 -08:00
Stan Grishin a57fbe29f0 https-dns-proxy: update to 2025.12.29-4
* add explicit LICENSE file to the repository
* pretty up Makefile
* minor shell script styling improvements
* better parsing if individual dnsmasq instances are used in config
* functional test

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit eea712197e)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-03-03 17:43:36 -08:00
Stan Grishin 0baeaaf3e7 pbr: update to 1.2.2-r8
* bugfix: don't mask RFC1918 in the support output
* bugfix: proper processing of downed interfaces

Thanks to everyone who reported/tested and @egc112 for collecting feedback.

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit abff4ba825)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-03-03 17:42:07 -08:00
xiao bo 7c38411e97 sing-box: update to 1.12.22
changelog: https://github.com/SagerNet/sing-box/releases/tag/v1.12.22

Signed-off-by: xiao bo <peterwillcn@gmail.com>
(cherry picked from commit 5a82fcebe8)
2026-03-01 08:51:10 +02:00
Stan Grishin e7e6b3b284 pbr: bugfix 1.2.2-6
* fixes partial cherry-pick from main

Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-02-28 17:33:26 -08:00
Stan Grishin 793274a78e pbr: update to 1.2.2-r6
Update pbr from 1.2.1-r87 to 1.2.2-r6. This release
adds mwan4 (Multi-WAN) integration, a diagnostic
`support` command, IPv6 lease-to-nftset handling,
improved split-uplink detection, stricter UCI
validation, shell variable quoting fixes across 30+
locations, and a comprehensive 126-case test suite
with a full mock OpenWrt sysroot.

Signed-off-by: Stan Grishin <stangri@melmac.ca>

---

- **31 files changed**, +1,745 / -227 lines
  (net +1,518)
- **1 commit**: `61c8923` —
  `pbr: update to 1.2.2-r6`

---

- Version bumped from `1.2.1-r87` to `1.2.2-r6`
- URL updated from `github.com/stangri/pbr/` to
  `github.com/mossdef-org/pbr/`
- No dependency changes

---

Three options changed from scalar to list type:

| Option              | Old Type | New Type |
|---------------------|----------|----------|
| `ignored_interface` | `option` | `list`   |
| `lan_device`        | `option` | `list`   |
| `resolver_instance` | `option` | `list`   |

Options reordered: scalars first, then lists,
matching UCI convention. No values changed.

---

The init script (`/etc/init.d/pbr`) received
significant additions and fixes across ~660 lines
(+443/-218).

Bumped from `24` to `25`.

**mwan4 (Multi-WAN) Integration (8 new functions):**
- `mwan4_is_installed()` — Detect mwan4 package
- `mwan4_is_running()` — Check service status
- `mwan4_get_iface_list()` — Get enabled interfaces
- `mwan4_get_strategy_list()` — Get strategies
- `mwan4_get_iface_mark_chain()` — Get nft mark
  chain for interface
- `mwan4_get_iface_nft_sets()` — Get nftset names
- `mwan4_get_strategy_chain()` — Get strategy chain
- `mwan4_get_mmx_mask()` — Get Multi-WAN mark mask

Enables PBR to coordinate with mwan4 for combined
policy routing and multi-WAN failover.

**Diagnostic `support` Command:**
- New `support()` function generates masked
  diagnostic output for troubleshooting
- `print_config_masked()` redacts sensitive data
  (passwords, keys, tokens, PSKs, endpoints)
  while preserving IP addresses and structure

**IPv6 Lease Handling:**
- New `ipv6_leases_to_nftset()` parses DHCPv6
  leases from `/tmp/hosts/odhcpd`
- Complements existing `ipv4_leases_to_nftset()`

**Split Uplink Detection (3 new functions):**
- `is_uplink4()` — Check IPv4 uplink interface
- `is_uplink6()` — Check IPv6 uplink interface
- `is_uplink()` — Unified check (v4 or v6)
- New `ipv6_default_lookup` variable for split
  IPv4/IPv6 uplink routing table assignment

**ubus Integration:**
- New `ubus_get_interface()` queries PBR gateway
  data via ubus

**Shell Variable Quoting (30+ locations):**
Systematic conversion of bare variable references
to brace-quoted syntax throughout the script:
- `$2` to `${2}` in string replacements
- `$_ret` to `${_ret}` in conditional expansions
- `$_mark` to `${_mark}` in nft rule generation
- `$nftset6` to `${nftset6}` in dnsmasq rules
- `$nft_set_timeout` to `${nft_set_timeout}`
- `$xrayIfacePrefix` to `${xrayIfacePrefix}`
- And many more across rule generation, output
  strings, and conditional expressions

**Specific Fixes:**
- `pbr_get_gateway6()`: Changed `is_wan` to
  `is_uplink4` for correct IPv4 uplink detection
- `is_netifd_interface()`: Now checks both
  `ip4table` and `ip6table` (was IPv4 only)
- `load_environment()`: Fixed inverted flag check
  (`-z` changed to `-n` for `loadEnvironmentFlag`)
- Dnsmasq instance detection: Fixed UCI section
  lookup with proper variable handling
- Help text URL: `#WarningMessagesDetails` changed
  to `#warning-messages-details` (kebab-case)

- `uplink_ip_rules_priority`: Changed from
  `uinteger` to `range(99,32765)` to enforce
  valid Linux routing policy DB bounds

Three options now use `config_get_list` instead of
`config_get` to support multiple values:
- `ignored_interface`
- `lan_device`
- `resolver_instance`

**Rule Cleanup Refactored:**
- Replaced complex awk-based rule parsing with
  priority-range approach
- Calculates `prio_min = priority - max_ifaces`
  and `prio_max = priority`, iterates and deletes
  rules within range
- Skips netifd-managed fwmark rules
- Added legacy rule cleanup for
  `suppress_prefixlength` entries

**Firewall Sync:**
- Added `fw4 -q reload` after successful nft file
  installation to ensure fw4 state synchronizes
  with PBR's nftables changes

**Resolver Instance Handling:**
- Added robustness checks in
  `_dnsmasq_instance_config()`: file existence
  check and instance validity check
- Better section name resolution with UCI query
- Added missing `setup` parameter in resolver
  instance setup calls

- `uci_get_device()` — Replaced with inline call
- `uci_get_protocol()` — Replaced with inline call

---

In `70-pbr`, fixed shell variable quoting:
```sh
${DEVICE:+ ($DEVICE)}
${DEVICE:+ (${DEVICE})}
```

---

In `pbr.user.netflix`, fixed two instances of
bare variable expansion in parameter substitution:
```sh
params="${params:+$params, }${p}"
params="${params:+${params}, }${p}"
```

---

A full test suite is added in `net/pbr/tests/`
(21 new files, ~1,300 lines) using the shunit2
framework with a complete mock OpenWrt sysroot.

**Runner (`run_tests.sh`):**
- Discovers test files via glob pattern
- Supports pattern-based filtering via CLI arg
- Executes each test in isolated bash subprocess
- Captures output, reports pass/fail with color
- Accumulates stats and lists failures at end
- Requires `shunit2` package

**Setup (`lib/setup.sh`):**
- Creates temporary mock sysroot (`$MOCK_ROOT`)
- Sets `IPKG_INSTROOT` for OpenWrt path resolution
- Installs mock libraries, configs, and binaries
- Stubs `rc.common`, procd, logger, resolveip,
  jsonfilter, pidof, sync
- Sources pbr init script with `readonly` keyword
  stripped (allows test overrides)
- Redirects all file paths to temp directories

**UCI Config API (`lib/mocks/functions.sh`):**
- Full `config_load` parser for UCI syntax
- `config_get`, `config_get_bool`,
  `config_get_list`, `config_foreach`,
  `config_list_foreach`
- `uci_set`, `uci_get`, `uci_add_list`,
  `uci_remove`, `uci_remove_list`, `uci_commit`
- Stores state in associative arrays

**Network API (`lib/mocks/network.sh`):**
- `network_get_device`, `network_get_physdev`,
  `network_get_gateway`, `network_get_gateway6`,
  `network_get_protocol`, `network_get_ipaddr`,
  `network_get_ip6addr`, `network_get_dnsserver`,
  `network_flush_cache`
- Backed by `MOCK_NET_*` variables that tests
  override to simulate different network states
- Pre-configured: wan (eth0/dhcp/192.168.1.1),
  wan6 (eth0/dhcpv6/fd00::1), wg0 (wireguard),
  lan (br-lan/static), loopback (lo/static)

**JSON Shell (`lib/mocks/jshn.sh`):**
- Minimal JSON-in-shell implementation
- `json_init`, `json_add_string/boolean/int`,
  `json_add_object/array`, `json_close_*`,
  `json_select`, `json_get_var`, `json_get_keys`,
  `json_dump`, `json_load`
- Associative array backend with path tracking

**Mock Binaries:**
- `nft` — Returns fw4 table structure with
  standard chains (input, forward, output,
  dstnat, mangle_*); passes syntax checks
- `dnsmasq` — Reports version with nftset support
- `readlink` — Returns `/usr/libexec/ip-full`
  for `*/sbin/ip` (simulates ip-full installed)

**Mock UCI Configs:**
- `pbr` — Full config: enabled, policies
  (vpn_all, vpn_gaming, disabled_policy),
  dns_policy, nft settings, interface lists
- `network` — Interfaces: loopback, lan, wan,
  wan6, wg0 (wireguard)
- `firewall` — Zones: lan (accept all),
  wan (reject input/forward)
- `dhcp` — DHCP server stub
- `system` — Hostname and timezone

**01_validation — Input Validation (67 cases):**

`01_ipv4_validation` (13 cases):
- Valid IPs: 192.168.1.1, 10.0.0.1, 172.16.0.1
- Valid CIDR: /8, /24, /32, /0
- Invalid: octets >255, wrong octet count,
  CIDR >32, IPv6 addresses, domain names

`02_ipv6_validation` (21 cases):
- Valid: ::1, fe80::1, 2001:db8::1, fd00::1,
  full addresses, ::/0
- Invalid: IPv4 addrs, plain strings, MACs
- Scope detection: global (2001:db8::/32),
  link-local (fe80::/10), ULA (fd00::/8)

`03_domain_validation` (8 cases):
- Host: single labels (router, host123)
- Hostname: multi-label (example.com,
  sub.example.com, deep.sub.example.com)
- Domain: FQDN or single-label
- Invalid: IPs, empty strings, MAC notation

`04_misc_validators` (25 cases):
- MAC addresses (colon notation, case variants)
- Integer validation (positive, not negative)
- Negation marker (! prefix detection)
- URL schemes (http, https, ftp, file://)
- Version comparison (is_greater,
  is_greater_or_equal)
- Family mismatch (IPv4/IPv6 mixing detection)

**02_string_utils — String Functions (8 cases):**

`01_str_functions`:
- `str_contains` — Substring search
- `str_contains_word` — Word-boundary search
- `str_to_lower` / `str_to_upper` — Case convert
- `str_first_word` — Token extraction
- `str_replace` — String substitution
- `str_extras_to_underscore` — Normalize delims
- `str_extras_to_space` — Expand delimiters

**03_wan_detection — Interface Detection
  (13 cases):**

`01_wan_types`:
- `is_wan4` — Detects wan/wanX, not wan6/lan/wg0
- `is_wan6` — Detects wan6/mwan6 (IPv6-aware)
- `is_wan6_disabled` — Disabled when ipv6 off
- `is_wan` — Unified v4+v6 detection
- `is_uplink4` / `is_uplink6` — Uplink detection
- `is_tor` — Case-insensitive tor detection
- `is_ignore_target` — Ignore target detection
- `is_list` — Comma/space list vs single value

**04_config — Configuration Loading (13 cases):**

`01_load_config` (7 cases):
- Default values from UCI config
- Hex value parsing (fw_mask, uplink_mark)
- XOR calculation (fw_maskXor = ~fw_mask)
- List parsing (ignored_interface, resolver)
- nft parameters (auto-merge, flags)
- Config-loaded flag tracking

`02_disabled_service` (2 cases):
- Disabled: enabled option becomes unset
- Enabled: enabled option is set

`03_config_ipv6` (4 cases):
- IPv6 enabled: config and uplink interface set
- IPv6 disabled: both unset
- Reload behavior verification

**05_nft — nftables Integration (14 cases):**

`01_nft_file_operations` (8 cases):
- File creation with nft shebang
- Chain creation (dstnat, forward, output,
  prerouting)
- Jump rules and guard rules
- File append, content search, file deletion

`02_nft_check_element` (6 cases):
- fw4 table existence
- Chain existence (input, forward, output,
  dstnat, mangle_*)
- Non-existent chain detection

**06_network — Network Functions (11 cases):**

`01_gateway_discovery` (4 cases):
- IPv4 gateway from mock (192.168.1.1)
- IPv4 gateway fallback (ip addr parsing)
- IPv6 gateway from mock (fd00::1)
- Interface finding for uplinks

`02_supported_interfaces` (7 cases):
- Ignored: loopback in ignored list
- LAN detection vs non-LAN
- Uplink support (wan is supported)
- LAN/loopback not supported
- Wireguard supported (wg0)
- Explicit custom interface support

---

```sh
cd net/pbr/tests && sh run_tests.sh
```

Requires: `bash`, `shunit2`.
Optional filter: `sh run_tests.sh 01_validation`

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit cf1d2770ed)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-02-26 17:01:12 -08:00
Stan Grishin c6437a6344 adblock-fast: update to 1.2.2-r6
Update adblock-fast from 1.2.1-r7 to 1.2.2-r6. This is a major
architectural rewrite that ports the core business logic from a ~2,700-line
monolithic shell script (`/etc/init.d/adblock-fast`) to a ~2,850-line ucode
module (`/lib/adblock-fast/adblock-fast.uc`), reducing the init script to a
thin ~130-line procd wrapper. The rewrite also introduces a comprehensive
test suite and adds the AGPL-3.0-or-later LICENSE file.

---

- **36 files changed**, +5,787 / -2,836 lines (net +2,951)
- **1 commit**: `0263b2b` — `adblock-fast: update to 1.2.2-r6`

---

The previous implementation embedded all business logic (download pipeline,
domain processing, resolver configuration, status reporting, caching)
inside the init.d script as a ~2,700-line POSIX shell script. This made the
code difficult to test, maintain, and extend. Shell limitations (no native
data structures, reliance on subshell `eval`, global namespace pollution)
also introduced fragility and performance overhead from repeated subprocess
spawning for UCI/ubus operations.

```
/etc/init.d/adblock-fast          (131 lines) — Thin procd wrapper
/lib/adblock-fast/adblock-fast.uc (2849 lines) — Core logic (ucode)
/lib/adblock-fast/cli.uc          (95 lines)  — CLI action dispatcher
```

The init script now delegates all operations to the ucode module via:
```sh
readonly _ucode="ucode -S -L /lib/${packageName} /lib/${packageName}/cli.uc --"
```

The CLI dispatcher (`cli.uc`) maps init script actions (start, stop,
status, allow, check, pause, etc.) to the module's exported functions.
The init script retains only procd lifecycle glue (`start_service`,
`stop_service`, `service_triggers`, `service_data`) and UCI validation
schemas.

1. **Native UCI/ubus bindings** — Direct `cursor()` and `connect()` calls
   replace subprocess-heavy `uci get/set` and `jsonfilter` pipelines
2. **Proper data structures** — Objects and arrays for config, status
   tracking, DNS mode definitions; no more string-concatenation state
   management
3. **Streaming I/O** — 64KB chunked file reads for blocklist processing
   instead of loading entire files into memory via pipes
4. **Memoized environment detection** — Platform capabilities (installed
   resolvers, ipset/nftset support, downloader detection) cached on first
   call
5. **Centralized trigger logic** — Config diff comparison
   (`adb_config_cache()`) determines download/restart/skip in one place
6. **Testable** — Module exports enable direct unit testing without mocking
   an entire init system

---

- `+ucode` — ucode interpreter runtime
- `+ucode-mod-fs` — Filesystem operations (readfile, writefile, popen,
  stat, etc.)
- `+ucode-mod-uci` — Native UCI cursor API
- `+ucode-mod-ubus` — Native ubus RPC API

- `+jshn` — No longer needed (was used for JSON parsing in shell)

- URL updated from `github.com/stangri/adblock-fast/` to
  `github.com/mossdef-org/adblock-fast/`
- Install target now installs `/lib/adblock-fast/adblock-fast.uc` and
  `/lib/adblock-fast/cli.uc` alongside the init script
- Version stamp now patches the ucode module
  (`version:` field) instead of init script (`PKG_VERSION` variable)
- `postinst` script removed (service enable handled elsewhere)
- `prerm` script simplified: only purges cache, no longer
  stops service or removes rc.d symlinks (handled by procd)

---

The module supports all existing DNS resolver integrations through a
unified `dns_modes{}` configuration map. Each mode defines output file
paths, gzip cache names, sed format/parse filters, and grep patterns:

| Mode                 | Output Format                                    |
|----------------------|--------------------------------------------------|
| `dnsmasq.addnhosts`  | `127.0.0.1 domain` (+ `:: domain` with IPv6)    |
| `dnsmasq.conf`       | `local=/domain/`                                 |
| `dnsmasq.ipset`      | `ipset=/domain/adb`                              |
| `dnsmasq.nftset`     | `nftset=/domain/4#inet#fw4#adb4[,6#...]`         |
| `dnsmasq.servers`    | `server=/domain/` (block) / `server=/domain/#` (allow) |
| `smartdns.domainset` | Raw domain (with smartdns conf wrapper)          |
| `smartdns.ipset`     | Raw domain (with smartdns ipset conf)            |
| `smartdns.nftset`    | Raw domain (with smartdns nftset conf)           |
| `unbound.adb_list`   | `local-zone: "domain." always_nxdomain`          |

The download pipeline auto-detects blocklist format from content:

| Format       | Detection                           | Example                    |
|--------------|-------------------------------------|----------------------------|
| AdBlock Plus | `[Adblock Plus]` header / `^||`     | `\|\|example.com^`         |
| dnsmasq      | `^server=`                          | `server=/example.com/`     |
| dnsmasq2     | `^local=`                           | `local=/example.com/`      |
| dnsmasq3     | `^address=`                         | `address=/example.com/0.0.0.0` |
| hosts        | `^0.0.0.0\s` or `^127.0.0.1\s`     | `0.0.0.0 example.com`     |
| domains      | (fallback — plain domain list)      | `example.com`              |

```
For each file_url UCI section:
  → Download URL (curl with retries, timeout, optional max-file-size)
  → Auto-detect format → Apply format-specific sed filter → Extract domains
  → Append to accumulator (blocked or allowed)

Merge phase:
  → sort -u (deduplicate)
  → Subdomain optimization (awk label-reverse → sort → dedup → reverse)
  → Remove allowed domains (sed -f generated_script)
  → Inject canary domains (iCloud Private Relay, Mozilla DoH)
  → Inject manually blocked_domain entries from config
  → Format for target DNS resolver
  → Optional validity check (remove malformed entries)
  → Atomic rename to output file

Resolver phase:
  → Update resolver config (UCI: addnhosts, conf-dir, server files)
  → Sanity check (dnsmasq --test)
  → Restart resolver service
  → Heartbeat probe (resolve canary domain to verify blocking)
  → Revert on failure
```

| Function              | Purpose                                              |
|-----------------------|------------------------------------------------------|
| `start(args)`         | Main lifecycle: download, restore from cache, or restart |
| `stop()`              | Disable blocking, flush kernel state, cleanup        |
| `status_service()`    | Report status to syslog/ubus                         |
| `allow(domain)`       | Whitelist domain in live blocklist + UCI config       |
| `check(pattern)`      | Search current blocklist for domain                  |
| `check_tld()`         | Detect TLD entries (sanity check)                    |
| `check_leading_dot()` | Detect leading-dot errors                            |
| `check_lists(domain)` | Search upstream list URLs for domain                 |
| `dl()`                | Force re-download all lists                          |
| `killcache()`         | Purge all cached files                               |
| `pause(seconds)`      | Temporarily disable blocking                         |
| `show_blocklist()`    | Output parsed blocklist to stdout                    |
| `sizes()`             | Fetch/display configured blocklist file sizes        |
| `get_init_status()`   | Full service state for UI/RPC clients                |
| `get_init_list()`     | Enabled/disabled status                              |
| `get_platform_support()` | Detect installed resolvers and features           |
| `get_file_url_filesizes()` | Return cached/live URL metadata                |

- 40+ localized message codes (e.g., `errorDownloadingList`,
  `errorConfigValidationFail`, `warningSanityCheckTLD`)
- Errors/warnings accumulated in `status_data{}` arrays
- Synced atomically to ubus service data for UI consumption
- Status states: `statusSuccess`, `statusFail`, `statusDownloading`,
  `statusProcessing`, `statusRestarting`, `statusPaused`

---

The init script (`/etc/init.d/adblock-fast`) is reduced from ~2,700 to ~130
lines. It now serves exclusively as a procd service wrapper:

- **procd lifecycle**: `start_service()` calls ucode `start`, captures
  shell output for `service_data()`; `stop_service()` calls ucode `stop`
- **Service triggers**: WAN interface triggers, config change triggers, UCI
  validation (unchanged from previous version)
- **Extra commands**: `allow`, `check`, `check_tld`, `check_leading_dot`,
  `check_lists`, `dl`, `killcache`, `pause`, `show_blocklist`, `sizes`,
  `version` — all delegate directly to ucode CLI dispatcher
- **procd data bridge**: `emit_procd_shell()` in ucode generates shell
  statements that the init script `eval`s for `service_data()` and
  `service_stopped()`/`service_started()` hooks (firewall restart flag)

---

The `90-adblock-fast` uci-defaults script is simplified from 181 to 65
lines:

- **Removed**: Entire `simple-adblock` migration path (config, cache files,
  URL lists). This migration was for the initial transition from
  simple-adblock to adblock-fast and is no longer needed.
- **Retained**: List name migration (adds `name` option to `file_url`
  sections that lack one, using pristine default config as reference),
  config key renames (`debug` → `debug_init_script`, `proc_debug` →
  `debug_performance`, `sanity_check` → `dnsmasq_sanity_check`)
- **Simplified**: Uses direct `uci` commands instead of sourcing the init
  script for `uci_get`/`uci_set` helpers. Pristine config lookup now
  supports both apk (`.apk-new`) and opkg (`-opkg`) package manager
  conventions.

---

A full test suite is added in `net/adblock-fast/tests/` (16 new files,
~1,800 lines) mock-and-expect pattern.

- **Module patching**: Converts ES6 imports to CommonJS requires, redirects
  hardcoded system paths to temp directories for isolation
- **Resolver stubs**: Mock binaries for dnsmasq (v2.89), smartdns, unbound,
  ipset, nft, resolveip
- **Test case format**: Markup-based (`-- Testcase --`,
  `-- Environment --`, `-- Expect stdout --`, `-- File path --`) with
  support for inline test data and per-test environment overrides
- **Assertion model**: Compares stdout, stderr, and exit code against
  expected values using `diff -u`
- **Shell validation**: Syntax-checks init.d and uci-defaults scripts via
  `sh -n`
- **Automatic cleanup**: Trap-based temp directory removal

**UCI Mock** (`tests/lib/mocklib/uci.uc`):
- Full `cursor()` interface: `load`, `get`, `get_all`, `foreach`, `set`,
  `delete`, `list_add`, `list_remove`, `commit`, `changes`
- Loads JSON fixtures from `tests/mocks/uci/` (adblock-fast, dhcp, network,
  smartdns, unbound configs)
- Supports `@type[index]` extended section addressing

**ubus Mock** (`tests/lib/mocklib/ubus.uc`):
- `connect()` → `call(object, method, args)` with signature-based fixture
  lookup
- Fixtures in `tests/mocks/ubus/` (system info, network interface
  dump/status, dnsmasq service list)

**System Call Interception** (`tests/lib/mocklib.uc`):
- Blocks service operations: `/etc/init.d/*`, `logger`, `sleep`,
  `dnsmasq --test`
- Passes through data processing: `sed`, `sort`, `grep`, `awk`
- Fixed timestamp (`1615382640`) for reproducible output
- Null `getenv()` for environment isolation

**01_pipeline** — Data processing pipeline (9 tests):
1. `01_all_dns_modes` — Verifies all 9 DNS output modes produce valid,
   deduplicated output (~162-165 domains from 2 input lists)
2. `02_input_format_detection` — Validates auto-detection of domains,
   hosts, AdBlock Plus, and dnsmasq input formats
3. `03_subdomain_dedup` — Confirms parent domains retained, child
   subdomains removed (e.g., blocks `example.com`, skips `sub.example.com`)
4. `04_allowed_domains` — Verifies `allowed_domain` config removes domains
   from output while preserving others
5. `05_canary_domains` — Confirms iCloud Private Relay and Mozilla DoH
   canary domain injection when enabled
6. `06_servers_mode_allow` — Validates dnsmasq.servers mode prepends
   explicit allow entries (`server=/domain/#` format)
7. `07_ipv6_addnhosts` — Verifies dual-stack output (both `127.0.0.1` and
   `::` entries) in addnhosts mode with IPv6 enabled
8. `08_ipv6_nftset` — Confirms nftset mode includes IPv6 set references
   (`4#inet#fw4#adb4,6#inet#fw4#adb6`) when IPv6 enabled
9. `09_unbound_header` — Validates `server:` header line prepended in
   unbound output mode

**02_config** — Configuration handling (1 test):
1. `01_blocked_domain_injection` — Verifies `blocked_domain` config entries
   appear in output

**03_functional** — CLI command tests (2 tests):
1. `01_check_domain` — Tests `check()` correctly identifies blocked vs.
   unblocked domains with appropriate output messages
2. `02_show_blocklist` — Tests `show_blocklist()` outputs parsed domain
   list (162 domains, correct format)

5 curated test data files with ~160+ unique test domains across multiple
formats (plain domains, hosts, AdBlock Plus, dnsmasq), including:
- Valid tracking/ad domains for positive matching
- Overlapping domains across files for deduplication testing
- Parent/child domain pairs for subdomain optimization testing
- Invalid entries (IPs, malformed, special chars) for filter robustness
- Mock UCI/ubus fixtures simulating a standard OpenWrt environment
  (512MB RAM, WAN interface up, dnsmasq running)

---

Adds the full AGPL-3.0-or-later license text (661 lines), matching the
`PKG_LICENSE` field already declared in the Makefile.

---

- Package compat bumped from `11` to `13` (in the ucode module's
  `pkg.compat` constant), reflecting the architectural change
- All existing UCI configuration options preserved (same validation schema)
- All existing extra_commands preserved (same CLI interface)
- All existing DNS resolver modes preserved (same output formats)
- procd service triggers and config triggers unchanged
- `simple-adblock` migration path removed from uci-defaults (obsolete)

---

```sh
cd net/adblock-fast/tests && sh run_tests.sh
```

Requires: `ucode`, `ucode-mod-fs`, `ucode-mod-uci`, `ucode-mod-ubus`,
`sed`, `sort`, `grep`, `awk` (standard OpenWrt buildroot tools).

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit bb3625e94a)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-02-26 17:00:19 -08:00
Ray Wang f4aeec6937 natmap: update to 20260214
Upstream changelog:
https://github.com/heiher/natmap/releases/tag/20260214

Signed-off-by: Ray Wang <git@hev.cc>
(cherry picked from commit 6ca009121c)
2026-02-15 10:25:13 +02:00
Christian Lachner 03801e8313 haproxy: update to v3.0.16
- Fixes CVE-2026-26081
  https://www.haproxy.com/blog/cves-2026-quic-denial-of-service
- Updated haproxy PKG_VERSION and PKG_HASH
- See changes: http://git.haproxy.org/?p=haproxy-3.2.git;a=shortlog

Signed-off-by: Christian Lachner <gladiac@gmail.com>
2026-02-14 15:01:06 +02:00
Christian Lachner 1547203595 haproxy: implement force_reload init option
- It will be used for acme-renew events
- Fixes issue #28038

Signed-off-by: Christian Lachner <gladiac@gmail.com>
2026-02-14 15:01:06 +02:00
Tianling Shen 3097eb25c6 v2ray-geodata: Update to latest version
Update all geodata.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit 44940c3ae7)
2026-02-09 15:44:26 +08:00
Tianling Shen 393bd55cec v2ray-geodata: Update to latest version
Update all geodata.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit cd4e1a0bd1)
2026-02-09 15:43:40 +08:00
Zhu Yujie 31ad90c72a v2ray-geodata: update to latest version
Update all geodata.

Signed-off-by: Zhu Yujie <libriunc@gmail.com>
(cherry picked from commit 851bfade60)
2026-02-09 15:43:37 +08:00
Tianling Shen c0a1800725 dos2unix: Update to 7.5.4
2026-01-30: Version 7.5.4
  * Don't return an error code if a binary file is skipped.
    Reverting change in 7.5.3.
  * Refactored code.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit e0efa48e6e)
2026-02-09 15:43:16 +08:00
Hannu Nyman 66f2501967 nano: update to 8.7.1
Update nano editor to version 8.7.1.

Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
(cherry picked from commit 75458bf089)
2026-02-08 20:55:18 +02:00
Tianling Shen 308f24f706 rust: Update to 1.90.0
Release note: https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit 4c8c41c023)
2026-02-06 09:52:49 +08:00
Stan Grishin 9859e2e706 adblock-fast: update to 1.2.1-r7
* switch from nslookup to resolveip and add dependencey
* fix/use new OutputFormatFilter names for all resolvers

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit eacb797256)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-02-04 20:04:26 -08:00
Hannu Nyman 4b61c3b9d8 irqbalance: update to version 1.9.5
Update to version 1.9.5

* Use upstream meson.build file, as they now support meson
  * patch it locally to continue using static glib linking

* Disable numa, systemd and thermal functions via meson options

* Resurrect the patch to silence repetitive EINVAL warnings.
  (patch was used with 1.9.3, but was not needed with 1.9.4)
  Related discussion in upstream issue 336 and 349

Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
(cherry picked from commit 99076937b1)
2026-01-31 10:47:10 +02:00
Stan Grishin d6f53d5155 adblock-fast: update to 1.2.1-3
* add an option dnsmasq_validity_check to enable removal of invalid
  domains from the final dnsmasq files
* renamed option sanity_check to dnsmasq_sanity_check
* better names for Format Filters and Parse Filters variables

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit e714c02b3e)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-01-29 10:36:39 -08:00
Noah Meyerhans f921966cda bind: bump to 9.20.18
Fixes security issues:

 - CVE-2025-13878: Malformed BRID and HHIT records could trigger an
   assertion failure.

Signed-off-by: Noah Meyerhans <frodo@morgul.net>
(cherry picked from commit 11aee85513)
2026-01-26 15:33:21 -05:00
xiao bo 66328c3a9d sing-box: update to 1.12.17
changelog: https://github.com/SagerNet/sing-box/releases/tag/v1.12.17

Signed-off-by: xiao bo <peterwillcn@gmail.com>
2026-01-23 21:52:40 +02:00
Daniel F. Dickinson 51d68aacd9 python-passlib: remove unmaintained package
passlib is unmaintained since 2020 and a maintained fork called libpass,
which is a drop-in replacement (even using the passlib module name), is
now available. https://github.com/Kozea/Radicale/issues/1952 has more
information.

Therefore we remove the python-passlib package from this repo.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit 3de4d24830)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson 9ae2a8aaae radicale3: bump to version 3.6.0
This eliminates a dependency on the unmaintained passlib
(python3-passlib) package and add a dependency on libpass, a maintained
fork of passlib: https://github.com/Kozea/Radicale/pull/1953

In addition Radicale auth type 'autodetect' for `htpasswd` auth has
been improved by upstream.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit 7af729700b)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson e5fc7da090 python-libpass: add replacement for passlib
passlib has not be updated since 2020 and is therefore a dead project.
Radicale (used in this repo as radicale3) has updated to use libpass (a
maintained fork of passlib): https://github.com/Kozea/Radicale/pull/1953
therefore add python3-libpass to provide libpass, a drop-in replacement
for passlib, and a dependency for Radicale v3.6.0.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit ead09d5fd9)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson daef78745a radicale3: make the empty uci config consistent
We update the missing sections defaults to match the upstream default,
which are also our defaults when there is an UCI configuration, and
are also the defaults for the LuCI app.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit c199e37415)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson 336f8a2847 radicale3: add better reload handling
We update the initscript to rebuild the radicale3 target configuration
file and then HUP the radicale3 process to reload it, on a reload
event, rather than the default which does not regenerate the target
configuration.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit 9e33952b60)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson 6322fe4254 radicale3: update initial uci config
With recent changes to the proposed PR
(https://github.com/openwrt/luci/pull/8216) for the LuCI app for
radicale3, it is not longer necessary that uncommented configuration
be present in /etc/config/radicale3 for the LuCI app to work.

Therefore make the initial uci config commented sample only.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit 78cf89d7d3)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson 7f4c192dcb radicale3: fix permissions on ssl cert/key
When LuCI uploads files like the SSL key and certificate, it makes the
files readable only by root. Since radicale is running as a
non-privileged user it is unable to access a certificate and key
uploaded by LuCI, therefore when SSL cert and key (and optional CA) are
configured, make them group radicale3 and group readable, so the
radicale server can use them.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit ecf9fb51db)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson 630ffca4de radicale3: updates due to radicale 3 vs 2 changes
* Various options have changed since radicale2, and the current
  initscripts set configuration that prevents radicale3 from starting
  in some cases. So update the options to radicale3.
* LuCI will not display the app when the config file is empty, so
  uncomment the first (server section) line.
* Changed the default data directory to /var (emphemeral storage) as
  OpenWrt policy is to not write flash by default. As with PostgreSQL,
  to be useful the user will need to set configuration for an
  appropriate path.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit b1210d155d)
2026-01-23 15:23:47 +07:00
Daniel F. Dickinson d39b524561 radicale3: tweak Makefile and initscript
* fix service_reload in initscript so it reloads configuration
* fold long lines for readability
* shellcheck is a useful linter, if a bit pedantic, so use it and
  update script to address its warnings.

Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
(cherry picked from commit 2dfa60f3f7)
2026-01-23 15:23:47 +07:00
Josef Schlehofer 38497de7f4 radicale2: drop package as we do have radicale3
This package is not compiled due to this build log failure:
```
adding 'radicale-2.1.12.dist-info/RECORD'
removing build/bdist.linux-aarch64/wheel
Successfully built radicale-2.1.12-py3-none-any.whl
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/builder/shared-workdir/build/sdk/staging_dir/hostpkg/lib/python3.13/site-packages/installer/__main__.py", line 98, in <module>
    _main(sys.argv[1:], "python -m installer")
    ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/builder/shared-workdir/build/sdk/staging_dir/hostpkg/lib/python3.13/site-packages/installer/__main__.py", line 86, in _main
    with WheelFile.open(args.wheel) as source:
         ~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/builder/shared-workdir/build/sdk/staging_dir/target-aarch64_cortex-a53_musl/usr/lib/python3.13/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/builder/shared-workdir/build/sdk/staging_dir/hostpkg/lib/python3.13/site-packages/installer/sources.py", line 162, in open
    with zipfile.ZipFile(path) as f:
         ~~~~~~~~~~~~~~~^^^^^^
  File "/builder/shared-workdir/build/sdk/staging_dir/target-aarch64_cortex-a53_musl/usr/lib/python3.13/zipfile/__init__.py", line 1367, in __init__
    self.fp = io.open(file, filemode)
              ~~~~~~~^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/builder/shared-workdir/build/sdk/build_dir/target-aarch64_cortex-a53_musl/pypi/Radicale-2.1.12//openwrt-build/Radicale-2.1.12-*.whl'
```

This occurred due to PEP 625, which requires wheel filenames in lowercase.
The local build produces lowercase-compliant names (radicale-2.1.12-*.whl),
but the script searches for uppercase (Radicale-2.1.12-*.whl).

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit 2f1a3a1f29)
Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
2026-01-23 15:23:47 +07:00
Josef Schlehofer 511c567696 radicale3: new package
Radicale is a small but powerful CalDAV (calendars, to-do lists) and
CardDAV (contacts) server.
This package provides the latest 3.x series, which succeeds radicale2.

This is replacament for recently dropped radicale2 and radicale1.

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit 16b5a43e39)
2026-01-23 15:23:47 +07:00
Josef Schlehofer a6a55873f6 python-pika: add new package for radicale3
Pika is a pure-Python implementation of the AMQP 0-9-1 protocol that
tries to stay fairly independent of the underlying network support
library.

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit d8437af213)
2026-01-23 15:23:47 +07:00
Hirokazu MORIKAWA 9788d496a6 node: january 13, 2026 Security Releases
This is a security release.
Notable Changes
* (CVE-2025-55132) disable futimes when permission model is enabled (RafaelGSS) nodejs-private/node-private#802
* (CVE-2025-59465) add TLSSocket default error handler (RafaelGSS) nodejs-private/node-private#797
lib,permission:
* (CVE-2025-55130) require full read and write to symlink APIs (RafaelGSS) nodejs-private/node-private#760
src:
* (CVE-2025-59466) rethrow stack overflow exceptions in async_hooks (Matteo Collina) nodejs-private/node-private#773
src,lib:
* (CVE-2025-55131) refactor unsafe buffer creation to remove zero-fill toggle (Сковорода Никита Андреевич) nodejs-private/node-private#759
tls:
* (CVE-2026-21637) route callback exceptions through error handlers (Matteo Collina) nodejs-private/node-private#796

add patch, address llhttp build failure on armv7

Signed-off-by: Hirokazu MORIKAWA <morikw2@gmail.com>
2026-01-22 15:31:44 +02:00
Tianling Shen d901044347 Revert "exim: adjust with glibc and libcrypt-compat"
This commit only applies to master and 25.12 branch which have newer
glibc (2.39). We don't have `libcrypt-compat` package on 24.10 branch.

This reverts commit 80c90e9049.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
2026-01-16 16:52:21 +08:00
George Sapkin 3e171c35ca sqlite3: bump to 3.51.2
Changelog: https://sqlite.org/releaselog/3_51_2.html
Signed-off-by: George Sapkin <george@sapk.in>
(cherry picked from commit 8392630a2f)
2026-01-16 06:23:14 +02:00
Eric Fahlgren 25d0d67801 owut: update to 2026.01.13
Enhancements:
    efahl/owut@2526d84be8 owut: add better messaging in quiet modes

Signed-off-by: Eric Fahlgren <ericfahlgren@gmail.com>
(cherry picked from commit 2891aa4472)
2026-01-15 00:54:47 +02:00
Nick Hainke 6b5c6b3d5e snowflake: update to 2.11.0
ChangeLog:
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/commit/6472bd86cdd5d13fe61dc851edcf83b03df7bda1

Signed-off-by: Nick Hainke <vincent@systemli.org>
(cherry picked from commit 31f41a7937)
[Adjust PKG_MIRROR_HASH because of apk/opkg mismatch]
2026-01-12 00:46:11 +01:00
Stan Grishin fe1e1d8bf1 https-dns-proxy: update to 2025-12-29-1
* bump binary to 2025.12.29 with support for -S
* update README and delete README in files/
* bugfix: properly load global option for `force_ipv6_resolvers`
* add global and per-instance `source_addr` option

Thanks to @karl82 for adding source_addr support upstream.

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit c7eb47657e)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-01-08 20:29:30 -08:00
Stan Grishin 835d8c3409 adblock-fast: update to 1.2.0-26
Makefile:
* nicer DEPENDS

Init Script:
* ensure resolver config is reverted and resolver is restarted on
  service fail

Signed-off-by: Stan Grishin <stangri@melmac.ca>
(cherry picked from commit 1e7cc76e91)
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2026-01-05 11:03:20 -08:00
TeleostNaCl Dai a9dce8f502 vim: fix depends configuration
Due to the incorrect DEPENDS configuration, the vim-full and vim-fuller
packages won't show up in menuconfig if the vim-runtime package is not
selected. This happens because these packages depend on vim-runtime.

To fix this, add the '+' symbol to the DEPENDS line. This ensures that
when either vim-full or vim-fuller is selected, the vim-runtime package
(which is a dependency) will also be selected automatically.

Fixes: d1351b3 ("vim: fix config and runtime")
Signed-off-by: TeleostNaCl Dai <teleostnacl@gmail.com>
(cherry picked from commit 639fdb4008)
2026-01-04 14:08:12 +01:00
George Sapkin d4855897c8 vim: add SPDX license identifier
Replace license header with SPDX license identifier.

Update copyright.

Signed-off-by: George Sapkin <george@sapk.in>
(cherry picked from commit 45a857940c)
2026-01-04 14:08:06 +01:00
George Sapkin 6b11c46a54 vim: fix config and runtime
- Install shared runtime for both full and fuller.
- Switch big to huge as big is just an alias to normal.
- Fix default config path for tiny variant.
- Use upstream default config for both full and fuller.
- Don't mark default config files for backup.
- Don't mix variant files.
- Mark fuller variant config files for backup.
- Update configure arguments and remove deprecated ones.
- Remove deprecated configuration variables.
- Improve descriptions.
- Fix the following error by installing the missing runtime files for
  full and correctly installing the default config for tiny:

  E1187: Failed to source defaults.vim

- Fix the following fuller error by installing the missing directory in
  runtime:

  Error detected while processing /usr/share/vim/vim91/plugin/netrwPlugin.vim:
  line    7:
  E919: Directory not found in 'packpath': "pack/*/opt/netrw"

Fixes: https://github.com/openwrt/packages/issues/20203
Fixes: https://github.com/openwrt/packages/issues/28104
Signed-off-by: George Sapkin <george@sapk.in>
(cherry picked from commit d1351b3d8b)
2026-01-04 14:08:02 +01:00
George Sapkin e0d3108076 vim: disable wayland to fix missing dependency
vim autodetects wayland if it's installed, but there's no dependency on
it which results in:

Package vim-full is missing dependencies for the following libraries:
libwayland-client.so.0

Fixes: 4406b79 ("vim: bump to 9.1.1918")
Signed-off-by: George Sapkin <george@sapk.in>
(cherry picked from commit f4cf114981)
2026-01-04 14:07:57 +01:00
George Sapkin fe45e7ccd1 vim: bump to 9.1.1918
Switch source to GitHub for the most recent releases.

Changes: https://github.com/vim/vim/compare/v9.1.0...v9.1.1918
Signed-off-by: George Sapkin <george@sapk.in>
(cherry picked from commit 4406b792e7)
2026-01-04 14:07:53 +01:00