Public/Set-BfdSession.ps1
|
function Set-BfdSession { <# .SYNOPSIS Changes a BFD session in place, or injects faults. .DESCRIPTION Timers, DetectMult, Demand and echo mode, Passive and authentication apply live: a running session negotiates new timers with a Poll sequence (RFC 5880 6.8.3) and does not go Down. -Port, -ListenPort, -LocalAddress, -EchoPort and -EchoListenPort restart a running session. Fault injection (all revert with -ClearFaults): -Suppress $true stop sending control packets while the session stays alive (the peer's detection time expires) -AdminDown $true send AdminDown (diagnostic 7) without stopping the session -DropEcho $true keep advertising echo support but stop looping the peer's echo packets back -FaultMyDiscriminator advertise another My Discriminator than the real one (0 is invalid on the wire) -FaultYourDiscriminator advertise a wrong Your Discriminator, so the peer drops the packets -FaultDesiredMinTxMs / -FaultRequiredMinRxMs advertise bad timers (0 is allowed, e.g. RequiredMinRx 0 tells the peer to stop sending) -FaultDetectMult advertise another DetectMult (0 is invalid) -FaultDiagnostic / -FaultState advertise another diagnostic code or state -FaultAuthKey sign packets with the wrong key #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipelineByPropertyName)][string]$Name, [ValidateRange(1, 4294967)][uint32]$DesiredMinTxMs, [ValidateRange(0, 4294967)][uint32]$RequiredMinRxMs, [ValidateRange(1, 255)][int]$DetectMult, [bool]$Passive, [bool]$DemandMode, [ValidateSet('Disabled', 'Reflect', 'Active')][string]$EchoMode, [ValidateRange(1, 4294967)][uint32]$EchoIntervalMs, [ValidateSet('None', 'SimplePassword', 'KeyedMD5', 'MeticulousKeyedMD5', 'KeyedSHA1', 'MeticulousKeyedSHA1')][string]$AuthType, [ValidateRange(0, 255)][int]$AuthKeyId, [string]$AuthKey, [bool]$RecordPackets, [ValidateRange(1, 65535)][int]$Port, [ValidateRange(1, 65535)][int]$ListenPort, [ipaddress]$LocalAddress, [ValidateRange(1, 65535)][int]$EchoPort, [ValidateRange(1, 65535)][int]$EchoListenPort, [bool]$Suppress, [bool]$AdminDown, [bool]$DropEcho, [uint32]$FaultMyDiscriminator, [uint32]$FaultYourDiscriminator, [uint32]$FaultDesiredMinTxMs, [uint32]$FaultRequiredMinRxMs, [ValidateRange(0, 255)][int]$FaultDetectMult, [ValidateRange(0, 31)][int]$FaultDiagnostic, [ValidateSet('AdminDown', 'Down', 'Init', 'Up')][string]$FaultState, [string]$FaultAuthKey, [switch]$ClearFaults ) process { $S = (Get-BfdRegistry).Bfd[$Name] if (-not $S) { throw "No such BFD session '$Name'." } $c = $S.Config $p = $PSBoundParameters $authType = if ($p.ContainsKey('AuthType')) { $AuthType } else { $c.AuthType } $authKey = if ($p.ContainsKey('AuthKey')) { $AuthKey } else { $c.AuthKey } Assert-BfdAuth -AuthType $authType -AuthKey $authKey $restart = foreach ($k in 'Port', 'ListenPort', 'LocalAddress', 'EchoPort', 'EchoListenPort') { if ($p.ContainsKey($k)) { $k } } $wasRunning = $S.State -ne 'Stopped' if ($restart -and $wasRunning) { Stop-BfdSession -Name $Name } if ($p.ContainsKey('DesiredMinTxMs')) { $c.DesiredMinTx = [uint32]($DesiredMinTxMs * 1000) } if ($p.ContainsKey('RequiredMinRxMs')) { $c.RequiredMinRx = [uint32]($RequiredMinRxMs * 1000) } if ($p.ContainsKey('EchoIntervalMs')) { $c.EchoInterval = [uint32]($EchoIntervalMs * 1000) } foreach ($k in 'DetectMult', 'Passive', 'DemandMode', 'EchoMode', 'AuthKeyId', 'RecordPackets', 'Port', 'ListenPort', 'EchoPort', 'EchoListenPort') { if ($p.ContainsKey($k)) { $prop = if ($k -eq 'Port') { 'RemotePort' } else { $k } $c.$prop = $p[$k] } } if ($p.ContainsKey('LocalAddress')) { $c.LocalAddress = $LocalAddress.ToString() } $c.AuthType = $authType; $c.AuthKey = $authKey if ($p.ContainsKey('Suppress')) { $S.Suppress = $Suppress } if ($p.ContainsKey('AdminDown')) { $S.AdminDown = $AdminDown } if ($p.ContainsKey('DropEcho')) { $S.DropEcho = $DropEcho } if ($ClearFaults) { $S.Fault.Clear(); $S.Suppress = $false; $S.AdminDown = $false; $S.DropEcho = $false } $faults = @{ FaultMyDiscriminator = 'MyDiscriminator'; FaultYourDiscriminator = 'YourDiscriminator' FaultDetectMult = 'DetectMult'; FaultDiagnostic = 'Diagnostic'; FaultState = 'State'; FaultAuthKey = 'AuthKey' } foreach ($k in $faults.Keys) { if ($p.ContainsKey($k)) { $S.Fault[$faults[$k]] = $p[$k]; Add-BfdEvent -State $S -Type 'Fault' -Summary "fault injected: $($faults[$k]) = $($p[$k])" } } if ($p.ContainsKey('FaultDesiredMinTxMs')) { $S.Fault.DesiredMinTx = [uint32]($FaultDesiredMinTxMs * 1000) } if ($p.ContainsKey('FaultRequiredMinRxMs')) { $S.Fault.RequiredMinRx = [uint32]($FaultRequiredMinRxMs * 1000) } if ($restart -and $wasRunning) { $null = Resume-BfdSession -Name $Name } } } |