Skip to content

Drop BGP learned routes from networkConnections PUT body - #630

Merged
Adam Rudell (arudell) merged 2 commits into
microsoft:mainfrom
arudell:arudell-drop-bgp-routes-on-put
Aug 31, 2026
Merged

Drop BGP learned routes from networkConnections PUT body#630
Adam Rudell (arudell) merged 2 commits into
microsoft:mainfrom
arudell:arudell-drop-bgp-routes-on-put

Conversation

@arudell

Copy link
Copy Markdown
Member

Problem

The routes array of a networkConnections resource (/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.protocol is a read-only property that indicates how the route was added (Static or BGP).

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 routes array. 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-SdnResource now removes any route reporting protocol of 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 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.psm1

  • Remove-BgpLearnedRoute (private) - returns a copy of a virtualGateways/networkConnections resource with every properties.routes entry whose protocol is bgp removed. Matching is case-insensitive and tolerates surrounding whitespace. Recurses into properties.networkConnections. Returns the original object reference when nothing needed to be removed.
  • Select-StaticRoute (private) - the array filter. Returns $null when no BGP routes were present so the caller can skip the copy entirely.
  • Set-SdnResource - applies the filter on the PUT path before Remove-PropertiesFromObject and JSON serialization.

src/modules/SdnDiag.Utilities.psm1

  • Copy-ObjectWithPropertyOverride (private) - shallow copy with case-insensitive property replacement, alongside the existing Remove-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 routes dropped, static routes retained
  • Mixed protocol casing (BGP, bgp, Bgp)
  • Routes that do not report a protocol are conservatively retained
  • An all-BGP array serializes to [], asserted against the raw PUT body rather than the decoded object
  • A single retained route still serializes as a JSON array, not a scalar
  • The caller's object is never mutated, verified by comparing full before/after serialization
  • null entries within a networkConnections array
  • Both the -ResourceRef and -Resource/-ResourceId parameter sets
  • Non-gateway resources are left alone

Mock data adds vgw-tenant-0002 with a network connection carrying both static and BGP learned routes. The existing vgw-tenant-0001 is 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:

  1. Remove-BgpLearnedRoute -Object was Mandatory without [AllowNull()], so a $null element inside a networkConnections array would have thrown at parameter binding instead of reaching the null guard. A regression test covers this.
  2. Copy-ObjectWithPropertyOverride silently picked an arbitrary value when a case-sensitive hashtable contained both name and NAME, and picked differently on 5.1 than on 7. It now throws on ambiguous keys.

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
Copilot AI balanced review requested due to automatic review settings August 27, 2026 15:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@arudell
Adam Rudell (arudell) marked this pull request as ready for review August 27, 2026 15:49
@arudell
Adam Rudell (arudell) requested a review from a team as a code owner August 27, 2026 15:49
Copilot AI review requested due to automatic review settings August 27, 2026 16:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Comment thread src/modules/SdnDiag.Utilities.psm1
@arudell
Adam Rudell (arudell) merged commit 92cb03e into microsoft:main Aug 31, 2026
7 checks passed
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.

3 participants