Drop BGP learned routes from networkConnections PUT body - #630
Merged
Adam Rudell (arudell) merged 2 commits intoAug 31, 2026
Merged
Conversation
The routes array of a networkConnections resource contains both the statically configured routes and the routes dynamically learned from the remote peer via BGP. routes.protocol is a read-only property per MS-NCNBI, so when a caller performs a GET and PUTs the object back with the BGP learned routes still present, Network Controller persists them as static routes. Once static, they can never be withdrawn when the peer stops advertising them. Set-SdnResource now removes any route reporting protocol 'bgp' from the PUT body when the target resource is a virtualGateways or networkConnections resource. networkConnections are returned inline when operating against the parent virtualGateway, so those nested routes are filtered as well. - Add private Remove-BgpLearnedRoute and Select-StaticRoute to SdnDiag.NetworkController - Add private Copy-ObjectWithPropertyOverride to SdnDiag.Utilities so the object supplied by the caller is never mutated - Add offline Pester coverage and virtualGateways mock data containing a network connection with both static and BGP learned routes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6662a9b3-9bc4-43b6-bbe2-8b29aee607a6
Contributor
There was a problem hiding this comment.
Pull request overview
Prevents BGP-learned routes from becoming static during Network Controller updates.
Changes:
- Filters BGP routes from gateway-related PUT payloads without mutating caller objects.
- Adds reusable object-copy support.
- Adds comprehensive offline Pester coverage and mock gateway data.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/modules/SdnDiag.NetworkController.psm1 |
Filters BGP routes before serialization. |
src/modules/SdnDiag.Utilities.psm1 |
Adds property-override copying helper. |
tests/offline/NetworkController.Tests.ps1 |
Tests filtering and PUT behavior. |
tests/offline/Utilities.Tests.ps1 |
Tests object-copy behavior. |
tests/offline/data/SdnApiResources/virtualGateways.json |
Adds mixed static/BGP fixture. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Adam Rudell (arudell)
marked this pull request as ready for review
August 27, 2026 15:49
andrwli
approved these changes
Aug 31, 2026
6 tasks
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.
Problem
The
routesarray of anetworkConnectionsresource (/virtualGateways/{id}/networkConnections/{id}) contains both the statically configured routes and the routes dynamically learned from the remote peer via BGP.Per MS-NCNBI,
routes.protocolis a read-only property that indicates how the route was added (StaticorBGP).This creates a trap for the standard GET/modify/PUT pattern. When a caller retrieves a network connection, changes an unrelated property, and PUTs the object back, the BGP learned routes are still sitting in the
routesarray. Network Controller then persists them as static routes. Once static, those routes can never be withdrawn when the BGP peer stops advertising them, which leaves stale routing state on the connection.Fix
Set-SdnResourcenow removes any route reportingprotocolofbgpfrom the PUT body when the target resource is avirtualGatewaysornetworkConnectionsresource.networkConnectionsare returned inline when operating against the parentvirtualGateway, so the same conversion can happen through the parent resource. Nested connections are filtered as well.Non-gateway resources are untouched, so there is no behavior change for any other resource type.
Changes
src/modules/SdnDiag.NetworkController.psm1Remove-BgpLearnedRoute(private) - returns a copy of avirtualGateways/networkConnectionsresource with everyproperties.routesentry whoseprotocolisbgpremoved. Matching is case-insensitive and tolerates surrounding whitespace. Recurses intoproperties.networkConnections. Returns the original object reference when nothing needed to be removed.Select-StaticRoute(private) - the array filter. Returns$nullwhen no BGP routes were present so the caller can skip the copy entirely.Set-SdnResource- applies the filter on the PUT path beforeRemove-PropertiesFromObjectand JSON serialization.src/modules/SdnDiag.Utilities.psm1Copy-ObjectWithPropertyOverride(private) - shallow copy with case-insensitive property replacement, alongside the existingRemove-PropertiesFromObject. This is what keeps the object supplied by the caller from being mutated.Testing
82/82 offline Pester tests pass (21 new). New coverage:
BGP,bgp,Bgp)[], asserted against the raw PUT body rather than the decoded objectnullentries within anetworkConnectionsarray-ResourceRefand-Resource/-ResourceIdparameter setsMock data adds
vgw-tenant-0002with a network connection carrying both static and BGP learned routes. The existingvgw-tenant-0001is unchanged so the empty-connections case stays covered.The changed code paths were also validated directly on Windows PowerShell 5.1 and PowerShell 7 to confirm identical array and JSON serialization semantics, since the manifest declares
PowerShellVersion = '5.1'.Notes for reviewers
Two defects were caught during review of this change and are already fixed here:
Remove-BgpLearnedRoute -ObjectwasMandatorywithout[AllowNull()], so a$nullelement inside anetworkConnectionsarray would have thrown at parameter binding instead of reaching the null guard. A regression test covers this.Copy-ObjectWithPropertyOverridesilently picked an arbitrary value when a case-sensitive hashtable contained bothnameandNAME, and picked differently on 5.1 than on 7. It now throws on ambiguous keys.