Add bind classify variants that select the WFP filter by callout key#315
Draft
mikeagun wants to merge 1 commit into
Draft
Add bind classify variants that select the WFP filter by callout key#315mikeagun wants to merge 1 commit into
mikeagun wants to merge 1 commit into
Conversation
mikeagun
pushed a commit
to mikeagun/ebpf-for-windows
that referenced
this pull request
Jul 15, 2026
usersim_fwp_bind_ipv4/ipv6_by_callout() is not yet in usersim upstream. Point the external/usersim submodule URL at the mikeagun/usersim fork so CI can resolve the submodule commit while microsoft/usersim#315 is in review. Revert to https://github.com/microsoft/usersim.git once microsoft#315 lands. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c2ba0624-5e1d-4385-9972-eec1b8c595f1
usersim's test_callout() selects a single WFP filter by (layer, sublayer) first-match. When multiple callouts are registered at the same layer and sublayer -- for example the legacy bind callout and the CGROUP_SOCK_ADDR bind callout, both at ALE_RESOURCE_ASSIGNMENT -- that first-match can dispatch to the wrong callout, so a test cannot reliably target a specific callout. Add usersim_fwp_bind_ipv4_by_callout() / usersim_fwp_bind_ipv6_by_callout(), which select the filter bound to a caller-supplied callout key via a new get_fwpm_filter_by_callout_under_lock() helper. test_callout() and test_bind_ipv4()/test_bind_ipv6() take an optional callout_key; when null, behavior is unchanged (layer+sublayer first-match), so existing callers are unaffected. This lets a consumer (e.g. the ebpf-for-windows netebpfext bind tests) exercise a specific bind callout explicitly even when multiple bind callouts share a WFP layer. The public _by_callout wrappers assert a non-null callout_key. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c2ba0624-5e1d-4385-9972-eec1b8c595f1
mikeagun
force-pushed
the
users/mikeagun/fwp-bind-select-by-callout
branch
from
July 15, 2026 22:47
7537d02 to
6f836e8
Compare
mikeagun
pushed a commit
to mikeagun/ebpf-for-windows
that referenced
this pull request
Jul 15, 2026
usersim_fwp_bind_ipv4/ipv6_by_callout() is not yet in usersim upstream. Point the external/usersim submodule URL at the mikeagun/usersim fork so CI can resolve the submodule commit while microsoft/usersim#315 is in review. Revert to https://github.com/microsoft/usersim.git once microsoft#315 lands. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c2ba0624-5e1d-4385-9972-eec1b8c595f1
There was a problem hiding this comment.
Pull request overview
This PR extends the usersim WFP test harness to allow bind classify tests to target a specific callout when multiple callouts (and filters) coexist on the same WFP layer/sublayer, avoiding accidental dispatch to the wrong callout due to first-match ordering.
Changes:
- Add optional
callout_keyparameters tofwp_engine_t::test_callout()and bind helpers to select a filter by callout key when provided. - Introduce
get_fwpm_filter_by_callout_under_lock()to locate filters by(layer, calloutKey)instead of(layer, sublayer)first-match. - Add exported APIs
usersim_fwp_bind_ipv4_by_callout()/usersim_fwp_bind_ipv6_by_callout()for callers that want explicit callout selection.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/fwp_um.h | Adds optional callout_key plumbing and a helper to find a filter by callout key under lock. |
| src/fwp_um.cpp | Implements callout-key-based filter selection in test_callout() and adds new exported bind-by-callout entry points. |
| inc/usersim/fwp_test.h | Exposes the new bind-by-callout APIs to consumers with documentation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+302
to
+316
| // Select a filter by its bound callout key at the given layer. This disambiguates the case where | ||
| // multiple callouts (each with its own filter) are registered at the same WFP layer and sublayer | ||
| // (e.g., the legacy bind callout and the CGROUP_SOCK_ADDR bind callout both at | ||
| // ALE_RESOURCE_ASSIGNMENT). Selecting the filter by its callout key lets a test target a specific | ||
| // callout explicitly instead of relying on layer+sublayer first-match ordering. | ||
| _Ret_maybenull_ const FWPM_FILTER* | ||
| get_fwpm_filter_by_callout_under_lock(_In_ const GUID& layer_guid, _In_ const GUID& callout_key) | ||
| { | ||
| for (auto& [first, filter] : fwpm_filters) { | ||
| if (memcmp(&filter.layerKey, &layer_guid, sizeof(GUID)) == 0 && | ||
| memcmp(&filter.action.calloutKey, &callout_key, sizeof(GUID)) == 0 && filter.rawContext != 0) { | ||
| return &filter; | ||
| } | ||
| } | ||
| return nullptr; |
Comment on lines
+1080
to
+1085
| FWP_ACTION_TYPE | ||
| usersim_fwp_bind_ipv4_by_callout(_In_ fwp_classify_parameters_t* parameters, _In_ const GUID* callout_key) | ||
| { | ||
| CXPLAT_DEBUG_ASSERT(callout_key != nullptr); | ||
| return fwp_engine_t::get()->test_bind_ipv4(parameters, callout_key); | ||
| } |
Comment on lines
+1087
to
+1092
| FWP_ACTION_TYPE | ||
| usersim_fwp_bind_ipv6_by_callout(_In_ fwp_classify_parameters_t* parameters, _In_ const GUID* callout_key) | ||
| { | ||
| CXPLAT_DEBUG_ASSERT(callout_key != nullptr); | ||
| return fwp_engine_t::get()->test_bind_ipv6(parameters, callout_key); | ||
| } |
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.
Summary
fwp_engine_t::test_callout()selects a single WFP filter by(layer, sublayer)first-match. When multiple callouts (each with its own filter) are registered at the
same WFP layer and sublayer, that first-match can dispatch to the wrong callout, so a
test cannot reliably target a specific callout.
Concrete case (ebpf-for-windows): the legacy bind hook callout and the new
CGROUP_SOCK_ADDR bind hook callout both register filters at
FWPM_LAYER_ALE_RESOURCE_ASSIGNMENT_V4/V6with the default sublayer, so a sock_addrbind test could pass while actually exercising the legacy bind callout.
Change
Add
usersim_fwp_bind_ipv4_by_callout()/usersim_fwp_bind_ipv6_by_callout(), whichselect the filter bound to a caller-supplied callout key via a new
get_fwpm_filter_by_callout_under_lock()helper.test_callout()andtest_bind_ipv4()/test_bind_ipv6()take an optionalcallout_key; when null, behavioris unchanged (layer+sublayer first-match), so existing callers are unaffected.
Testing
Consumed and validated by the ebpf-for-windows netebpfext bind tests: a co-registration
test registers both bind callouts and verifies each bind entry dispatches to its intended
callout. usersim builds clean; existing callers are unaffected (default first-match path
unchanged).