Skip to content

feat: protocol-level filtering in ACL rules#91

Merged
LiranCohen merged 1 commit into
mainfrom
feat/protocol-filter
Feb 27, 2026
Merged

feat: protocol-level filtering in ACL rules#91
LiranCohen merged 1 commit into
mainfrom
feat/protocol-filter

Conversation

@LiranCohen

Copy link
Copy Markdown
Contributor

Closes #64

Summary

  • Map ACL rule proto field (tcp, udp, icmp, *) to IP protocol numbers in the packet filter pipeline
  • The acl-policy.json schema already defined the proto field but buildFilterRules() was ignoring it — this change makes the engine actually enforce it

Changes

File Change
internal/control/types.go Add IPProto []int field to FilterRule
internal/control/dwnclient.go Add protoToIPProto() mapping function; wire Proto into buildFilterRules()
internal/engine/convert.go Carry IPProto through convertFilterRules()tailcfg.FilterRule.IPProto
internal/control/control_test.go Tests for protoToIPProto() and buildFilterRules with protocol filtering
internal/engine/convert_test.go Test for convertFilterRules carrying IPProto to tailcfg

Protocol mapping

ACL proto IANA numbers Notes
tcp [6] TCP only
udp [17] UDP only
icmp [1, 58] ICMPv4 + ICMPv6
* or empty nil All protocols (meshnet default: TCP, UDP, ICMP)

How it works

  1. buildFilterRules() calls protoToIPProto(rule.Proto) for each ACL rule
  2. The resulting []int is stored in FilterRule.IPProto
  3. convertFilterRules() copies IPProto to tailcfg.FilterRule.IPProto
  4. meshnet's MatchesFromFilterRules() already handles IPProto — it filters the protocol list to valid ipproto.Proto values and uses defaultProtos (TCP, UDP, ICMPv4, ICMPv6) when nil

Verification

  • go build ./... — zero errors
  • go vet ./... — zero warnings
  • go test ./... -count=1 -race — all tests pass, no data races

Map ACLRule.Proto ('tcp', 'udp', 'icmp', '*') to IP protocol numbers
in the packet filter pipeline:

- Add IPProto []int field to control.FilterRule
- Add protoToIPProto() mapping: tcp→6, udp→17, icmp→1+58
- Wire Proto into buildFilterRules() when constructing filter rules
- Carry IPProto through convertFilterRules() to tailcfg.FilterRule
- meshnet's MatchesFromFilterRules already handles IPProto correctly

The acl-policy.json schema already defined the 'proto' field; this
change makes the engine actually enforce it.
@LiranCohen LiranCohen merged commit 8b05ac6 into main Feb 27, 2026
2 checks passed
@LiranCohen LiranCohen deleted the feat/protocol-filter branch February 27, 2026 15:49
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.

feat: protocol-level filtering in ACL rules

1 participant