From patchwork Mon Oct 8 23:26:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alin-Gabriel Serdean X-Patchwork-Id: 980924 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Tc224P07z9vZs for ; Tue, 9 Oct 2018 10:26:33 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D1FD07261; Mon, 8 Oct 2018 23:26:30 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id DE09D6FFE for ; Mon, 8 Oct 2018 23:26:15 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1E812784 for ; Mon, 8 Oct 2018 23:26:13 +0000 (UTC) X-Originating-IP: 89.46.161.178 Received: from localhost.localdomain (unknown [89.46.161.178]) (Authenticated sender: aserdean@ovn.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 3CF38FF802; Mon, 8 Oct 2018 23:26:11 +0000 (UTC) From: Alin Gabriel Serdean To: dev@openvswitch.org Date: Tue, 9 Oct 2018 02:26:02 +0300 Message-Id: <20181008232602.30924-1-aserdean@ovn.org> X-Mailer: git-send-email 2.16.1.windows.1 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, WEIRD_QUOTING autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Alin Gabriel Serdean Subject: [ovs-dev] [RFC PATCH v1 1/3] datapath-windows: Introduce HNS OVS calls X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org We introduce a new powershell module for interacting with HNS (host network service): https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/hns.psm1 In our repository this shall be named HNSHelper.psm1. We also add five new commandlets in our OVS powershell module: Disable-OVSOnHNSNetwork - disable OVS extension on a given HNS network. Enable-OVSOnHNSNetwork - enable OVS extension on a given HNS network. Get-OVSEnabledHNSNetworks - return the HNS network on which OVS is enabled. Add-OVSHNSInternalPort - will add a new internal port with he name: `name`, on the HNS network, which has OVS enabled. This port shall use the host compartment. Delete-OVSHNSInternalPort - will delete an internal port with name: `name` on a HNS network which has OVS enabled. Signed-off-by: Alin Gabriel Serdean --- datapath-windows/automake.mk | 1 + datapath-windows/misc/HNSHelper.psm1 | 499 +++++++++++++++++++++++++++++++++++ datapath-windows/misc/OVS.psm1 | 79 +++++- 3 files changed, 578 insertions(+), 1 deletion(-) create mode 100644 datapath-windows/misc/HNSHelper.psm1 diff --git a/datapath-windows/automake.mk b/datapath-windows/automake.mk index 3820041f6..d98ab3c60 100644 --- a/datapath-windows/automake.mk +++ b/datapath-windows/automake.mk @@ -3,6 +3,7 @@ EXTRA_DIST += \ datapath-windows/Package/package.VcxProj.user \ datapath-windows/include/OvsDpInterfaceExt.h \ datapath-windows/include/OvsDpInterfaceCtExt.h \ + datapath-windows/misc/HNSHelper.psm1 \ datapath-windows/misc/OVS.psm1 \ datapath-windows/misc/install.cmd \ datapath-windows/misc/uninstall.cmd \ diff --git a/datapath-windows/misc/HNSHelper.psm1 b/datapath-windows/misc/HNSHelper.psm1 new file mode 100644 index 000000000..ac99889cf --- /dev/null +++ b/datapath-windows/misc/HNSHelper.psm1 @@ -0,0 +1,499 @@ +# SDN Sample Scripts v.1.0 +# +# Copyright (c) Microsoft Corporation +# +# All rights reserved. +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the ""Software""), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +######################################################################### +# Global Initialize +function Get-VmComputeNativeMethods() +{ + $signature = @' + [DllImport("vmcompute.dll")] + public static extern void HNSCall([MarshalAs(UnmanagedType.LPWStr)] string method, [MarshalAs(UnmanagedType.LPWStr)] string path, [MarshalAs(UnmanagedType.LPWStr)] string request, [MarshalAs(UnmanagedType.LPWStr)] out string response); +'@ + + # Compile into runtime type + try { return [VmCompute.PrivatePInvoke.NativeMethods] } + catch { return (Add-Type -MemberDefinition $signature -Namespace VmCompute.PrivatePInvoke -Name NativeMethods -PassThru) } +} + +######################################################################### +# Configuration +######################################################################### +function Get-HnsSwitchExtensions +{ + param + ( + [parameter(Mandatory=$true)] [string] $NetworkId + ) + + return (Get-HNSNetwork $NetworkId).Extensions +} + +function Set-HnsSwitchExtension +{ + param + ( + [parameter(Mandatory=$true)] [string] $NetworkId, + [parameter(Mandatory=$true)] [string] $ExtensionId, + [parameter(Mandatory=$true)] [bool] $state + ) + + # { "Extensions": [ { "Id": "...", "IsEnabled": true|false } ] } + $req = @{ + "Extensions"=@(@{ + "Id"=$ExtensionId; + "IsEnabled"=$state; + };) + } + Invoke-HNSRequest -Method POST -Type networks -Id $NetworkId -Data (ConvertTo-Json $req) +} + +######################################################################### +# Activities +######################################################################### +function Get-HNSActivities +{ + [cmdletbinding()]Param() + return Invoke-HNSRequest -Type activities -Method GET +} + +######################################################################### +# PolicyLists +######################################################################### +function Get-HNSPolicyList { + [cmdletbinding()]Param() + return Invoke-HNSRequest -Type policylists -Method GET +} + +function Remove-HnsPolicyList +{ + [CmdletBinding()] + param + ( + [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [Object[]] $InputObjects + ) + begin {$Objects = @()} + process {$Objects += $InputObjects; } + end { + $Objects | foreach { Invoke-HNSRequest -Method DELETE -Type policylists -Id $_.Id } + } +} + +function New-HnsRoute { + param + ( + [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null, + [parameter(Mandatory = $true)] [string] $DestinationPrefix, + [parameter(Mandatory = $false)] [switch] $EncapEnabled + ) + + $policyLists = @{ + References = @( + get-endpointReferences $Endpoints; + ); + Policies = @( + @{ + Type = "ROUTE"; + DestinationPrefix = $DestinationPrefix; + NeedEncap = $EncapEnabled.IsPresent; + } + ); + } + + Invoke-HNSRequest -Method POST -Type policylists -Data (ConvertTo-Json $policyLists -Depth 10) +} + +function New-HnsLoadBalancer { + param + ( + [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null, + [parameter(Mandatory = $true)] [int] $InternalPort, + [parameter(Mandatory = $true)] [int] $ExternalPort, + [parameter(Mandatory = $false)] [string] $Vip + ) + + $policyLists = @{ + References = @( + get-endpointReferences $Endpoints; + ); + Policies = @( + @{ + Type = "ELB"; + InternalPort = $InternalPort; + ExternalPort = $ExternalPort; + VIPs = @($Vip); + } + ); + } + + Invoke-HNSRequest -Method POST -Type policylists -Data ( ConvertTo-Json $policyLists -Depth 10) +} + + +function get-endpointReferences { + param + ( + [parameter(Mandatory = $true)] [Guid[]] $Endpoints = $null + ) + if ($Endpoints ) { + $endpointReference = @() + foreach ($endpoint in $Endpoints) + { + $endpointReference += "/endpoints/$endpoint" + } + return $endpointReference + } + return @() +} + +######################################################################### +# Networks +######################################################################### +function New-HnsNetwork +{ + param + ( + [parameter(Mandatory=$false, Position=0)] + [string] $JsonString, + [ValidateSet('ICS', 'Internal', 'Transparent', 'NAT', 'Overlay', 'L2Bridge', 'L2Tunnel', 'Layered', 'Private')] + [parameter(Mandatory = $false, Position = 0)] + [string] $Type, + [parameter(Mandatory = $false)] [string] $Name, + [parameter(Mandatory = $false)] [string] $AddressPrefix, + [parameter(Mandatory = $false)] [string] $Gateway, + [parameter(Mandatory = $false)] [string] $DNSServer, + [parameter(Mandatory = $false)] [string] $AdapterName + ) + + Begin { + if (!$JsonString) { + $netobj = @{ + Type = $Type; + }; + + if ($Name) { + $netobj += @{ + Name = $Name; + } + } + + if ($AddressPrefix -and $Gateway) { + $netobj += @{ + Subnets = @( + @{ + AddressPrefix = $AddressPrefix; + GatewayAddress = $Gateway; + } + ); + } + } + + if ($DNSServerName) { + $netobj += @{ + DNSServerList = $DNSServer + } + } + + if ($AdapterName) { + $netobj += @{ + NetworkAdapterName = $AdapterName; + } + } + + $JsonString = ConvertTo-Json $netobj -Depth 10 + } + + } + Process{ + return Invoke-HNSRequest -Method POST -Type networks -Data $JsonString + } +} + +######################################################################### +# Endpoints +######################################################################### +function New-HnsEndpoint +{ + param + ( + [parameter(Mandatory=$false, Position = 0)] [string] $JsonString = $null, + [parameter(Mandatory = $false, Position = 0)] [Guid] $NetworkId, + [parameter(Mandatory = $false)] [string] $Name, + [parameter(Mandatory = $false)] [string] $IPAddress, + [parameter(Mandatory = $false)] [string] $Gateway, + [parameter(Mandatory = $false)] [string] $MacAddress, + [parameter(Mandatory = $false)] [switch] $EnableOutboundNat + ) + + begin + { + if ($JsonString) + { + $EndpointData = $JsonString | ConvertTo-Json | ConvertFrom-Json + } + else + { + $endpoint = @{ + VirtualNetwork = $NetworkId; + Policies = @(); + } + + if ($Name) { + $endpoint += @{ + Name = $Name; + } + } + + if ($MacAddress) { + $endpoint += @{ + MacAddress = $MacAddress; + } + } + + if ($IPAddress) { + $endpoint += @{ + IPAddress = $IPAddress; + } + } + + if ($Gateway) { + $endpoint += @{ + GatewayAddress = $Gateway; + } + } + + if ($EnableOutboundNat) { + $endpoint.Policies += @{ + Type = "OutBoundNAT"; + } + + } + # Try to Generate the data + $EndpointData = convertto-json $endpoint + } + } + + Process + { + return Invoke-HNSRequest -Method POST -Type endpoints -Data $EndpointData + } +} + + +function New-HnsRemoteEndpoint +{ + param + ( + [parameter(Mandatory = $true)] [Guid] $NetworkId, + [parameter(Mandatory = $false)] [string] $IPAddress, + [parameter(Mandatory = $false)] [string] $MacAddress + ) + + $remoteEndpoint = @{ + ID = [Guid]::NewGuid(); + VirtualNetwork = $NetworkId; + IPAddress = $IPAddress; + MacAddress = $MacAddress; + IsRemoteEndpoint = $true; + } + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $remoteEndpoint -Depth 10) + +} + + +function Attach-HnsHostEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID, + [parameter(Mandatory=$true)] [int] $CompartmentID + ) + $request = @{ + SystemType = "Host"; + CompartmentId = $CompartmentID; + }; + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID +} + +function Attach-HNSVMEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID, + [parameter(Mandatory=$true)] [string] $VMNetworkAdapterName + ) + + $request = @{ + VirtualNicName = $VMNetworkAdapterName; + SystemType = "VirtualMachine"; + }; + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "attach" -Id $EndpointID + +} + +function Attach-HNSEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID, + [parameter(Mandatory=$true)] [int] $CompartmentID, + [parameter(Mandatory=$true)] [string] $ContainerID + ) + $request = @{ + ContainerId = $ContainerID; + SystemType="Container"; + CompartmentId = $CompartmentID; + }; + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID +} + +function Detach-HNSVMEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID + ) + $request = @{ + SystemType = "VirtualMachine"; + }; + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID +} + +function Detach-HNSHostEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID + ) + $request = @{ + SystemType = "Host"; + }; + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID +} + +function Detach-HNSEndpoint +{ + param + ( + [parameter(Mandatory=$true)] [Guid] $EndpointID, + [parameter(Mandatory=$true)] [string] $ContainerID + ) + + $request = @{ + ContainerId = $ContainerID; + SystemType="Container"; + }; + + return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID +} +######################################################################### + +function Invoke-HNSRequest +{ + param + ( + [ValidateSet('GET', 'POST', 'DELETE')] + [parameter(Mandatory=$true)] [string] $Method, + [ValidateSet('networks', 'endpoints', 'activities', 'policylists', 'endpointstats', 'plugins')] + [parameter(Mandatory=$true)] [string] $Type, + [parameter(Mandatory=$false)] [string] $Action = $null, + [parameter(Mandatory=$false)] [string] $Data = $null, + [parameter(Mandatory=$false)] [Guid] $Id = [Guid]::Empty + ) + + $hnsPath = "/$Type" + + if ($id -ne [Guid]::Empty) + { + $hnsPath += "/$id"; + } + + if ($Action) + { + $hnsPath += "/$Action"; + } + + $request = ""; + if ($Data) + { + $request = $Data + } + + $output = ""; + $response = ""; + Write-Verbose "Invoke-HNSRequest Method[$Method] Path[$hnsPath] Data[$request]" + + $hnsApi = Get-VmComputeNativeMethods + $hnsApi::HNSCall($Method, $hnsPath, "$request", [ref] $response); + + Write-Verbose "Result : $response" + if ($response) + { + try { + $output = ($response | ConvertFrom-Json); + } catch { + Write-Error $_.Exception.Message + return "" + } + if ($output.Error) + { + Write-Error $output; + } + $output = $output.Output; + } + + return $output; +} + +######################################################################### + +Export-ModuleMember -Function Get-HNSActivities +Export-ModuleMember -Function Get-HnsSwitchExtensions +Export-ModuleMember -Function Set-HnsSwitchExtension + +Export-ModuleMember -Function New-HNSNetwork + +Export-ModuleMember -Function New-HNSEndpoint +Export-ModuleMember -Function New-HnsRemoteEndpoint + +Export-ModuleMember -Function Attach-HNSHostEndpoint +Export-ModuleMember -Function Attach-HNSVMEndpoint +Export-ModuleMember -Function Attach-HNSEndpoint +Export-ModuleMember -Function Detach-HNSHostEndpoint +Export-ModuleMember -Function Detach-HNSVMEndpoint +Export-ModuleMember -Function Detach-HNSEndpoint + +Export-ModuleMember -Function Get-HNSPolicyList +Export-ModuleMember -Function Remove-HnsPolicyList +Export-ModuleMember -Function New-HnsRoute +Export-ModuleMember -Function New-HnsLoadBalancer + +Export-ModuleMember -Function Invoke-HNSRequest diff --git a/datapath-windows/misc/OVS.psm1 b/datapath-windows/misc/OVS.psm1 index a8ffcaefd..1cc347bc6 100644 --- a/datapath-windows/misc/OVS.psm1 +++ b/datapath-windows/misc/OVS.psm1 @@ -207,4 +207,81 @@ function Set-VMNetworkAdapterOVSPortDirect } } -Export-ModuleMember -function Set-*, Get-* +function Get-OVSEnabledHNSNetworks +{ + return (Get-HNSNetwork) | Where-Object {($_.Extensions.Id -eq '583cc151-73ec-4a6a-8b47-578297ad7623') -and ($_.Extensions.IsEnabled -eq 'True')} +} + +function Add-OVSHNSInternalPort +{ + param + ( + [parameter(Mandatory=$true)] [string] $PortName + ) + $test = [array](Get-NetAdapter -IncludeHidden -InterfaceAlias "$PortName" -ErrorAction SilentlyContinue) + if (!($test -eq $null)) + { + return + } + $test = [array]((Get-HnsEndpoint) | Where-Object {($_.Name -eq "$PortName")}) + if (!($test -eq $null)) + { + return + } + $a = [array](Get-OVSEnabledHNSNetworks).Id + if ($a.count -eq 0) + { + # If we did not find any OVS enabled switches try to find the ID via + # environment variable + $a = [array]$env:OVS_ENABLED_NETWORK_ID + if ($a.count -eq 0) + { + # Bypass 1803 listing bug and assumed that the first transparent + # network is OVS enabled + $a = [array](Get-HNSNetwork | where {$_.type -eq "transparent"}).ID + if ($a.count -eq 0) + { + return + } + } + } + $temp = New-HnsEndpoint -NetworkId $a[0] -Name "$PortName" + Attach-HnsHostEndpoint $temp.Id 1 + Rename-NetAdapter -IncludeHidden -InterfaceAlias "vEthernet ($PortName)" -NewName "$PortName" -ErrorAction SilentlyContinue + Remove-NetRoute -InterfaceAlias "$PortName" -Confirm:$false -ErrorAction SilentlyContinue + Disable-NetAdapter -Confirm:$false -IncludeHidden -InterfaceAlias "$PortName" -ErrorAction SilentlyContinue +} + +function Delete-OVSHNSInternalPort +{ + param + ( + [parameter(Mandatory=$true)] [string] $PortName + ) + $a = [array]((Get-HnsEndpoint) | Where-Object {($_.Name -eq "$PortName")}) + $request = @{ + SystemType = "Host"; + }; + + return Invoke-HNSRequest -Method DELETE -Type endpoints -Data (ConvertTo-Json $request ) -Id $a[0].ID +} + +function Enable-OVSOnHNSNetwork +{ + param + ( + [parameter(Mandatory=$true)] [string] $NetworkId + ) + return Set-HnsSwitchExtension -NetworkId $NetworkId -ExtensionId 583cc151-73ec-4a6a-8b47-578297ad7623 -state $True +} + +function Disable-OVSOnHNSNetwork +{ + param + ( + [parameter(Mandatory=$true)] [string] $NetworkId + ) + return Set-HnsSwitchExtension -NetworkId $NetworkId -ExtensionId 583cc151-73ec-4a6a-8b47-578297ad7623 -state $False +} + +Export-ModuleMember -function Set-*, Get-*, Enable-*, Disable-*, Add-*, Delete-* From patchwork Mon Oct 8 23:26:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alin-Gabriel Serdean X-Patchwork-Id: 980925 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Tc336Sd0z9vZs for ; Tue, 9 Oct 2018 10:27:27 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D50FF7236; Mon, 8 Oct 2018 23:27:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 2C49872EF for ; Mon, 8 Oct 2018 23:27:06 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 59DEF7C6 for ; Mon, 8 Oct 2018 23:27:04 +0000 (UTC) X-Originating-IP: 89.46.161.178 Received: from localhost.localdomain (unknown [89.46.161.178]) (Authenticated sender: aserdean@ovn.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id E2A56C0007; Mon, 8 Oct 2018 23:27:01 +0000 (UTC) From: Alin Gabriel Serdean To: dev@openvswitch.org Date: Tue, 9 Oct 2018 02:26:54 +0300 Message-Id: <20181008232654.18608-1-aserdean@ovn.org> X-Mailer: git-send-email 2.16.1.windows.1 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Alin Gabriel Serdean Subject: [ovs-dev] [RFC PATCH v1 2/3] windows, installer: Add a new module file to the installer X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch adds the new powershell module HNSHelper.psm1 to the OVS windows installer. Signed-off-by: Alin Gabriel Serdean --- windows/automake.mk | 1 + windows/ovs-windows-installer/Product.wxs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/windows/automake.mk b/windows/automake.mk index 80dca1467..79ffe4317 100644 --- a/windows/automake.mk +++ b/windows/automake.mk @@ -16,6 +16,7 @@ PTHREAD_TEMP_DIR=`echo "$(PTHREAD_LDFLAGS)" | sed 's|^.\(.*\).$:\1||'` windows_installer: all #Userspace files needed for the installer cp -f $(top_srcdir)/datapath-windows/misc/OVS.psm1 windows/ovs-windows-installer/Services/OVS.psm1 + cp -f $(top_srcdir)/datapath-windows/misc/HNSHelper.psm1 windows/ovs-windows-installer/Services/HNSHelper.psm1 cp -f $(top_srcdir)/vswitchd/vswitch.ovsschema windows/ovs-windows-installer/Services/vswitch.ovsschema cp -f $(top_srcdir)/vswitchd/ovs-vswitchd.exe windows/ovs-windows-installer/Services/ovs-vswitchd.exe cp -f $(top_srcdir)/ovsdb/ovsdb-server.exe windows/ovs-windows-installer/Services/ovsdb-server.exe diff --git a/windows/ovs-windows-installer/Product.wxs b/windows/ovs-windows-installer/Product.wxs index ea1bc6896..9742c1773 100644 --- a/windows/ovs-windows-installer/Product.wxs +++ b/windows/ovs-windows-installer/Product.wxs @@ -67,6 +67,7 @@ + @@ -147,6 +148,7 @@ + @@ -156,6 +158,10 @@ + + + + From patchwork Mon Oct 8 23:27:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alin-Gabriel Serdean X-Patchwork-Id: 980926 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Tc3Z2LqFz9vZs for ; Tue, 9 Oct 2018 10:27:54 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8483A7441; Mon, 8 Oct 2018 23:27:47 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 4F906734E for ; Mon, 8 Oct 2018 23:27:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 637DF784 for ; Mon, 8 Oct 2018 23:27:26 +0000 (UTC) X-Originating-IP: 89.46.161.178 Received: from localhost.localdomain (unknown [89.46.161.178]) (Authenticated sender: aserdean@ovn.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 6F61260004; Mon, 8 Oct 2018 23:27:24 +0000 (UTC) From: Alin Gabriel Serdean To: dev@openvswitch.org Date: Tue, 9 Oct 2018 02:27:16 +0300 Message-Id: <20181008232716.28296-1-aserdean@ovn.org> X-Mailer: git-send-email 2.16.1.windows.1 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Alin Gabriel Serdean Subject: [ovs-dev] [RFC PATCH v1 3/3] windows: Allow add/delete ports via HNS API X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org On Windows 2016 LTSC(RTM) the Container feature and Hyper-V feature both had DCOM API to add and delete internal (management) ports on the Hyper-V switch. Starting from the 1703 release and above, enabling only the Container feature does not fulfil this requirement anymore. We need new ways to interact with the host API without the Hyper-V integration. Unfortunately, there is no C API for it, only golang and .net: https://github.com/Microsoft/hcsshim (golang) https://github.com/microsoft/dotnet-computevirtualization (.net) It is also poorly documented and reserved. Although not pretty and less performant, this will provide a way to add/delete and query the new APIs across different versions of Windows, until new API's or documentation are available. Signed-off-by: Alin Gabriel Serdean --- lib/wmi.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/lib/wmi.c b/lib/wmi.c index e6dc63cde..14451d591 100644 --- a/lib/wmi.c +++ b/lib/wmi.c @@ -203,6 +203,93 @@ wait_for_job(IWbemServices *psvc, wchar_t *job_path) return retval; } +static boolean +hns_delete(char *name) +{ + VLOG_DBG("Trying to delete port via HNS API"); + char buffer[10000]; + int count; + count = snprintf(buffer, 10000, "-NoLogo -NoProfile -NonInteractive" + "-Command \"try {Delete-OVSHNSInternalPort '%s'}" + "catch { exit 1 }; exit 0; \"", name); + if (count < 0 || count > 10000) { + VLOG_WARN("Could not allocate memory for powershell delete command"); + return false; + } + VLOG_DBG("command = %s", buffer); + DWORD res = 0; + SHELLEXECUTEINFOA ShExecInfo; + ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + ShExecInfo.hwnd = NULL; + ShExecInfo.lpVerb = NULL; + ShExecInfo.lpFile = "powershell.exe"; + ShExecInfo.lpParameters = buffer; + ShExecInfo.lpDirectory = NULL; + ShExecInfo.nShow = SW_HIDE; + ShExecInfo.hInstApp = NULL; + ShellExecuteExA(&ShExecInfo); + WaitForSingleObject(ShExecInfo.hProcess, 50000); + if (GetExitCodeProcess(ShExecInfo.hProcess, &res)) { + if (res != 0) { + VLOG_ERR("Powershell delete command failed with exit code: %d", + res); + CloseHandle(ShExecInfo.hProcess); + return false; + } + } else { + VLOG_ERR("Failed to get exit code for powershell delete command." + "Last Error: %s", ovs_lasterror_to_string()); + CloseHandle(ShExecInfo.hProcess); + return false; + } + CloseHandle(ShExecInfo.hProcess); + return true; +} + +static boolean +hns_add(char *name) +{ + VLOG_WARN("Trying to add port via HNS API"); + char buffer[10000]; + int count; + count = snprintf(buffer, 10000, "-NoLogo -NoProfile -NonInteractive" + "-Command \"try {Add-OVSHNSInternalPort '%s'}" + "catch { exit 1 }; exit 0; \"", name); + if (count < 0 || count > 10000) { + VLOG_WARN("Could not allocate memory for powershell add command"); + return false; + } + VLOG_WARN("command = %s", buffer); + DWORD res = 0; + SHELLEXECUTEINFOA ShExecInfo; + ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); + ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + ShExecInfo.hwnd = NULL; + ShExecInfo.lpVerb = NULL; + ShExecInfo.lpFile = "powershell.exe"; + ShExecInfo.lpParameters = buffer; + ShExecInfo.lpDirectory = NULL; + ShExecInfo.nShow = SW_HIDE; + ShExecInfo.hInstApp = NULL; + ShellExecuteExA(&ShExecInfo); + WaitForSingleObject(ShExecInfo.hProcess, 50000); + if (GetExitCodeProcess(ShExecInfo.hProcess, &res)) { + if (res != 0) { + VLOG_ERR("Powershell add command failed with exit code: %d", res); + CloseHandle(ShExecInfo.hProcess); + return false; + } + } else { + VLOG_ERR("Failed to get exit code for powershell add command." + "Last Error: %s", ovs_lasterror_to_string()); + CloseHandle(ShExecInfo.hProcess); + return false; + } + CloseHandle(ShExecInfo.hProcess); + return true; +} + /* This function will initialize DCOM retrieving the WMI locator's ploc and * the context associated to it. */ static boolean @@ -390,14 +477,14 @@ delete_wmi_port(char *name) if (!initialize_wmi(&ploc, &pcontext)) { VLOG_WARN("Could not initialize DCOM"); - retval = false; + retval = hns_delete(name); goto error; } if (!connect_set_security(ploc, pcontext, L"Root\\Virtualization\\v2", &psvc)) { VLOG_WARN("Could not connect and set security for virtualization"); - retval = false; + retval = hns_delete(name); goto error; } @@ -673,14 +760,14 @@ create_wmi_port(char *name) { if (!initialize_wmi(&ploc, &pcontext)) { VLOG_WARN("Could not initialize DCOM"); - retval = false; + retval = hns_add(name); goto error; } if (!connect_set_security(ploc, pcontext, L"Root\\Virtualization\\v2", &psvc)) { VLOG_WARN("Could not connect and set security for virtualization"); - retval = false; + retval = hns_add(name); goto error; }