Skip to content

Commit

Permalink
Invoke xdpbpfexport.exe from MSI install/uninstall (#519)
Browse files Browse the repository at this point in the history
* invoke xdp_bpfexport.exe from MSI install/uninstall

* create separate feature for ebpf integration

* fix bad merge submodules

* WIP

* HUZZAH

* consume new MSI feature from setup.ps1

* add description

* update documentation
  • Loading branch information
mtfriesen authored Sep 6, 2024
1 parent e341177 commit 6242219
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 38 deletions.
12 changes: 9 additions & 3 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ XDP for Windows consists of a usermode library (xdpapi.dll) and a driver (xdp.sy

```PowerShell
Invoke-WebRequest https://aka.ms/xdp-v1.msi -OutFile xdp.msi
msiexec /i xdp.msi /quiet
msiexec.exe /i xdp.msi /quiet
```

### Install a Test Version
Expand All @@ -29,15 +29,21 @@ bcdedit.exe /set testsigning on
Install:

```bat
msiexec /i xdp-for-windows.msi /quiet
msiexec.exe /i xdp-for-windows.msi /quiet
```

Uninstall:

```bat
msiexec /x xdp-for-windows.msi /quiet
msiexec.exe /x xdp-for-windows.msi /quiet
```

### Enable eBPF Support

**Note** eBPF support is experimental and is not officially supported by XDP.

Starting with XDP version 1.1, experimental eBPF support can be enabled by appending an `ADDLOCAL=xdp_ebpf` parameter to the `msiexec.exe` install commands.

### Version Upgrade

To upgrade versions of XDP, uninstall the old version and install the new version. If processes have XDP handles open (e.g. sockets, programs) those handles need to be closed for uninstallation to complete.
Expand Down
35 changes: 27 additions & 8 deletions src/xdpinstaller/product.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@ SPDX-License-Identifier: MIT
<!-- Define the Product features and installation steps -->
<Feature Id="ProductFeature" Title="XDP for Windows Installer" ConfigurableDirectory="INSTALLFOLDER" Display="expand" Level="1" Absent="disallow" AllowAdvertise="no" InstallDefault="local" TypicalDefault="install" >
<ComponentGroupRef Id="xdp" />
<Feature Id="xdp_ebpf" Level="10" AllowAdvertise="no" Title="XDP eBPF" Description="Experimental eBPF support. NOT officially supported.">
<ComponentGroupRef Id="xdp_ebpf" />
</Feature>
</Feature>

<InstallExecuteSequence>
<!--Rollback sequence-->
<Custom Action="xdp_uninstall_rollback" Before="xdp_install">NOT Installed</Custom>
<Custom Action="xdp_ebpf_uninstall_rollback" Before="xdp_ebpf_install">NOT Installed</Custom>

<!--Install sequence-->
<Custom Action="xdp_install" After="InstallFiles">NOT Installed</Custom>
<Custom Action="xdp_ebpf_install" After="xdp_install">(&amp;xdp_ebpf=3) AND NOT(!xdp_ebpf=3) </Custom>

<!--Uninstall sequence-->
<Custom Action="xdp_uninstall" After="InstallInitialize">REMOVE="ALL"</Custom>
<Custom Action="xdp_ebpf_uninstall" After="InstallInitialize">(&amp;xdp_ebpf=2) AND (!xdp_ebpf=3)</Custom>
<Custom Action="xdp_uninstall" After="xdp_ebpf_uninstall">REMOVE="ALL"</Custom>
</InstallExecuteSequence>

<!-- Define the UI style & behavior -->
Expand All @@ -60,7 +66,7 @@ SPDX-License-Identifier: MIT
<Component Id ="xdpPATH" Guid="{0445C769-0841-4FD9-939F-C2E7F514E61A}" KeyPath="yes">
<Environment Id="xdpPATH" Name="PATH" Value="[INSTALLFOLDER]" Permanent="no" Part="last" Action="set" System="yes" Separator=";" />
</Component>
<Component Id="xdp_setup" Guid="{0D991B56-5C01-4E57-AB33-E81696B73D55}">
<Component Id="xdp_setup" Guid="{0D991B56-5C01-4E57-AB33-E81696B73D55}" Location="local" >
<File Id="xdp_setup_ps1" Source="$(var.TargetDir)xdp-setup.ps1" KeyPath="yes"/>
</Component>
<Component Id="xdppcw.man" Guid="{EDD336F3-5350-4046-AF01-C76B10A3B965}">
Expand All @@ -78,12 +84,6 @@ SPDX-License-Identifier: MIT
<Component Id="xdpcfg.pdb" Guid="{ECA5A361-BF61-443C-8E6F-1CE57C0B19DA}">
<File Id="xdpcfg.pdb" Name="xdpcfg.pdb" Source="$(var.TargetDir)xdpcfg.pdb" KeyPath="yes" />
</Component>
<Component Id="xdpbpfexport.exe" Guid="{E190E2ED-566C-424A-83F3-0422EB865FCA}">
<File Id="xdpbpfexport.exe" Name="xdpbpfexport.exe" Source="$(var.TargetDir)xdpbpfexport.exe" KeyPath="yes" />
</Component>
<Component Id="xdpbpfexport.pdb" Guid="{13148622-35D3-4005-AA31-DD9AAE4C9021}">
<File Id="xdpbpfexport.pdb" Name="xdpbpfexport.pdb" Source="$(var.TargetDir)xdpbpfexport.pdb" KeyPath="yes" />
</Component>
<Component Id="xdp.sys" Guid="{5E1B9729-E58D-4A4D-A845-FB6D2EE0C498}">
<File Id="xdp.sys" Name="xdp.sys" Source="$(var.TargetDir)xdp\xdp.sys" KeyPath="yes" />
</Component>
Expand All @@ -101,6 +101,15 @@ SPDX-License-Identifier: MIT
</Component>
</ComponentGroup>

<ComponentGroup Id="xdp_ebpf" Directory="INSTALLFOLDER">
<Component Id="xdpbpfexport.exe" Guid="{E190E2ED-566C-424A-83F3-0422EB865FCA}" Location="local">
<File Id="xdpbpfexport.exe" Name="xdpbpfexport.exe" Source="$(var.TargetDir)xdpbpfexport.exe" KeyPath="yes" />
</Component>
<Component Id="xdpbpfexport.pdb" Guid="{13148622-35D3-4005-AA31-DD9AAE4C9021}">
<File Id="xdpbpfexport.pdb" Name="xdpbpfexport.pdb" Source="$(var.TargetDir)xdpbpfexport.pdb" KeyPath="yes" />
</Component>
</ComponentGroup>

<!-- Install/Uninstall/Rollback the XDP driver installation -->
<SetProperty Id="xdp_install" Value="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -ExecutionPolicy Bypass &quot;&amp; '[#xdp_setup_ps1]' -Install xdp -Verbose&quot;" Before="xdp_install" Sequence="execute"/>
<CustomAction Id="xdp_install" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="check" Impersonate="no"/>
Expand All @@ -110,5 +119,15 @@ SPDX-License-Identifier: MIT

<SetProperty Id="xdp_uninstall_rollback" Value="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -ExecutionPolicy Bypass &quot;&amp; '[#xdp_setup_ps1]' -Uninstall xdp -Verbose&quot;" Before="xdp_uninstall_rollback" Sequence="execute"/>
<CustomAction Id="xdp_uninstall_rollback" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="rollback" Return="ignore" Impersonate="no"/>

<!-- Install/Uninstall/Rollback the XDP eBPF installation -->
<SetProperty Id="xdp_ebpf_install" Value="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -ExecutionPolicy Bypass &quot;&amp; '[#xdp_setup_ps1]' -Install xdpebpf -Verbose&quot;" Before="xdp_ebpf_install" Sequence="execute"/>
<CustomAction Id="xdp_ebpf_install" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="check" Impersonate="no"/>

<SetProperty Id="xdp_ebpf_uninstall" Value="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -ExecutionPolicy Bypass &quot;&amp; '[#xdp_setup_ps1]' -Uninstall xdpebpf -Verbose&quot;" Before="xdp_ebpf_uninstall" Sequence="execute"/>
<CustomAction Id="xdp_ebpf_uninstall" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>

<SetProperty Id="xdp_ebpf_uninstall_rollback" Value="&quot;[System64Folder]WindowsPowerShell\v1.0\powershell.exe&quot; -ExecutionPolicy Bypass &quot;&amp; '[#xdp_setup_ps1]' -Uninstall xdpebpf -Verbose&quot;" Before="xdp_ebpf_uninstall_rollback" Sequence="execute"/>
<CustomAction Id="xdp_ebpf_uninstall_rollback" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="rollback" Return="ignore" Impersonate="no"/>
</Fragment>
</Wix>
2 changes: 1 addition & 1 deletion src/xdppcw/xdppcw.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</Ctrpp>
</ItemDefinitionGroup>
<Import Project="$(SolutionDir)src\xdp.targets" />
<Target Name="CopyFiles" AfterTargets="Build">
<Target Name="CopyFiles" BeforeTargets="Build">
<Copy SourceFiles="xdppcw.man" DestinationFolder="$(OutDir)" />
</Target>
</Project>
41 changes: 39 additions & 2 deletions src/xdpruntime/xdp-setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ This script installs or uninstalls various XDP components.
param (

[Parameter(Mandatory = $false)]
[ValidateSet("", "xdp")]
[ValidateSet("", "xdp", "xdpebpf")]
[string]$Install = "",

[Parameter(Mandatory = $false)]
[ValidateSet("", "xdp")]
[ValidateSet("", "xdp", "xdpebpf")]
[string]$Uninstall = ""
)

Expand All @@ -30,6 +30,7 @@ $InstallDir = $PSScriptRoot
# Global paths.
$XdpInf = "$InstallDir\xdp.inf"
$XdpPcwMan = "$InstallDir\xdppcw.man"
$XdpBpfExport = "$InstallDir\xdpbpfexport.exe"

# Helper wait for a service to stop and then delete it. Callers are responsible
# making sure the service is already stopped or stopping.
Expand Down Expand Up @@ -127,6 +128,42 @@ if ($Install -eq "xdp") {
Write-Verbose "xdp.sys install complete!"
}

# Installs the XDP eBPF feature.
if ($Install -eq "xdpebpf") {
Write-Verbose "reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f"
reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f | Write-Verbose

# XDP needs to be restarted to reload this registry key. Continue past failures.
Write-Verbose "Restarting xdp"
Restart-Service xdp -ErrorAction 'Continue'

Write-Verbose "$XdpBpfExport"
& $XdpBpfExport
if ($LastExitCode) {
Write-Error "$XdpBpfExport exit code: $LastExitCode"
}

Write-Verbose "XDP eBPF feature install complete!"
}

# Uninstalls the XDP eBPF feature.
if ($Uninstall -eq "xdpebpf") {
Write-Verbose "$XdpBpfExport --clear"
& $XdpBpfExport --clear
if ($LastExitCode) {
Write-Error "$XdpBpfExport exit code: $LastExitCode"
}

Write-Verbose "reg.exe delete HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /f"
reg.exe delete HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /f | Write-Verbose

# XDP needs to be restarted to reload this registry key. Continue past failures.
Write-Verbose "Restarting xdp"
Restart-Service xdp -ErrorAction 'Continue'

Write-Verbose "XDP eBPF feature uninstall complete!"
}

# Uninstalls the xdp driver.
if ($Uninstall -eq "xdp") {

Expand Down
14 changes: 14 additions & 0 deletions test/functional/lib/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5322,6 +5322,20 @@ SecurityAdjustDeviceAcl()
}
}

VOID
EbpfNetsh()
{
//
// Verify XDP metadata is registered with eBPF via store APIs.
//
CHAR Path[MAX_PATH];
CHAR CmdBuff[256] = {0};

TEST_HRESULT(GetCurrentBinaryPath(Path, RTL_NUMBER_OF(Path)));
sprintf_s(CmdBuff, "netsh ebpf show verification file=%s\\bpf\\pass.o", Path);
TEST_EQUAL(0, InvokeSystem(CmdBuff));
}

static
HRESULT
TryAttachEbpfXdpProgram(
Expand Down
3 changes: 3 additions & 0 deletions test/functional/lib/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ GenericRxFuzzForwardGro(
VOID
SecurityAdjustDeviceAcl();

VOID
EbpfNetsh();

VOID
GenericRxEbpfAttach();

Expand Down
4 changes: 4 additions & 0 deletions test/functional/taef/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,10 @@ TEST_CLASS(xdpfunctionaltests)
::SecurityAdjustDeviceAcl();
}

TEST_METHOD(EbpfNetsh) {
::EbpfNetsh();
}

TEST_METHOD_PRERELEASE(GenericRxEbpfAttach) {
::GenericRxEbpfAttach();
}
Expand Down
18 changes: 9 additions & 9 deletions tools/functional.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ for ($i = 1; $i -le $Iterations; $i++) {

& "$RootDir\tools\log.ps1" -Start -Name $LogName -Profile XdpFunctional.Verbose -Config $Config -Arch $Arch

if (!$EbpfPreinstalled) {
Write-Verbose "installing ebpf..."
& "$RootDir\tools\setup.ps1" -Install ebpf -Config $Config -Arch $Arch -UseJitEbpf:$UseJitEbpf
Write-Verbose "installed ebpf."
}

Write-Verbose "installing xdp..."
& "$RootDir\tools\setup.ps1" -Install xdp -Config $Config -Arch $Arch -EnableEbpf
Write-Verbose "installed xdp."
Expand All @@ -103,12 +109,6 @@ for ($i = 1; $i -le $Iterations; $i++) {
& "$RootDir\tools\setup.ps1" -Install fnsock -Config $Config -Arch $Arch
Write-Verbose "installed fnsock."

if (!$EbpfPreinstalled) {
Write-Verbose "installing ebpf..."
& "$RootDir\tools\setup.ps1" -Install ebpf -Config $Config -Arch $Arch
Write-Verbose "installed ebpf."
}

$TestArgs = @()
if (![string]::IsNullOrEmpty($TestBinaryPath)) {
$TestArgs += $TestBinaryPath
Expand Down Expand Up @@ -149,13 +149,13 @@ for ($i = 1; $i -le $Iterations; $i++) {
if ($Watchdog -ne $null) {
Remove-Job -Job $Watchdog -Force
}
if (!$EbpfPreinstalled) {
& "$RootDir\tools\setup.ps1" -Uninstall ebpf -Config $Config -Arch $Arch -ErrorAction 'Continue'
}
& "$RootDir\tools\setup.ps1" -Uninstall fnsock -Config $Config -Arch $Arch -ErrorAction 'Continue'
& "$RootDir\tools\setup.ps1" -Uninstall fnlwf -Config $Config -Arch $Arch -ErrorAction 'Continue'
& "$RootDir\tools\setup.ps1" -Uninstall fnmp -Config $Config -Arch $Arch -ErrorAction 'Continue'
& "$RootDir\tools\setup.ps1" -Uninstall xdp -Config $Config -Arch $Arch -ErrorAction 'Continue'
if (!$EbpfPreinstalled) {
& "$RootDir\tools\setup.ps1" -Uninstall ebpf -Config $Config -Arch $Arch -ErrorAction 'Continue'
}
& "$RootDir\tools\log.ps1" -Stop -Name $LogName -Config $Config -Arch $Arch -ErrorAction 'Continue'
}
}
Expand Down
20 changes: 13 additions & 7 deletions tools/setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,14 @@ function Install-Xdp {
if ($XdpInstaller -eq "MSI") {
$XdpPath = Get-XdpInstallPath

Write-Verbose "msiexec.exe /i $XdpMsiFullPath INSTALLFOLDER=$XdpPath /quiet /l*v $LogsDir\xdpinstall.txt"
msiexec.exe /i $XdpMsiFullPath INSTALLFOLDER=$XdpPath /quiet /l*v $LogsDir\xdpinstall.txt | Write-Verbose
$AddLocal = ""

if ($EnableEbpf) {
$AddLocal = "ADDLOCAL=xdp_ebpf"
}

Write-Verbose "msiexec.exe /i $XdpMsiFullPath INSTALLFOLDER=$XdpPath $AddLocal /quiet /l*v $LogsDir\xdpinstall.txt"
msiexec.exe /i $XdpMsiFullPath INSTALLFOLDER=$XdpPath $AddLocal /quiet /l*v $LogsDir\xdpinstall.txt | Write-Verbose

if ($LastExitCode -ne 0) {
Write-Error "XDP MSI installation failed: $LastExitCode"
Expand All @@ -280,12 +286,12 @@ function Install-Xdp {
if ($LastExitCode) {
Write-Error "lodctr.exe exit code: $LastExitCode"
}
}

if ($EnableEbpf) {
Write-Verbose "reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f"
reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f | Write-Verbose
Stop-Service xdp
if ($EnableEbpf) {
Write-Verbose "reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f"
reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\xdp\Parameters /v XdpEbpfEnabled /d 1 /t REG_DWORD /f | Write-Verbose
Stop-Service xdp
}
}

Start-Service-With-Retry xdp
Expand Down
16 changes: 8 additions & 8 deletions tools/spinxsk.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ while (($Minutes -eq 0) -or (((Get-Date)-$StartTime).TotalMinutes -lt $Minutes))
Write-Verbose "installed fndis."
}

if (!$EbpfPreinstalled) {
Write-Verbose "installing ebpf..."
& "$RootDir\tools\setup.ps1" -Install ebpf -Config $Config -Arch $Arch
Write-Verbose "installed ebpf."
}

Write-Verbose "installing xdp..."
& "$RootDir\tools\setup.ps1" -Install xdp -Config $Config -Arch $Arch -EnableEbpf:$EnableEbpf
Write-Verbose "installed xdp."
Expand All @@ -143,12 +149,6 @@ while (($Minutes -eq 0) -or (((Get-Date)-$StartTime).TotalMinutes -lt $Minutes))
& "$RootDir\tools\setup.ps1" -Install xdpmp -XdpmpPollProvider $XdpmpPollProvider -Config $Config -Arch $Arch
Write-Verbose "installed xdpmp."

if (!$EbpfPreinstalled) {
Write-Verbose "installing ebpf..."
& "$RootDir\tools\setup.ps1" -Install ebpf -Config $Config -Arch $Arch
Write-Verbose "installed ebpf."
}

Write-Verbose "Set-NetAdapterRss XDPMP -NumberOfReceiveQueues $QueueCount"
Set-NetAdapterRss XDPMP -NumberOfReceiveQueues $QueueCount

Expand Down Expand Up @@ -185,11 +185,11 @@ while (($Minutes -eq 0) -or (((Get-Date)-$StartTime).TotalMinutes -lt $Minutes))
throw "SpinXsk failed with $LastExitCode"
}
} finally {
& "$RootDir\tools\setup.ps1" -Uninstall xdpmp -Config $Config -Arch $Arch -ErrorAction 'Continue'
& "$RootDir\tools\setup.ps1" -Uninstall xdp -Config $Config -Arch $Arch -ErrorAction 'Continue'
if (!$EbpfPreinstalled) {
& "$RootDir\tools\setup.ps1" -Uninstall ebpf -Config $Config -Arch $Arch -ErrorAction 'Continue'
}
& "$RootDir\tools\setup.ps1" -Uninstall xdpmp -Config $Config -Arch $Arch -ErrorAction 'Continue'
& "$RootDir\tools\setup.ps1" -Uninstall xdp -Config $Config -Arch $Arch -ErrorAction 'Continue'
if ($XdpmpPollProvider -eq "FNDIS") {
& "$RootDir\tools\setup.ps1" -Uninstall fndis -Config $Config -Arch $Arch -ErrorAction 'Continue'
}
Expand Down

0 comments on commit 6242219

Please sign in to comment.