Repository navigation
Raw Ethernet on macOS through BPF - #31
Merged
Merged
Conversation
Contributor
|
Thanks for the PR. I will add Mac to the CI and then merge. |
Preserve the macOS transport addition alongside the mailbox deadline fix and shared Linux/macOS CI timing policy. Resolve the changelog conflict by retaining both user-facing entries. Validation: mix compile --warnings-as-errors; mix test (478 passed, 30 excluded; BPF wire tests require macOS fixtures). Co-authored-by: Codex <codex@openai.com>
Compile into atomically created owner-only temporary directories and reuse only builds published by this VM. Ignore pre-existing executables, serialize concurrent builds, and rebuild on source-content changes. Report exited helper ports as closed before explicit transport cleanup. Exercise the production BPF receive path over an isolated macOS feth pair in the shared mix ci workflow. Configured BPF setup failures now fail instead of silently excluding the tests. Document the fixture and remove the test-only see-sent helper variant. Validation: mix ci passed locally (484 tests; 30 hardware/platform tests excluded), including six portable build-security/lifecycle regressions. macOS wire validation follows on the PR runner before merge. Co-authored-by: Codex <codex@openai.com>
Replace the pending reference with the validated implementation commit. No code changes; validation remains the preceding successful mix ci run. Co-authored-by: Codex <codex@openai.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
{:raw, %{interface: "en7"}}now works on macOS, so a rack on a desk can be scanned and run from a Mac. Linux is unchanged.macOS has no
AF_PACKETsockets. Whole Ethernet frames go through a BPF device (/dev/bpfN) instead, withioctlcalls the BEAM cannot make. So this adds:priv/bpf/ethercat_bpf.c, a small C program run as an Erlang port (a process of its own, no NIF). It opens a BPF device on the interface, lets only EtherType 0x88A4 through (with or without one VLAN tag), never receives what the machine itself sent, and passes frames to and from the BEAM over stdio in{:packet, 2}.EtherCAT.Bus.Transport.Bpf, theEtherCAT.Bus.Transportbehaviour on top of that port.EtherCAT.Bus.Transport.raw/0, which givesBpfon macOS andRawSocketeverywhere else.Link.SingleandLink.Redundantuse it where they usedRawSocketby default.Choices you may want different
cc, beside its source or in the temporary directory. That keeps the build as it is for everyone on Linux: noelixir_make, no compiler step. It does mean a Mac needs the Xcode command line tools at run time. If you would rather have a build-time compiler, I can change it.RawSocketdoes withSO_TIMESTAMPING. Every round trip includes the time through the port, some tens of microseconds. Fine for a desk, not for timing that matters.set_active_once/1andrearm/1have nothing to do, anddrain/1empties the mailbox of waiting frames.Not covered
EtherCAT.Simulator.Transport.Raw.Endpoint) still usesAF_PACKET, so the raw simulator and redundant-ring tests remain Linux only.EtherCAT.Bus.InterfaceInfostill reads sysfs; the BPF transport gets the hardware address from the port program and does not use it.How it was tested
On hardware, from a Mac (macOS 15, Apple Silicon) through a Realtek RTL8153 USB adapter, against an EK1100 with EL7037 ×3, EL1809 ×2, EL1088, EL2535 and EL2809:
EtherCAT.Scan.scan/1finds all nine devices in about 175 ms, the same on repeated scans.In the suite,
test/ethercat/bus/transport/bpf_test.exs(7 tests, tagged:bpf). They need no second interface and no root: a second port program is built from the same source with-DETHERCAT_BPF_SEE_SENT=1, so it receives what the first one sends on the same interface. They check the frame on the wire (destination, source, EtherType, payload, padding), the filter, VLAN tags, that the transport does not hear itself, draining, and a port program that dies.They run only on macOS with
ETHERCAT_BPF_INTERFACEset to an interface that is not on a network, such as a USB adapter with no cable in it, since they send frames on it; elsewhere they are excluded:ETHERCAT_BPF_INTERFACE=en17 mix test test/ethercat/bus/transport/bpf_test.exsOn macOS the rest of the suite has 83 failures before and after this change, all from the simulator binding
127.0.0.2, which macOS only has aftersudo ifconfig lo0 alias 127.0.0.2. I have not run the suite on Linux; CI will.Access on macOS
Opening
/dev/bpf*needs root, or membership of theaccess_bpfgroup that Wireshark's ChmodBPF sets up.🤖 Generated with Claude Code