Bug-fix release from a full-project review.
Fixes
- Multi-IP interfaces no longer break
--configure. An interface with several IPv4 addresses previously planned duplicateip route addcommands; the second failed with EEXIST and rolled back the entire apply. The planner now dedupes per (table, destination) and re-verifies each change against detected state per address. All four persistence backends also now emit one config per interface covering every address (networkd overwrote per-IP files, netplan emitted invalid duplicate YAML keys, the NM dispatcher generated unreachable case branches). - Rollback is a true snapshot restore. Backups capture every managed persistence file alongside rt_tables.
--rollbackrestores the configuration that was running when the backup was taken: SBR rules, routes, rt_tables entries, sysctl values, and persistence files all return to their backed-up state, and anything added since is removed. Backups from older versions fall back to the previous remove-all behavior. - Sysctl persistence writes the complete required set, not just the run's delta, so settings that already happened to be correct at runtime survive reboot.
- ifupdown persistence is idempotent -- repeat runs replace the managed post-up/pre-down block instead of stacking duplicates and stale IPs.
- Rule priority allocation fixed -- rules get 100, 110, 120... instead of all landing on priority 100; the networkd/netplan priority formula is clamped against negative values for low-numbered pre-existing tables.
- Missing
/etc/iproute2is created automatically instead of failing (directory mode pinned to 0755 under strict umasks). - Backups are never overwritten (counter suffix on same-second collisions) and the 10 most recent are kept.
- Relative
--log-filepaths no longer crash logging setup. netplan apply/networkctl reloadget realistic timeouts (60s/30s) instead of 10s.- Lock file is no longer unlinked on exit, closing a race where two later instances could both acquire the lock.
- Wrapper's Python version check accepts future major versions.
Release on top of v1.1.2.