Skip to content

[3/3] Add CGROUP_SOCK_ADDR matcher support#465

Open
yaakov-stein wants to merge 8 commits intofacebook:mainfrom
yaakov-stein:add_cgroup_sock_addr_matcher_support
Open

[3/3] Add CGROUP_SOCK_ADDR matcher support#465
yaakov-stein wants to merge 8 commits intofacebook:mainfrom
yaakov-stein:add_cgroup_sock_addr_matcher_support

Conversation

@yaakov-stein
Copy link
Contributor

@yaakov-stein yaakov-stein commented Mar 8, 2026

Stacked PRs:

Completes CGROUP_SOCK_ADDR support (#355) by implementing matcher codegen, per-hook matcher validation, CLI counter semantics, E2E tests, and documentation.

Summary

#459 added the CGROUP_SOCK_ADDR flavor with only default-verdict support and no working matchers. This adds matcher codegen so rules can actually match against fields available in the bpf_sock_addr context.

Matcher codegen

The _bf_cgroup_sock_addr_gen_inline_matcher() callback loads fields directly from struct bpf_sock_addr (user_ip4/user_ip6, user_port, family, protocol) and delegates to the shared bf_cmp_*() functions from #464. No packet parsing prologue is needed.

Supported matchers:

  • Meta: l3_proto, l4_proto, probability, dport
  • IPv4 (CONNECT4 only): daddr, dnet, proto
  • IPv6 (CONNECT6 only): daddr, dnet
  • TCP/UDP: dport

Unsupported matchers are enforced at validation time via unsupported_hooks flags in matcher.c, so invalid rules are rejected before codegen.

CLI counter display

CGROUP_SOCK_ADDR hooks intercept connect() syscalls, not packets. The CLI now prints calls instead of packets and bytes for these hooks.

E2E tests

New tests/e2e/hooks/ directory for per-hook behavioral tests that combine dry-run validation (supported + unsupported matchers) with sandbox testing in an isolated cgroup. Each supported matcher is verified by attaching a chain and confirming that matching traffic is dropped and, where possible, non-matching traffic passes through. Also adds CGROUP_SOCK_ADDR coverage to chain_attach.sh.

Documentation

Updates bfcli.rst and daemon.rst: new hooks in the hooks list, cgpath option, counter semantics, REDIRECT incompatibility, and a connection-level note for meta.probability.

Testing

  • unit + e2e
  • e2e.hooks for both CONNECT4 and CONNECT6
  • e2e.cli.chain_attach with new CGROUP_SOCK_ADDR section
  • e2e.rulesets with new .bf files for both CONNECT4 and CONNECT6

@meta-cla meta-cla bot added the cla signed label Mar 8, 2026
@yaakov-stein yaakov-stein changed the title Add CGROUP_SOCK_ADDR matcher support [3/3] Add CGROUP_SOCK_ADDR matcher support Mar 8, 2026
@github-actions
Copy link

github-actions bot commented Mar 8, 2026

Claude: review of facebook/bpfilter #465 (2cb9ddc)

Must fix

  • Pointer dereference before assert() in bfc_chain_dumpsrc/bfcli/print.c:89 — Fixed: is_pkt_hook is now declared first, assigned after assert(chain).
  • Pointer dereference before assert() in _bf_cgroup_sock_addr_gen_inline_matchersrc/bpfilter/cgen/cgroup_sock_addr.c:226 — Fixed: function restructured with asserts before any dereference.
  • log incompatibility with cgroup_sock_addr not documenteddoc/usage/bfcli.rst:393 — The log line now includes the cgroup_sock_addr restriction note.
  • Connect6 test missing 4 unsupported-matcher negative teststests/e2e/hooks/cgroup_sock_addr_connect6.sh:25 — connect4 tests 13 unsupported matchers; connect6 tests only 11. Missing: meta.mark, tcp.sport, tcp.flags, udp.sport.
  • Per-layer protocol dedup drops guards for mixed-protocol rulessrc/bpfilter/cgen/program.c:312checked_layers deduplicates by layer, not by (layer, hdr_id). A rule with e.g. tcp.dport eq 80 udp.dport eq 80 emits only one L4 protocol check (for whichever comes first). Pre-patch, each per-protocol matcher emitted its own guard.

Suggestions

  • Inconsistent static function namingsrc/bpfilter/cgen/cgroup_sock_addr.c:76 — Fixed: all helpers now use _bf_cgroup_sock_addr_* prefix.
  • _bf_prefix_to_mask lacks bounds checksrc/bpfilter/cgen/matcher/cmp.c:56memset(mask, 0xff, prefixlen / 8) does not verify prefixlen / 8 <= mask_len. Adding assert(prefixlen <= mask_len * 8) would provide defense-in-depth.
  • BF_MATCHER_SET bypasses unsupported_hooks validation — Fixed: BF_MATCHER_SET now has a proper _bf_matcher_metas entry with unsupported_hooks.
  • Document per-hook matcher availabilitydoc/usage/bfcli.rstip4.daddr is CONNECT4-only, ip6.daddr is CONNECT6-only, and many matchers are blocked on cgroup_sock_addr. A summary note (like those for meta.flow_hash and REDIRECT) would save users from discovering restrictions by trial and error.
  • meta.mark compatibility note incompletedoc/usage/bfcli.rst:547 — The meta.mark docs say "Incompatible with BF_HOOK_XDP hook" but the code also blocks it on both BF_HOOK_CGROUP_SOCK_ADDR_CONNECT4 and BF_HOOK_CGROUP_SOCK_ADDR_CONNECT6.
  • Cgroup directory leaks on early test failure in chain_attach.shtests/e2e/cli/chain_attach.sh:44 — The cgroup at CGROUP_PATH is mkdir -p'd but the EXIT trap is not updated to include rmdir.
  • meta.flow_probability missing unsupported_hooks for cgroup_sock_addr (dismissed) — src/libbpfilter/matcher.c:954 — Author disagrees this is an issue.
  • Zero ifindex in cgroup_sock_addr prologuesrc/bpfilter/cgen/cgroup_sock_addr.c:42 — The prologue zeroes pkt_size because the counter elfstub reads it unconditionally, but ifindex is left uninitialized. While meta.iface is currently blocked by unsupported_hooks, zeroing ifindex would be consistent and defensive.
  • Connect4 missing unsupported-matcher dry-run for IPv6/meta matcherstests/e2e/hooks/cgroup_sock_addr_connect4.sh — connect4's unsupported section omits ip6.saddr, ip6.snet, ip6.nexthdr, ip6.dscp, icmpv6.type, icmpv6.code, meta.flow_hash, meta.flow_probability.
  • Connect6 dry-run coverage asymmetry with connect4tests/e2e/hooks/cgroup_sock_addr_connect6.sh — connect4 tests meta.l4_proto not, meta.dport not, tcp.dport range, udp.dport range but connect6 omits these operator variants.

Nits

  • Commit 6 (cli:) has empty body — Style guide says descriptions should explain "why". A brief sentence about counter semantics for non-packet hooks would help.
  • Commit 8 (doc:) has empty body — Similarly, a brief description of which docs were updated and why.
  • Removed blank line between test groupstests/e2e/CMakeLists.txt — Blank line between matchers and rules groups was removed; existing file separates groups with blank lines.
  • bf_cmp_value clobber docs incomplete for size 8src/bpfilter/cgen/matcher/cmp.h:18 — Doxygen says "Clobbers BPF_REG_2 for size 4/8" but size 8 also clobbers BPF_REG_3 via _bf_cmp_build_imm64.
  • Commit 7 title missing e2e: subcomponent — Title is tests: add per-hook behavioral tests... but all changes are under tests/e2e/; convention uses tests: e2e: (see tests: e2e: add syscall wrappers in setuserns).

Separate comparison logic from data loading in matcher codegen.
bf_cmp_value, bf_cmp_masked_value, bf_cmp_range, and bf_cmp_bitfield
encapsulate the BPF bytecode patterns previously duplicated across
ip4.c, ip6.c, tcp.c, udp.c, icmp.c, and meta.c. No behavioral change;
emitted bytecode is identical.
Remove ip4.c/h, ip6.c/h, tcp.c/h, udp.c/h, and icmp.c/h by absorbing
their loading logic into packet.c. Protocol guards and header loads now
go through bf_stub_rule_check_protocol and bf_stub_load_header driven
by _bf_matcher_metas, while comparisons use the shared cmp.c functions.

This centralises all packet matcher codegen in a single dispatch point,
making it straightforward to add new flavor-specific dispatch without
touching per-protocol files.
Add BF_FLAVOR_CGROUP_SOCK_ADDR and
BF_HOOK_CGROUP_SOCK_ADDR_CONNECT4/CONNECT6 to support
BPF_PROG_TYPE_CGROUP_SOCK_ADDR programs. This is the foundational
enum/mapping work for sock_addr filtering. All mapping tables (hook
strings, flavor, prog_type, attach_type), BPF type constants, link
creation, and hookopts are updated.

All existing matchers are blocked on the new hooks via
unsupported_hooks. Flavor ops are registered as NULL and codegen is
added in a follow-up.
Implement bf_flavor_ops for BF_FLAVOR_CGROUP_SOCK_ADDR so chains
with a default policy can be loaded and attached to a cgroup.
@yaakov-stein yaakov-stein force-pushed the add_cgroup_sock_addr_matcher_support branch from d0d91e6 to 8f1a356 Compare March 12, 2026 21:29
Replace the -ENOTSUP stub with a dispatcher that loads fields from
bpf_sock_addr (user_ip4, user_ip6, user_port, protocol) and reuses the
shared bf_cmp_*() comparison functions. Update unsupported_hooks to
unblock the supported matchers on CONNECT4/CONNECT6 hooks.
@yaakov-stein yaakov-stein force-pushed the add_cgroup_sock_addr_matcher_support branch from 8f1a356 to 2bf98d5 Compare March 12, 2026 21:33
@yaakov-stein yaakov-stein force-pushed the add_cgroup_sock_addr_matcher_support branch from 2bf98d5 to a970627 Compare March 12, 2026 21:37
@yaakov-stein yaakov-stein force-pushed the add_cgroup_sock_addr_matcher_support branch 2 times, most recently from c4fbebb to 5f658dd Compare March 12, 2026 22:32
@yaakov-stein yaakov-stein marked this pull request as ready for review March 12, 2026 22:32
Introduce a tests/e2e/hooks/ directory for tests that combine dry-run
validation with behavioral sandbox testing on a per-hook basis. Each
test verifies every supported matcher against actual traffic in an
isolated cgroup, rather than only checking dry-run acceptance.
@yaakov-stein yaakov-stein force-pushed the add_cgroup_sock_addr_matcher_support branch from 5f658dd to 2cb9ddc Compare March 12, 2026 22:46
Copy link
Contributor

@qdeslandes qdeslandes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, waiting for other PRs to be merged before approving.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants