Skip to content

fix(ethercat): drop iptables/IPv6 isolation; keep NIC tuning#127

Merged
thiagoralves merged 3 commits into
developmentfrom
fix/ethercat-iface-isolation
May 5, 2026
Merged

fix(ethercat): drop iptables/IPv6 isolation; keep NIC tuning#127
thiagoralves merged 3 commits into
developmentfrom
fix/ethercat-iface-isolation

Conversation

@thiagoralves
Copy link
Copy Markdown
Contributor

Summary

  • Removes the iptables INPUT -j DROP rule and IPv6 sysctl manipulation that ecat_iface_state_apply was installing on the EtherCAT NIC. On boards with a single NIC (Pi 4 in our case), this rule kills SSH/HTTP at the moment the master starts and leaves the device unreachable.
  • Keeps the NIC tuning that actually delivers jitter wins: ethtool coalescing (rx-usecs/tx-usecs=0), GRO/GSO/TSO offload disables, and SO_BUSY_POLL on the SOEM AF_PACKET socket. Those are NIC-local and don't break the management plane.
  • Drops the legacy iptables/IPv6 migration code too, since this branch comes off development and the iptables variant never shipped — no installed runtime needs the migration path.

ecat_iface_state_t now carries NIC-tuning fields only. The apply/revert API on ethercat_iface_state.{c,h} is the same shape, just the IP-stack chunk removed end-to-end.

Test plan

  • Deploy a runtime with EtherCAT configured to a Pi 4 (single NIC), confirm SSH and /api/status stay reachable while the master is in OPERATIONAL.
  • Confirm ethtool -c <iface> shows rx-usecs=0/tx-usecs=0 while running and the saved values restored after stop_loop.
  • Confirm ethtool -k <iface> shows GRO/GSO/TSO off while running and the saved values restored after stop_loop.
  • Bus jitter (period_us/latency_us in the editor stats panel) at parity with the previous iptables-installing build.

🤖 Generated with Claude Code

thiagoralves and others added 3 commits May 5, 2026 12:35
The plugin's "jitter isolation" path inserted `iptables -I INPUT 1
-i <iface> -j DROP` and wrote 1 to /proc/sys/net/ipv6/conf/<iface>/
disable_ipv6 on every master start. Both predate the dedicated bus
thread and were aimed at trimming softirq pressure on the EtherCAT
NIC by silencing inbound IP traffic that the kernel would otherwise
process. The win was real but small (a few µs of scheduling jitter
relief in the 99th percentile under heavy management traffic).

Cost was huge on single-NIC hardware: dropping all eth0 INPUT
disconnects SSH, the editor's runtime API, and ICMP — making the
Pi unreachable for the duration of the run. Pi 4 ships with one
Ethernet interface, so users hit this on their first build with
EtherCAT enabled. Same problem on any device whose management and
EtherCAT NICs are the same physical port.

Strip both. Keep the actual jitter mitigations that matter and don't
touch the rest of the system: NIC interrupt coalescing
(rx-usecs/tx-usecs=0 via ethtool -C), receive/transmit offloads
(GRO/GSO/TSO off via ethtool -K), and SO_BUSY_POLL on the SOEM raw
socket. Those are NIC-local settings that don't break management
paths.

The legacy-state migration code stays so users upgrading from a
previous version get the leftover iptables rule and IPv6 sysfs
flip rolled back automatically on first start (legacy_iptables_delete
+ legacy_write_ipv6_disabled in migrate_legacy_iso). After the old
state file is consumed, this runtime never inserts iptables rules
or flips IPv6 sysctls itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The iptables INPUT DROP + IPv6 disable was removed before this code
shipped, so there's no installed-in-the-wild legacy state to clean
up. Strip the migration shim:

  - migrate_legacy_iso() and its two helpers
    (legacy_iptables_delete, legacy_write_ipv6_disabled)
  - ECAT_LEGACY_ISO_FMT macro
  - the migrate_legacy_iso() call from ecat_iface_state_apply()

Also clean up stale references in adjacent files' comments — proc
helper banner, master.c socket-tuning header, config.c multi-master
single-owner note, header banners on iface_state.{c,h}.

ethercat_iface_state still keeps migrate_legacy_nic for users
upgrading from the pre-consolidation NIC-tuning file format
(ecat_nic_saved_<iface>.conf). That format DID ship.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
migrate_legacy_nic was reading /run/runtime/ecat_nic_saved_<iface>.conf,
the file format the pre-consolidation NIC-tuning code wrote (introduced
in b1d28fa, only ever included in v4.1.0-rc.1, never reached main).
No installed runtime ever produced that file, so the migration is dead
code — same situation as the iptables auto-restore we already removed.

Removes the migrate_legacy_nic function (55 lines duplicating
load_state's parser), the ECAT_LEGACY_NIC_FMT define, the call site in
ecat_iface_state_apply, and the migration note in the header.

recover_from_crash + load_state remain unchanged: they handle the
current-format file (/run/runtime/ecat_iface_<iface>.state) and that
path is real — it's what persist_state writes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thiagoralves thiagoralves merged commit d629ebf into development May 5, 2026
thiagoralves added a commit that referenced this pull request May 5, 2026
Picks up #127: drop migrate_legacy_nic — the legacy NIC state file
never shipped in any v4.0.x release (only v4.1.0-rc.1) so the migration
target doesn't exist on any installed runtime. 70 lines removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@thiagoralves thiagoralves deleted the fix/ethercat-iface-isolation branch May 5, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant