Skip to content

feat(gtpv2c): add finite S2b F-TEID receive policy - #694

Draft
VerifiedOrganic wants to merge 3 commits into
mainfrom
feat/687-s2b-fteid-receive-policy-wm-20260815
Draft

feat(gtpv2c): add finite S2b F-TEID receive policy#694
VerifiedOrganic wants to merge 3 commits into
mainfrom
feat/687-s2b-fteid-receive-policy-wm-20260815

Conversation

@VerifiedOrganic

@VerifiedOrganic VerifiedOrganic commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements only the reusable SDK primitive in Refs #687.

  • Adds opaque, finite, copy-by-value S2bCreateSessionResponseReceivePolicy state. The strict default remains control {32} and user-plane {33}; callers may independently opt into control {32, 7} and user-plane {33, 5}.
  • Adds only the one-shot decode_create_session_response_summary_with_receive_policy entry point. Existing structural, typed, and no-policy projection APIs remain strict.
  • Centralizes accepted-response endpoint selection so ProcedureAware validation and typed projection use the same role-specific resolver and first-retained singleton semantics.
  • Keeps canonical builders strict: every emitted control role is type 32 and every present nested user-plane role is type 33, including recursively nested grouped input and rejected-response additions.
  • Preserves the historical missing-endpoint requiredness distinction: generic ProcedureAware decode may retain an EBI-only response, while typed response projection reports the existing missing-endpoint variant.

Exact revision

  • Reviewed base commit: 9b85ae1f8a98f5fe9f9f77225f72e5364840b5b1
  • Reviewed base tree: 4cb0806bd910c32a3693dfa4f3237360c0f4385e
  • Pushed head commit: a27449e7c71c7ea85f95f810b6ae02aa583d3b77
  • Pushed head tree: 9006ac04e38060bf8036cf74c5a5f45ead6de75b
  • Base/head branches: main / feat/687-s2b-fteid-receive-policy-wm-20260815
  • Diff: 8 files, 1,235 insertions, 155 deletions

API and compatibility contract

The policy has private role state, no numeric or collection constructor, strict Default, and consuming named opt-in methods. It is copied into one decode. The policy applies only to accepted S2b Create Session Response PGW control and user-plane receive roles. It cannot broaden other GTPv2-C procedures or profiles, and no general policy-aware message decoder was added that could lose the policy before projection.

Endpoint selection retains ProcedureAware first-wins behavior per singleton key. A later duplicate cannot repair an invalid retained value; distinct table-defined nested instances remain independently eligible, and the first authoritative Bearer Context cannot be bypassed. Existing mismatch variants and static error strings remain stable.

Changed files

  • CHANGELOG.md
  • crates/opc-proto-gtpv2c/CONFORMANCE.md
  • crates/opc-proto-gtpv2c/README.md
  • crates/opc-proto-gtpv2c/src/lib.rs
  • crates/opc-proto-gtpv2c/src/s2b.rs
  • crates/opc-proto-gtpv2c/tests/s2b_profile_builders.rs
  • crates/opc-proto-gtpv2c/tests/s2b_typed.rs
  • docs/implementation-status.md

RED and mutation evidence

  • Initial RED: the focused typed-response test target failed to compile with 12 missing policy/helper/method errors before implementation.
  • Fix-removal mutation: replacing both opt-in predicates with strict-only checks made the complete finite policy matrix fail on the first opted-in role case; restoring the implementation returned the exact matrix test to green.
  • Adversarial role-set mutation: swapping the control and user-plane compatibility sets made the role-swap defense observe an unexpected success; restoring control-to-7 and user-plane-to-5 returned both the role-set defense and complete matrix to green.
  • First-occurrence defenses cover same-key poison-before-valid, accepted-before-malformed duplicate, distinct-instance selection, and later-Bearer-Context repair attempts.
  • The final privacy review found the response builders' derived Debug; commit a27449e7 replaces it with bounded, value-free custom formatting and adds sentinel defenses.

