Refactor SR Policy creation and add explicit SID validation - #395
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors SR Policy creation to replace the old sid_validate request flag with disable_path_compute and no_sid_validate, and moves explicit SID existence validation into the gRPC server (TED-backed). It also adds a CLI-supported “endpoint address” explicit-path mode that bypasses TED endpoint resolution/path computation while still allowing optional server-side SID validation.
Changes:
- Replace
sid_validatewithdisable_path_compute+no_sid_validatein the protobuf API and update example gRPC clients accordingly. - Add server-side SID existence validation (TED-backed) for explicit policies, plus new table utilities/tests for TED SID indexing.
- Update CLI behavior, schemas, docs, and scenario tests to cover the new validation/refusal behavior and warning messages.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tools/grpc/go/add-sr-policy/add_sr-policy.go | Updates example client to stop using removed SidValidate field. |
| tools/grpc/go/add-sr-policy-no-ls/add_sr-policy_no_ls.go | Updates example client to use DisablePathCompute + NoSidValidate. |
| test/scenario-test/explicit-path/test_explicit_path.py | Adds scenario assertions for stderr warnings and refusal without --no-sid-validate when TED is absent. |
| test/scenario-test/explicit-path/README.md | Documents the added refusal step in the scenario flow. |
| pkg/table/sid_validate.go | Introduces TED-backed SID indexing and missing-segment detection for validation. |
| pkg/table/sid_validate_test.go | Adds unit tests covering SR-MPLS, SRv6, uSID locator behavior, and missing-segment reporting. |
| pkg/server/grpc_server.go | Adds validateSIDs and wires server-side SID validation into SR policy creation. |
| pkg/server/grpc_server_test.go | Adds unit tests for server-side validation behavior and gRPC status codes/messages. |
| internal/pkg/version/version.go | Bumps version to 1.4.0. |
| examples/containerlab/srv6-explicit-path-l3vpn/README.md | Updates example output to include the CLI warning line. |
| examples/containerlab/sr-mpls-explicit-path/README.md | Updates example output to include the CLI warning line. |
| examples/containerlab/sr-mpls-explicit-path-l3vpn/README.md | Updates example output to include the CLI warning line. |
| cmd/pola/sr_policy_add.go | Refactors sr-policy add to support endpoint-address mode, new warning behavior, and improved error translation. |
| cmd/pola/README.md | Updates CLI docs to describe endpoint-address explicit-path mode and new --no-sid-validate semantics. |
| cmd/pola/docs/schemas/segment.json | Fixes/clarifies SID and address schema definitions (SR-MPLS vs SRv6, anyOf vs oneOf). |
| cmd/pola/docs/schemas/policy.json | Updates schema to model router-ID vs endpoint-address forms and related constraints. |
| api/pola/v1/pola.proto | Replaces sid_validate with reserved field + new disable_path_compute and no_sid_validate. |
| api/pola/v1/pola.pb.go | Regenerates Go bindings for the updated protobuf API. |
Files not reviewed (1)
- api/pola/v1/pola.pb.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
24c0de9 to
b3075dd
Compare
b3075dd to
99e8a44
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 18 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- api/pola/v1/pola.pb.go: Generated file
Suppressed comments (2)
cmd/pola/sr_policy_add.go:137
- translateCreateSRPolicyError always suggests using --no-sid-validate for codes.FailedPrecondition. If the server returns FailedPrecondition for reasons other than SID validation (e.g., TED needed for router-ID resolution/path computation), this hint becomes misleading. Reword the hint to be conditional.
if st.Code() == codes.FailedPrecondition {
return fmt.Errorf("%s\n hint: use --no-sid-validate to provision without validation", st.Message())
}
pkg/server/grpc_server.go:240
- When buildSegmentList fails due to TED being disabled/empty, the handler currently wraps the plain error and gRPC returns code=Unknown with a low-signal message (e.g., "failed to build segment list: ted is disabled"). Since this PR introduces explicit FailedPrecondition handling for TED-related validation, consider translating these specific TED readiness errors into codes.FailedPrecondition as well (with a user-facing message and guidance to use disable_path_compute / srcAddr+dstAddr when appropriate).
segmentList, srcAddr, dstAddr, err := buildSegmentList(s, req, disablePathCompute)
if err != nil {
return nil, fmt.Errorf("failed to build segment list: %w", err)
}
99e8a44 to
dcb873e
Compare
a75234d to
64f0b13
Compare
64f0b13 to
144af1d
Compare
5809b56 to
c2b2bac
Compare
c2b2bac to
b78f9de
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- api/pola/v1/pola.pb.go: Generated file
Suppressed comments (2)
pkg/table/sid_validate.go:124
- Locator containment is applied to every SRv6 segment, not just uSID containers. In normal full-SID mode, an unadvertised SID under the same locator as any advertised End SID will therefore pass validation, defeating the explicit SID existence check.
newEnrichedSegmentalready recordsusidModeinSegmentSRv6.USid; guard this fallback with that flag and update the containment tests accordingly.
// Fall back to locator containment for uSID containers.
locBits := 0
if len(s.Structure) == 4 {
locBits = int(s.Structure[0]) + int(s.Structure[1])
}
for loc := range idx.srv6Locators {
pkg/table/sid_validate.go:55
- When a node has not advertised an SRGB yet, this registers the Prefix-SID index itself as an MPLS label (
0 + SidIndex). That can falsely validate a label that the TED cannot actually derive; the new test even records this as a known non-guarantee. Do not index a Prefix-SID until its SRGB/label semantics are known.
if p != nil && p.SidIndex > FirstSIDIndex {
idx.mplsSIDs[node.SrgbBegin+p.SidIndex] = struct{}{}
| if req.GetNoSidValidate() { | ||
| s.logger.Warn("skipping SID validation: no_sid_validate specified", | ||
| zap.String("policyName", policy.GetPolicyName()), | ||
| zap.Uint32("color", policy.GetColor()), | ||
| ) | ||
| return nil | ||
| } | ||
|
|
||
| // Skip validation for TED-computed dynamic paths. | ||
| if policy.GetType() == pb.SRPolicyType_SR_POLICY_TYPE_DYNAMIC && !req.GetDisablePathCompute() { | ||
| return nil | ||
| } | ||
|
|
||
| if table.HasUnknownSegmentType(segmentList) { | ||
| return status.Errorf(codes.InvalidArgument, "segment list contains a segment with an unrecognized SID family") | ||
| } | ||
|
|
||
| if table.HasMixedSegmentTypes(segmentList) { | ||
| return status.Errorf(codes.InvalidArgument, "segment list contains mixed SR-MPLS and SRv6 SIDs") | ||
| } |
|
|
||
| type Segment interface { | ||
| SidString() string | ||
| GetFamily() SegmentFamily |
Description
This PR refactors SR Policy creation and adds server-side explicit SID validation.
The main changes are:
sid_validatebehavior with:disable_path_computeno_sid_validatesrcAddr/dstAddr) without TED-based endpoint resolution or path computation.Type of change
How was this tested?
make test-scenarioexamples/containerlab/sr-mpls-explicit-pathexamples/containerlab/sr-mpls-explicit-path-l3vpnexamples/containerlab/srv6-explicit-path-l3vpnexamples/containerlab/srv6-usid-dynamic-pathexamples/containerlab/srv6-usid-dynamic-path-loose-source-routing-sfcChecklist
make cipasses locally