feat(bpf): implement allow_ethertype L2 gatekeeper#51
Open
leodido wants to merge 8 commits intofeat/multi-value-rodatafrom
Open
feat(bpf): implement allow_ethertype L2 gatekeeper#51leodido wants to merge 8 commits intofeat/multi-value-rodatafrom
allow_ethertype L2 gatekeeper#51leodido wants to merge 8 commits intofeat/multi-value-rodatafrom
Conversation
L2 EtherType allowlist program. Reads eth->h_proto and checks it against a configurable set of allowed EtherTypes. Drops frames with non-matching EtherTypes (TC_ACT_SHOT). Fail-closed on truncated Ethernet headers. Rodata: allowed[MAX_MULTI_VALUES] array + num_allowed count + slot for chain tail-calls. In standalone mode, bpf_tail_call silently fails and falls through to TC_ACT_OK. Also adds ETH_P_IPV6, ETH_P_ARP, and MAX_MULTI_VALUES defines to commons.bpf.h. Co-authored-by: Ona <no-reply@ona.com>
Add case program_allow_ethertype in parse_input() calling the existing
parse_ethertypes() helper. Add allow_ethertype to program_requires_input().
Add allow_ethertype to input_fields in api.lua as the first multi-value
entry: { field = "ethertypes", multi = true }.
Co-authored-by: Ona <no-reply@ona.com>
Add case program_allow_ethertype in load_chain_program(). Passes the full ethertypes struct (values[] + count) to set_chain_rodata(). Add allow_ethertype to program_supports_chaining(). Co-authored-by: Ona <no-reply@ona.com>
Flag tests (cli.flags.bats): - missing input, unknown name, invalid hex, duplicate values, trailing +, leading + Integration tests (cli.bats): - allow_ethertype ipv4+arp allows IPv4 ping (needs ARP + IPv4) - allow_ethertype ipv6 blocks IPv4 ping (IPv4 not in allowed set) - chain allow_ethertype:ipv4+arp,allow_ipv4:ADDR allows matching traffic CNI test (cni.bats): - allow_ethertype via CNI with ipv4+arp fixture Co-authored-by: Ona <no-reply@ona.com>
allow_ethertype L2 gatekeeper
Co-authored-by: Ona <no-reply@ona.com>
d722d44 to
ca8c0dd
Compare
__u8 overflows at 256. If MAX_MULTI_VALUES were ever increased beyond 255, the loop would never terminate. __u32 is safer and has no performance cost in BPF. Co-authored-by: Ona <no-reply@ona.com>
Add flag tests for consecutive ++ delimiter, too many values exceeding MAX_MULTI_VALUES, and zero hex value 0x0000. Fix missing trailing newlines in both test files. Add integration tests for chain blocking non-matching EtherType and for hex value input (0x0800+0x0806). Co-authored-by: Ona <no-reply@ona.com>
leodido
added a commit
that referenced
this pull request
May 4, 2026
- Fix bpf_printk NDEBUG macro: use do { } while(0) instead of
{ } while(0) to avoid dangling-else in unbraced if/else.
- Update standalone template comment to reflect multi-value rodata
and the slot default-zero contract.
- Add cross-representation duplicate test (ipv4+0x0800).
- Add integration test: allow_ethertype ipv4 without ARP blocks ping
(verifies ARP filtering at L2).
- Document chain ordering constraint: allow_ethertype must be first
because L3+ passthrough paths bypass downstream L2 filters.
- Document VLAN (802.1Q) limitation in both README.txt and docs.
Co-authored-by: Ona <no-reply@ona.com>
Fix bpf_printk no-op macro to use do { } while(0). The previous
{ } while(0) form causes a dangling-else compile error when used
in unbraced if/else blocks.
Document allow_ethertype chain ordering constraint: must be first
in a chain because L3+ programs pass through non-matching traffic
via TC_ACT_OK, bypassing downstream L2 filters. Document 802.1Q
VLAN limitation (outer EtherType is 0x8100, not the payload type).
Add test for cross-representation duplicate detection (ipv4+0x0800).
Add integration test verifying that allow_ethertype ipv4 without arp
blocks ping (ARP resolution fails at L2).
Update standalone template comment to reflect multi-value rodata
layout and the slot default-zero contract.
Co-authored-by: Ona <no-reply@ona.com>
8bc8686 to
25b8334
Compare
fntlnz
approved these changes
May 4, 2026
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.
L2 EtherType allowlist program. Drops Ethernet frames whose EtherType
is not in the allowed set. Accepts a
+-delimited list of symbolicnames (
ipv4,ipv6,arp) or0x-prefixed hex values.First multi-value input program, using the infrastructure from PR #49.
Changes
BPF program (
bpf/allow_ethertype.bpf.c): readseth->h_proto,linear scans
allowed[MAX_MULTI_VALUES]array. Match: tail-call next.No match:
TC_ACT_SHOT. Fail-closed on truncated Ethernet headers.Also adds
ETH_P_IPV6,ETH_P_ARP,MAX_MULTI_VALUEStocommons.bpf.h.Parser wiring:
case program_allow_ethertypeinparse_input()calling the existing
parse_ethertypes()helper. Added toprogram_requires_input().input_fieldsentry inapi.lua:{ field = "ethertypes", multi = true }.Chain loader:
case program_allow_ethertypeinload_chain_program(). Passes the full ethertypes struct (array + count)to
set_chain_rodata(). Added toprogram_supports_chaining().Tests: 6 flag validation tests (missing input, unknown name, invalid
hex, duplicates, trailing/leading
+). 3 integration tests (standaloneallow, standalone block, chain). 1 CNI test with fixture.
Docs:
README.txtanddocs/README.md.Stacked on
feat/multi-value-rodata) - multi-value input infrastructurefeat/dispatcher-chain) - chain CLIfeat/dispatcher-bpf) - dispatcher infrastructureallow_dnsprogram #43 (feat/allow-dns)allow_portprogram #42 (feat/allow-port)allow_ipprogram #41 (feat/allow-ip)