Skip to content

Commit fa2de6d

Browse files
authored
set mellanox reg key (#1768)
1 parent f687dee commit fa2de6d

File tree

10 files changed

+505
-1
lines changed

10 files changed

+505
-1
lines changed

cns/configuration/cns_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
"MSISettings": {
3030
"ResourceID": ""
3131
},
32-
"PopulateHomeAzCacheRetryIntervalSecs": 15
32+
"PopulateHomeAzCacheRetryIntervalSecs": 15,
33+
"MellanoxMonitorIntervalSecs": 30
3334
}

cns/configuration/configuration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type CNSConfig struct {
4343
EnableCNIConflistGeneration bool
4444
CNIConflistFilepath string
4545
PopulateHomeAzCacheRetryIntervalSecs int
46+
MellanoxMonitorIntervalSecs int
4647
}
4748

4849
type TelemetrySettings struct {

cns/service/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,17 @@ func main() {
714714
return
715715
}
716716

717+
// We are only setting the PriorityVLANTag in 'cns.Direct' mode, because it neatly maps today, to 'isUsingMultitenancy'
718+
// In the future, we would want to have a better CNS flag, to explicitly say, this CNS is using multitenancy
719+
if config.ChannelMode == cns.Direct {
720+
// Set Mellanox adapter's PriorityVLANTag value to 3 if adapter exists
721+
// reg key value for PriorityVLANTag = 3 --> Packet priority and VLAN enabled
722+
// for more details goto https://docs.nvidia.com/networking/display/winof2v230/Configuring+the+Driver+Registry+Keys#ConfiguringtheDriverRegistryKeys-GeneralRegistryKeysGeneralRegistryKeys
723+
if platform.HasMellanoxAdapter() {
724+
go platform.MonitorAndSetMellanoxRegKeyPriorityVLANTag(rootCtx, cnsconfig.MellanoxMonitorIntervalSecs)
725+
}
726+
}
727+
717728
// Initialze state in if CNS is running in CRD mode
718729
// State must be initialized before we start HTTPRestService
719730
if config.ChannelMode == cns.CRD {

platform/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
REPO_ROOT = $(shell git rev-parse --show-toplevel)
2+
TOOLS_BIN_DIR = $(REPO_ROOT)/build/tools/bin
3+
MOCKGEN = $(TOOLS_BIN_DIR)/mockgen
4+
5+
.PHONY: generate
6+
7+
generate: $(MOCKGEN) ## Generate mock clients
8+
$(MOCKGEN) -source=$(REPO_ROOT)/platform/windows/adapter/network_adapter.go -package=mocks NetworkAdapter > windows/adapter/mocks/networkadapter_generated.go
9+
10+
$(MOCKGEN):
11+
@make -C $(REPO_ROOT) $(MOCKGEN)

platform/os_linux.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,11 @@ func PrintDependencyPackageDetails() {
179179
func ReplaceFile(source, destination string) error {
180180
return os.Rename(source, destination)
181181
}
182+
183+
// Mellanox adapter not applicable for linux
184+
func HasMellanoxAdapter() bool {
185+
return false
186+
}
187+
188+
// Not needed for Linux
189+
func MonitorAndSetMellanoxRegKeyPriorityVLANTag(_ context.Context, _ int) {}

platform/os_windows.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package platform
55

66
import (
77
"bytes"
8+
"context"
89
"fmt"
910
"os"
1011
"os/exec"
@@ -13,6 +14,8 @@ import (
1314
"time"
1415

1516
"github.com/Azure/azure-container-networking/log"
17+
"github.com/Azure/azure-container-networking/platform/windows/adapter"
18+
"github.com/Azure/azure-container-networking/platform/windows/adapter/mellanox"
1619
"golang.org/x/sys/windows"
1720
)
1821

@@ -65,6 +68,14 @@ const (
6568

6669
// Command to restart HNS service
6770
RestartHnsServiceCommand = "Restart-Service -Name hns"
71+
72+
// Interval between successive checks for mellanox adapter's PriorityVLANTag value
73+
defaultMellanoxMonitorInterval = 30 * time.Second
74+
75+
// Value for reg key: PriorityVLANTag for adapter
76+
// reg key value for PriorityVLANTag = 3 --> Packet priority and VLAN enabled
77+
// for more details goto https://learn.microsoft.com/en-us/windows-hardware/drivers/network/standardized-inf-keywords-for-ndis-qos
78+
desiredVLANTagForMellanox = 3
6879
)
6980

7081
// Flag to check if sdnRemoteArpMacAddress registry key is set
@@ -189,6 +200,68 @@ func SetSdnRemoteArpMacAddress() error {
189200
return nil
190201
}
191202

203+
func HasMellanoxAdapter() bool {
204+
m := &mellanox.Mellanox{}
205+
return hasNetworkAdapter(m)
206+
}
207+
208+
func hasNetworkAdapter(na adapter.NetworkAdapter) bool {
209+
adapterName, err := na.GetAdapterName()
210+
if err != nil {
211+
log.Errorf("Error while getting network adapter name: %v", err)
212+
return false
213+
}
214+
log.Printf("Name of the network adapter : %v", adapterName)
215+
return true
216+
}
217+
218+
// Regularly monitors the Mellanox PriorityVLANGTag registry value and sets it to desired value if needed
219+
func MonitorAndSetMellanoxRegKeyPriorityVLANTag(ctx context.Context, intervalSecs int) {
220+
m := &mellanox.Mellanox{}
221+
interval := defaultMellanoxMonitorInterval
222+
if intervalSecs > 0 {
223+
interval = time.Duration(intervalSecs) * time.Second
224+
}
225+
err := updatePriorityVLANTagIfRequired(m, desiredVLANTagForMellanox)
226+
if err != nil {
227+
log.Errorf("Error while monitoring mellanox, continuing: %v", err)
228+
}
229+
ticker := time.NewTicker(interval)
230+
defer ticker.Stop()
231+
for {
232+
select {
233+
case <-ctx.Done():
234+
log.Printf("context cancelled, stopping Mellanox Monitoring: %v", ctx.Err())
235+
return
236+
case <-ticker.C:
237+
err := updatePriorityVLANTagIfRequired(m, desiredVLANTagForMellanox)
238+
if err != nil {
239+
log.Errorf("Error while monitoring mellanox, continuing: %v", err)
240+
}
241+
}
242+
}
243+
}
244+
245+
// Updates the priority VLAN Tag of mellanox adapter if not already set to the desired value
246+
func updatePriorityVLANTagIfRequired(na adapter.NetworkAdapter, desiredValue int) error {
247+
currentVal, err := na.GetPriorityVLANTag()
248+
if err != nil {
249+
return fmt.Errorf("error while getting Priority VLAN Tag value: %w", err)
250+
}
251+
252+
if currentVal == desiredValue {
253+
log.Printf("Adapter's PriorityVLANTag is already set to %v, skipping reset", desiredValue)
254+
return nil
255+
}
256+
257+
err = na.SetPriorityVLANTag(desiredValue)
258+
if err != nil {
259+
return fmt.Errorf("error while setting Priority VLAN Tag value: %w", err)
260+
}
261+
262+
return nil
263+
}
264+
192265
func GetOSDetails() (map[string]string, error) {
193266
return nil, nil
194267
}

platform/os_windows_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package platform
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/Azure/azure-container-networking/platform/windows/adapter/mocks"
8+
"github.com/golang/mock/gomock"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
var errTestFailure = errors.New("test failure")
13+
14+
// Test if hasNetworkAdapter returns false on actual error or empty adapter name(an error)
15+
func TestHasNetworkAdapterReturnsError(t *testing.T) {
16+
ctrl := gomock.NewController(t)
17+
defer ctrl.Finish()
18+
19+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
20+
mockNetworkAdapter.EXPECT().GetAdapterName().Return("", errTestFailure)
21+
22+
result := hasNetworkAdapter(mockNetworkAdapter)
23+
assert.False(t, result)
24+
}
25+
26+
// Test if hasNetworkAdapter returns false on actual error or empty adapter name(an error)
27+
func TestHasNetworkAdapterAdapterReturnsEmptyAdapterName(t *testing.T) {
28+
ctrl := gomock.NewController(t)
29+
defer ctrl.Finish()
30+
31+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
32+
mockNetworkAdapter.EXPECT().GetAdapterName().Return("Ethernet 3", nil)
33+
34+
result := hasNetworkAdapter(mockNetworkAdapter)
35+
assert.True(t, result)
36+
}
37+
38+
// Test if updatePriorityVLANTagIfRequired returns error on getting error on calling getpriorityvlantag
39+
func TestUpdatePriorityVLANTagIfRequiredReturnsError(t *testing.T) {
40+
ctrl := gomock.NewController(t)
41+
defer ctrl.Finish()
42+
43+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
44+
mockNetworkAdapter.EXPECT().GetPriorityVLANTag().Return(0, errTestFailure)
45+
result := updatePriorityVLANTagIfRequired(mockNetworkAdapter, 3)
46+
assert.EqualError(t, result, "error while getting Priority VLAN Tag value: test failure")
47+
}
48+
49+
// Test if updatePriorityVLANTagIfRequired returns nil if currentval == desiredvalue (SetPriorityVLANTag not being called)
50+
func TestUpdatePriorityVLANTagIfRequiredIfCurrentValEqualDesiredValue(t *testing.T) {
51+
ctrl := gomock.NewController(t)
52+
defer ctrl.Finish()
53+
54+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
55+
mockNetworkAdapter.EXPECT().GetPriorityVLANTag().Return(4, nil)
56+
result := updatePriorityVLANTagIfRequired(mockNetworkAdapter, 4)
57+
assert.NoError(t, result)
58+
}
59+
60+
// Test if updatePriorityVLANTagIfRequired returns nil if SetPriorityVLANTag being called to set value
61+
func TestUpdatePriorityVLANTagIfRequiredIfCurrentValNotEqualDesiredValAndSetReturnsNoError(t *testing.T) {
62+
ctrl := gomock.NewController(t)
63+
defer ctrl.Finish()
64+
65+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
66+
mockNetworkAdapter.EXPECT().GetPriorityVLANTag().Return(1, nil)
67+
mockNetworkAdapter.EXPECT().SetPriorityVLANTag(2).Return(nil)
68+
result := updatePriorityVLANTagIfRequired(mockNetworkAdapter, 2)
69+
assert.NoError(t, result)
70+
}
71+
72+
// Test if updatePriorityVLANTagIfRequired returns error if SetPriorityVLANTag throwing error
73+
74+
func TestUpdatePriorityVLANTagIfRequiredIfCurrentValNotEqualDesiredValAndSetReturnsError(t *testing.T) {
75+
ctrl := gomock.NewController(t)
76+
defer ctrl.Finish()
77+
78+
mockNetworkAdapter := mocks.NewMockNetworkAdapter(ctrl)
79+
mockNetworkAdapter.EXPECT().GetPriorityVLANTag().Return(1, nil)
80+
mockNetworkAdapter.EXPECT().SetPriorityVLANTag(5).Return(errTestFailure)
81+
result := updatePriorityVLANTagIfRequired(mockNetworkAdapter, 5)
82+
assert.EqualError(t, result, "error while setting Priority VLAN Tag value: test failure")
83+
}

0 commit comments

Comments
 (0)