Public/Start-BgpSession.ps1
|
function Start-BgpSession { <# .SYNOPSIS Starts a BGP peer in a background runspace (active: connects out; -Passive: listens). -LocalAddress binds the session to a specific source IP (useful for several sessions to one router, e.g. ECMP tests). .EXAMPLE Start-BgpSession -Name nsx-t0 -RemoteAddress 192.168.1.1 -RemoteAS 65000 -LocalAS 65001 -RouterId 10.0.0.99 #> [CmdletBinding()] param( [string]$Name, [string]$RemoteAddress, [uint32]$RemoteAS, [ipaddress]$LocalAddress, [ValidateSet('IPv4', 'IPv6')][string[]]$AddressFamily = 'IPv4', [Parameter(Mandatory)][uint32]$LocalAS, [Parameter(Mandatory)][ipaddress]$RouterId, [uint16]$HoldTime = 90, [ValidateRange(1, 65535)][int]$Port = 179, [switch]$Passive, [ValidateRange(1, 255)][int]$Ttl, [switch]$AutoReconnect, [string]$Password, [ValidateRange(1, 3600)][int]$ReconnectDelay = 5, [ValidateRange(1, 3600)][int]$ReconnectMaxDelay = 60, [object[]]$InboundFilter = @(), [ValidateSet('Permit', 'Deny')][string]$InboundDefault = 'Permit' ) $rules = @(ConvertTo-BgpFilterRule $InboundFilter) if (-not $Passive -and -not $RemoteAddress) { throw '-RemoteAddress is required unless -Passive.' } if ($Password -and -not $IsLinux) { throw '-Password (TCP-MD5) is only supported when PowerShell runs on Linux (the Windows TCP stack has no TCP_MD5SIG).' } if (-not $Name) { $Name = if ($RemoteAddress) { $RemoteAddress } else { "passive-$Port" } } $reg = Get-PowerBgpRegistry if ($RemoteAddress) { $dup = @($reg.Bgp.Values) | Where-Object { $_.Name -ne $Name -and $_.Config.RemoteAddress -eq $RemoteAddress } | Select-Object -First 1 if ($dup) { throw "A peer for $RemoteAddress already exists ('$($dup.Name)'). Remove it first." } } $existing = $reg.Bgp[$Name] if ($existing) { if ($existing.State -notin 'Idle', 'Stopped') { throw "Peer '$Name' already exists and is $($existing.State)." } Stop-PowerBgpRunspace $existing 1 } $S = [hashtable]::Synchronized(@{ Name = $Name Config = [pscustomobject]@{ RemoteAddress = $RemoteAddress; RemoteAS = $RemoteAS; LocalAddress = $(if ($LocalAddress) { "$LocalAddress" }); LocalAS = $LocalAS; RouterId = $RouterId HoldTime = $HoldTime; Port = $Port; Passive = [bool]$Passive; Ttl = $Ttl AutoReconnect = [bool]$AutoReconnect; ReconnectDelay = $ReconnectDelay; ReconnectMaxDelay = $ReconnectMaxDelay Password = $Password; AddressFamily = @($AddressFamily | Select-Object -Unique); InboundFilter = $rules; InboundDefault = $InboundDefault } Filtered = 0 Reconnects = 0 NextRetry = $null LastEstablished = $false State = 'Idle' Stop = $false SuppressKeepalives = $false Outbound = [System.Collections.Concurrent.ConcurrentQueue[byte[]]]::new() Events = [System.Collections.Concurrent.ConcurrentQueue[object]]::new() Learned = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() Advertised = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() Sent = 0 Received = 0 Established = $null PeerOpen = $null PeerFourOctet = $true HoldTime = 0 LastError = $null RemoteEndpoint = $null LocalAddress = $null PowerShell = $null Handle = $null }) $reg.Bgp[$Name] = $S Start-PowerBgpRunspace -State $S -Entry 'Invoke-BgpPeerLoop' Get-BgpSession -Name $Name } |