Skip to content

[yang] sonic-static-route: give STATIC_ROUTE_TEMPLATE_LIST the same non-key leaves as STATIC_ROUTE_LIST#28578

Open
bhouse-nexthop wants to merge 1 commit into
sonic-net:masterfrom
nexthop-ai:sonic-static-route-give-static-route
Open

[yang] sonic-static-route: give STATIC_ROUTE_TEMPLATE_LIST the same non-key leaves as STATIC_ROUTE_LIST#28578
bhouse-nexthop wants to merge 1 commit into
sonic-net:masterfrom
nexthop-ai:sonic-static-route-give-static-route

Conversation

@bhouse-nexthop

@bhouse-nexthop bhouse-nexthop commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Why I did it

STATIC_ROUTE_TEMPLATE_LIST (key: prefix) and STATIC_ROUTE_LIST (key: vrf_name prefix) model the same table for the two CONFIG_DB key shapes, but their non-key leaf sets had drifted apart. distance, nexthop-vrf, blackhole and the sidlist list existed only on the two-component form.

The daemons make no such distinction, so the model was describing less than the implementation supports:

  • bgpcfgd (bgpcfgd/managers_static_rt.py) splits the key first and then reads the fields unconditionally. split_key maps a bare prefix onto ('default', prefix), which is indistinguishable from default|<prefix> — after that point nothing downstream can tell the two shapes apart.
  • frrcfgd (frrcfgd/frrcfgd.py) rewrites a single-component STATIC_ROUTE key to <default-vrf>|<key> before handling it, and declares its consumed field set per table, not per key shape.

The practical effect: a one-component key can only match the template list, so every default-VRF static route carrying distance was rejected by YANG validation. That blocks the field on any device whose routes are stored in the collapsed form, and breaks restoring a saved configuration on such a device. It is not tool-specific — it reproduces through sonic_yang directly, so it affects the Generic Config Updater equally.

This also adds the route tag attribute, which frrcfgd reads for both key shapes and renders into FRR's tag (1-4294967295) static-route parameter, but which neither list declared. Value 0 expresses the absence of a tag, matching how frrcfgd represents an unset tag and mirroring the existing color leaf.

Deliberately not added: track. frrcfgd's static route map references it, but FRR's static route CLI has no such keyword — grep -c track staticd/static_vty.c returns 0, and the only occurrences in staticd are internal nexthop-tracking flags. Modelling it would legitimise a field the backend cannot apply.

How I did it

Every added leaf is copied verbatim from its sibling in STATIC_ROUTE_LIST — same type, pattern, default and description — so the two lists now differ only by the vrf_name key. The change is purely additive: it can only widen the accepted set and cannot invalidate a configuration that validates today.

Separately, three descriptions now state that the leaf is a comma-separated per-nexthop list. advertise, bfd* and color already documented this; distance, nexthop-vrf and blackhole did not, so the multi-value encoding was only discoverable by reading the (X,)*X pattern. This touches the pre-existing STATIC_ROUTE_LIST copies too, which keeps the two lists byte-identical apart from the vrf_name key.

Also adds the first test coverage for STATIC_ROUTE_TEMPLATE_LIST, which had none. Every existing static-route case exercised STATIC_ROUTE_LIST, which is how the drift went unnoticed — bfd* and color were each correctly added to both lists in a single commit, so keeping them in sync is the established convention.

How to verify it

YANG model tests:

pytest src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py -k STATIC_ROUTE

Verified end-to-end on gold218 (main.Nexthop.122165, libyang3 3.12.2) against sonic_yang — the reference validator the Generic Config Updater uses — by swapping only this model file in /usr/local/yang-models:

config before after
{'10.99.0.0/16': {'nexthop': ..., 'distance': '1'}} REJECTED ACCEPTED
{'10.99.1.0/24': {'nexthop': ..., 'blackhole': 'true'}} REJECTED ACCEPTED
{'10.99.2.0/24': {'nexthop': ..., 'nexthop-vrf': 'default'}} REJECTED ACCEPTED
{'10.99.3.0/24': {'nexthop': ..., 'tag': '1234'}} REJECTED ACCEPTED
{'default|10.99.4.0/24': {..., 'distance': '1'}} ACCEPTED ACCEPTED (unregressed)
{'10.99.5.0/24': {..., 'distance': '300'}} REJECTED (arity) REJECTED (pattern)

The last row is the important one: the invalid value is now rejected by the distance pattern on the template list —

Unsatisfied pattern - "300" does not conform to "((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?),)*..."
Data path: /sonic-static-route:sonic-static-route/STATIC_ROUTE/STATIC_ROUTE_TEMPLATE_LIST[prefix='10.99.5.0/24']/distance

— rather than the field being unreachable. The constraint is enforced, not merely accepted.

Consumers inherit the fix with no code change (models are loaded at runtime).

Which release branch to port

  • 202605
  • 202511
  • 202505

Tested branch (Please provide the tested image version)

  • master as of 20260722

Description for the changelog

[yang] sonic-static-route: allow distance, nexthop-vrf, blackhole and sidlist on default-VRF (bare-prefix) static routes, and add the route tag attribute to both key forms.

Link to config_db schema for YANG module changes

https://github.com/sonic-net/sonic-buildimage/blob/master/src/sonic-yang-models/doc/Configuration.md#static_route

A picture of a cute animal (not mandatory but encouraged)

…leaves as STATIC_ROUTE_LIST

Signed-off-by: Brad House - Nexthop <bhouse@nexthop.ai>
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@bhouse-nexthop
bhouse-nexthop requested a review from lguohan July 22, 2026 16:10
@bhouse-nexthop

Copy link
Copy Markdown
Collaborator Author

/azpw run

@mssonicbld

Copy link
Copy Markdown
Collaborator

⚠️ Notice: /azpw run only runs failed jobs now. If you want to trigger a whole pipline run, please rebase your branch or close and reopen the PR.
💡 Tip: You can also use /azpw retry to retry failed jobs directly.

Retrying failed(or canceled) jobs...

@mssonicbld

Copy link
Copy Markdown
Collaborator

Retrying failed(or canceled) stages in build 1171962:

✅Stage Test:

  • Job impacted-area-kvmtest-t1-lag-vpp by Elastictest: retried.

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.

2 participants