Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 67 additions & 24 deletions platform/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
)

const (
Expand Down Expand Up @@ -61,24 +64,12 @@ const (
// for vlan tagged arp requests
SDNRemoteArpMacAddress = "12-34-56-78-9a-bc"

// Command to get SDNRemoteArpMacAddress registry key
GetSdnRemoteArpMacAddressCommand = "(Get-ItemProperty " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress).SDNRemoteArpMacAddress"

// Command to set SDNRemoteArpMacAddress registry key
SetSdnRemoteArpMacAddressCommand = "Set-ItemProperty " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress -Value \"12-34-56-78-9a-bc\""

// Command to check if system has hns state path or not
CheckIfHNSStatePathExistsCommand = "Test-Path " +
"-Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State"

// Command to fetch netadapter and pnp id
//TODO can we replace this (and things in endpoint_windows) with "golang.org/x/sys/windows"
//var adapterInfo windows.IpAdapterInfo
//var bufferSize uint32 = uint32(unsafe.Sizeof(adapterInfo))
GetMacAddressVFPPnpIDMapping = "Get-NetAdapter | Select-Object MacAddress, PnpDeviceID| Format-Table -HideTableHeaders"

// Command to restart HNS service
RestartHnsServiceCommand = "Restart-Service -Name hns"

// Interval between successive checks for mellanox adapter's PriorityVLANTag value
defaultMellanoxMonitorInterval = 30 * time.Second

Expand Down Expand Up @@ -258,31 +249,38 @@ func (p *execClient) ExecutePowershellCommandWithContext(ctx context.Context, co

// SetSdnRemoteArpMacAddress sets the regkey for SDNRemoteArpMacAddress needed for multitenancy if hns is enabled
func SetSdnRemoteArpMacAddress(execClient ExecClient) error {
exists, err := execClient.ExecutePowershellCommand(CheckIfHNSStatePathExistsCommand)
key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\hns\\State", registry.READ|registry.SET_VALUE)
if err != nil {
if err == registry.ErrNotExist {
log.Printf("hns state path does not exist, skip setting SdnRemoteArpMacAddress")
return nil
}
errMsg := fmt.Sprintf("Failed to check the existent of hns state path due to error %s", err.Error())
log.Printf(errMsg)
return errors.Errorf(errMsg)
}
if strings.EqualFold(exists, "false") {
log.Printf("hns state path does not exist, skip setting SdnRemoteArpMacAddress")
return nil
}

if sdnRemoteArpMacAddressSet == false {
result, err := execClient.ExecutePowershellCommand(GetSdnRemoteArpMacAddressCommand)

//Was (Get-ItemProperty -Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress).SDNRemoteArpMacAddress"
result, _, err := key.GetStringValue("SDNRemoteArpMacAddress")
if err != nil {
return err
}

// Set the reg key if not already set or has incorrect value
if result != SDNRemoteArpMacAddress {
if _, err = execClient.ExecutePowershellCommand(SetSdnRemoteArpMacAddressCommand); err != nil {

//was "Set-ItemProperty -Path HKLM:\\SYSTEM\\CurrentControlSet\\Services\\hns\\State -Name SDNRemoteArpMacAddress -Value \"12-34-56-78-9a-bc\""

if err := key.SetStringValue("SDNRemoteArpMacAddress", SDNRemoteArpMacAddress); err != nil {
log.Printf("Failed to set SDNRemoteArpMacAddress due to error %s", err.Error())
return err
}

log.Printf("[Azure CNS] SDNRemoteArpMacAddress regKey set successfully. Restarting hns service.")
if _, err := execClient.ExecutePowershellCommand(RestartHnsServiceCommand); err != nil {

// was "Restart-Service -Name hns"
if err := restartService("hns"); err != nil {
log.Printf("Failed to Restart HNS Service due to error %s", err.Error())
return err
}
Expand All @@ -294,6 +292,50 @@ func SetSdnRemoteArpMacAddress(execClient ExecClient) error {
return nil
}

// straight out of chat gpt
func restartService(serviceName string) error {
// Connect to the service manager
m, err := mgr.Connect()
if err != nil {
return fmt.Errorf("could not connect to service manager: %v", err)
}
defer m.Disconnect()

// Open the service by name
service, err := m.OpenService(serviceName)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
}
defer service.Close()

// Stop the service
_, err = service.Control(svc.Stop)
if err != nil {
return fmt.Errorf("could not stop service: %v", err)
}

// Wait for the service to stop
status, err := service.Query()
if err != nil {
return fmt.Errorf("could not query service status: %v", err)
}
for status.State != svc.Stopped {
time.Sleep(500 * time.Millisecond)
status, err = service.Query()
if err != nil {
return fmt.Errorf("could not query service status: %v", err)
}
}

// Start the service again
err = service.Start()
if err != nil {
return fmt.Errorf("could not start service: %v", err)
}

return nil
}

func HasMellanoxAdapter() bool {
m := &mellanox.Mellanox{}
return hasNetworkAdapter(m)
Expand Down Expand Up @@ -364,6 +406,7 @@ func GetProcessNameByID(pidstr string) (string, error) {
pidstr = strings.Trim(pidstr, "\r\n")
cmd := fmt.Sprintf("Get-Process -Id %s|Format-List", pidstr)
p := NewExecClient(nil)
//TODO not riemovign this because it seems to only be called in test?
out, err := p.ExecutePowershellCommand(cmd)
if err != nil {
log.Printf("Process is not running. Output:%v, Error %v", out, err)
Expand Down