Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: prevent CNS hanging on HNS restart #3343

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
6 changes: 5 additions & 1 deletion cns/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,11 +799,15 @@ func main() {
}

// Setting the remote ARP MAC address to 12-34-56-78-9a-bc on windows for external traffic if HNS is enabled
err = platform.SetSdnRemoteArpMacAddress(rootCtx)
arpCtx, arpCtxCancel := context.WithTimeout(rootCtx, 30*time.Second)
err = platform.SetSdnRemoteArpMacAddress(arpCtx)
if err != nil {
logger.Errorf("Failed to set remote ARP MAC address: %v", err)
arpCtxCancel()
rbtr marked this conversation as resolved.
Show resolved Hide resolved
return
}
arpCtxCancel()

// We are only setting the PriorityVLANTag in 'cns.Direct' mode, because it neatly maps today, to 'isUsingMultitenancy'
// In the future, we would want to have a better CNS flag, to explicitly say, this CNS is using multitenancy
if cnsconfig.ChannelMode == cns.Direct {
Expand Down
31 changes: 19 additions & 12 deletions platform/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,18 @@ func (p *execClient) ExecutePowershellCommandWithContext(ctx context.Context, co

// SetSdnRemoteArpMacAddress sets the regkey for SDNRemoteArpMacAddress needed for multitenancy if hns is enabled
func SetSdnRemoteArpMacAddress(ctx context.Context) error {
if err := setSDNRemoteARPRegKey(); err != nil {
return err
}
log.Printf("SDNRemoteArpMacAddress regKey set successfully")
if err := restartHNS(ctx); err != nil {
return err
}
log.Printf("HNS service restarted successfully")
return nil
}

func setSDNRemoteARPRegKey() error {
log.Printf("Setting SDNRemoteArpMacAddress regKey")
// open the registry key
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\hns\State`, registry.READ|registry.SET_VALUE)
Expand All @@ -265,7 +277,10 @@ func SetSdnRemoteArpMacAddress(ctx context.Context) error {
if err = k.SetStringValue("SDNRemoteArpMacAddress", SDNRemoteArpMacAddress); err != nil {
return errors.Wrap(err, "could not set registry key")
}
log.Printf("SDNRemoteArpMacAddress regKey set successfully")
return nil
}

func restartHNS(ctx context.Context) error {
log.Printf("Restarting HNS service")
// connect to the service manager
m, err := mgr.Connect()
Expand All @@ -279,24 +294,16 @@ func SetSdnRemoteArpMacAddress(ctx context.Context) error {
return errors.Wrap(err, "could not access service")
}
defer service.Close()
if err := restartService(ctx, service); err != nil {
return errors.Wrap(err, "could not restart service")
}
log.Printf("HNS service restarted successfully")
return nil
}

func restartService(ctx context.Context, s *mgr.Service) error {
// Stop the service
_, err := s.Control(svc.Stop)
_, err = service.Control(svc.Stop)
rbtr marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return errors.Wrap(err, "could not stop service")
}
// Wait for the service to stop
ticker := time.NewTicker(500 * time.Millisecond) //nolint:gomnd // 500ms
defer ticker.Stop()
for { // hacky cancellable do-while
status, err := s.Query()
status, err := service.Query()
if err != nil {
return errors.Wrap(err, "could not query service status")
}
Expand All @@ -310,7 +317,7 @@ func restartService(ctx context.Context, s *mgr.Service) error {
}
}
// Start the service again
if err := s.Start(); err != nil {
if err := service.Start(); err != nil {
return errors.Wrap(err, "could not start service")
}
return nil
Expand Down
Loading