Local verification

The exact consolidated gate was rerun from its first command after recovery and completed through the shared opc-heavy lock with exit 0, using repository-default Cargo parallelism and no target/cache/wrapper/job overrides.

Affected package and documentation:

  • cargo fmt --all --check
  • git diff --check
  • cargo clippy --locked -p opc-proto-gtpv2c --all-targets --all-features -- -D warnings
  • cargo test --locked -p opc-proto-gtpv2c --all-features (46 unit tests, 44 typed S2b tests, 13 builder tests, and all other integration/doc tests passed)
  • RUSTDOCFLAGS='-D warnings' cargo doc --locked -p opc-proto-gtpv2c --all-features --no-deps

Full repository gates prescribed by CONTRIBUTING.md:

  • cargo clippy --locked -p opc-persist --all-targets --no-default-features -- -D warnings
  • cargo test --locked -p opc-persist --no-run
  • All four serialized opc-persist security targets passed (12 + 6 + 7 + 13 tests).
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features --quiet -- --test-threads=4
    • The long real-mTLS suite passed 44 tests with 2 ignored in 849.80s.
    • The five-test OpenRaft stop/restart target passed, including real_three_and_five_process_openraft_sqlite_stop_restart_foundation, in 80.00s.
    • Generated-code integration fixtures, including real-mTLS gNMI/NETCONF cases, completed successfully.
  • Operator /usr/local/go/bin/go vet ./... and /usr/local/go/bin/go test ./... passed with Go 1.26.6.
  • kubectl kustomize operators/sdk-reference-operator/config/default passed.

Hosted exact-head status

All four hosted workflows for exact head a27449e7c71c7ea85f95f810b6ae02aa583d3b77 reached terminal success. The complete 44-check set is green: 43 checks passed and the scheduled-only Scheduled fuzz job was skipped. This includes the final dependent Rust workspace aggregate.

Fresh independent exact-head review

A bounded read-only adversarial review independently pinned base 9b85ae1f / tree 4cb0806b and head a27449e7 / tree 9006ac04 and returned no actionable findings. It specifically rechecked finite immutable exact-role state, strict defaults and legacy overloads, the shared first-retained resolver and no-repair behavior, typed projection alignment, recursive strict builder confinement, static/value-free errors and custom Debug, test defenses, and the generic downstream boundary.

Privacy treatment

Typed mismatch errors remain stable, static, and value-free. Endpoint Debug surfaces expose only bounded role/presence metadata. Accepted and rejected response summaries and both response builders use custom redacted Debug implementations, so TEIDs, IP addresses, response identifiers, and private-data payloads are not formatted. Tests exercise sentinel endpoint, identifier, address, and private-data values without including them in diagnostics.

Downstream boundary and exclusions

This is a generic SDK primitive for downstream ePDG #132. It does not edit ePDG, choose when compatibility is enabled, or add product policy. It does not accept arbitrary interface types, alter strict builder emission, add a mutable policy path, add a permissive projection overload, change unrelated procedures/profiles, add dependencies, or touch CRC/kernel state.

Checklist

  • Exact local validation gates pass (cargo fmt, warning-denied affected/workspace Clippy, focused/full Rust tests, docs, Go vet/tests, Kustomize).
  • Commits use VerifiedOrganic <verifiedorganic@sent.com> and are signed off.
  • Documentation updated (crate rustdoc, README, conformance, changelog, and implementation status).
  • Positive, negative, first-occurrence, exact-role, builder, overload, projection, privacy, and persistence defenses pass.
  • No new dependencies.
  • Exact-head hosted checks terminal: 43 passed, one scheduled-only skip.
  • Fresh independent exact-head adversarial review: no actionable findings.

Signed-off-by: VerifiedOrganic <verifiedorganic@sent.com>
Signed-off-by: VerifiedOrganic <verifiedorganic@sent.com>
Signed-off-by: VerifiedOrganic <verifiedorganic@sent.com>
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.

1 participant