Skip to content

Commit 01e4ea0

Browse files
Add registry keys for prefix on nic scenario
1 parent a1550f2 commit 01e4ea0

File tree

6 files changed

+139
-2
lines changed

6 files changed

+139
-2
lines changed

cns/NetworkContainerContract.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ type CreateNetworkContainerRequest struct {
128128
AllowNCToHostCommunication bool
129129
EndpointPolicies []NetworkContainerRequestPolicies
130130
NCStatus v1alpha.NCStatus
131+
SwiftV2PrefixOnNic bool // Indicates if is swiftv2 nc, PrefixOnNic scenario (isSwiftV2 && nc.Type == VNETBlock)
131132
NetworkInterfaceInfo NetworkInterfaceInfo //nolint // introducing new field for backendnic, to be used later by cni code
132133
}
133134

cns/kubecontroller/nodenetworkconfig/conversion.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func CreateNCRequestFromDynamicNC(nc v1alpha.NetworkContainer) (*cns.CreateNetwo
6262
NetworkContainerid: nc.ID,
6363
NetworkContainerType: cns.Docker,
6464
Version: strconv.FormatInt(nc.Version, 10), //nolint:gomnd // it's decimal
65+
SwiftV2PrefixOnNic: false, // Dynamic NCs don't use SwiftV2 PrefixOnNic
6566
IPConfiguration: cns.IPConfiguration{
6667
IPSubnet: subnet,
6768
GatewayIPAddress: nc.DefaultGateway,

cns/kubecontroller/nodenetworkconfig/conversion_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func createNCRequestFromStaticNCHelper(nc v1alpha.NetworkContainer, primaryIPPre
6060
GatewayIPv6Address: nc.DefaultGatewayV6,
6161
},
6262
NCStatus: nc.Status,
63+
SwiftV2PrefixOnNic: isSwiftV2 && nc.Type == v1alpha.VNETBlock,
6364
NetworkInterfaceInfo: cns.NetworkInterfaceInfo{
6465
MACAddress: nc.MacAddress,
6566
},

cns/restserver/internalapi.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strconv"
1616
"strings"
1717
"time"
18+
"runtime"
1819

1920
"github.com/Azure/azure-container-networking/cns"
2021
"github.com/Azure/azure-container-networking/cns/logger"
@@ -194,6 +195,16 @@ var errNonExistentContainerStatus = errors.New("nonExistantContainerstatus")
194195
// all NCs and update the CNS state accordingly. This function returns the the total number of NCs on this VM that have been programmed to
195196
// some version, NOT the number of NCs that are up-to-date.
196197
func (service *HTTPRestService) syncHostNCVersion(ctx context.Context, channelMode string) (int, error) {
198+
// will remove it later
199+
// hasVNETBlockNC1 := service.isPrefixonNicSwiftV2()
200+
// logger.Printf("winDebug: syncHostNCVersion hasVNETBlockNC1 %v", hasVNETBlockNC1)
201+
// if runtime.GOOS == "windows" {
202+
// logger.Printf("winDebug: before setPrefixOnNICRegistry in syncHostNCVersion")
203+
// err := service.setPrefixOnNICRegistry(true, "aa:bb:cc:dd:ee:ff")
204+
// if err != nil {
205+
// logger.Debugf("failed to add PrefixOnNic keys to Windows registry: %w", err)
206+
// }
207+
// }
197208
outdatedNCs := map[string]struct{}{}
198209
programmedNCs := map[string]struct{}{}
199210
for idx := range service.state.ContainerStatus {
@@ -219,7 +230,7 @@ func (service *HTTPRestService) syncHostNCVersion(ctx context.Context, channelMo
219230
programmedNCs[service.state.ContainerStatus[idx].ID] = struct{}{}
220231
}
221232
}
222-
if len(outdatedNCs) == 0 {
233+
if len(outdatedNCs) != 0 {
223234
return len(programmedNCs), nil
224235
}
225236

@@ -717,8 +728,27 @@ func (service *HTTPRestService) GetIMDSNCs(ctx context.Context) (map[string]stri
717728

718729
if ncID != "" {
719730
ncs[ncID] = PrefixOnNicNCVersion // for prefix on nic version scenario nc version is 1
731+
} else if runtime.GOOS == "windows" && service.isPrefixonNicSwiftV2() {
732+
err := service.setPrefixOnNICRegistry(true, iface.MacAddress.String())
733+
if err != nil {
734+
logger.Debugf("failed to add PrefixOnNic keys to Windows registry: %w", err)
735+
}
720736
}
721737
}
722738

723739
return ncs, nil
724740
}
741+
742+
// isPrefixonNicSwiftV2 checks if any NC in the container status should use SwiftV2 PrefixOnNic
743+
// Uses the SwiftV2PrefixOnNic field which captures the condition: isSwiftV2 && nc.Type == VNETBlock
744+
func (service *HTTPRestService) isPrefixonNicSwiftV2() bool {
745+
for _, containerStatus := range service.state.ContainerStatus {
746+
req := containerStatus.CreateNetworkContainerRequest
747+
748+
// Check if this NC is SwiftV2 PrefixOnNic setting
749+
if req.SwiftV2PrefixOnNic {
750+
return true
751+
}
752+
}
753+
return false
754+
}

cns/restserver/internalapi_linux.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,13 @@ func (service *HTTPRestService) programSNATRules(req *cns.CreateNetworkContainer
181181
func (service *HTTPRestService) setVFForAccelnetNICs() error {
182182
return nil
183183
}
184+
185+
func (service *HTTPRestService) setPrefixOnNICRegistry(enabled bool, infraNicMacAddress string) error {
186+
logger.Printf("[setPrefixOnNicEnabled winDebug] No-op on Linux platform")
187+
return nil
188+
}
189+
190+
func (service *HTTPRestService) getPrefixOnNicEnabled() (bool, error) {
191+
logger.Printf(" winDebug getPrefixOnNicEnabled is a no-op on non-Windows platforms")
192+
return false, nil // Add this missing return statement
193+
}

cns/restserver/internalapi_windows.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@ import (
66
"time"
77

88
"github.com/Azure/azure-container-networking/cns"
9+
"github.com/Azure/azure-container-networking/cns/logger"
910
"github.com/Azure/azure-container-networking/cns/types"
1011
"github.com/Microsoft/hcsshim"
1112
"github.com/pkg/errors"
13+
"golang.org/x/sys/windows/registry"
1214
)
1315

1416
const (
1517
// timeout for powershell command to return the interfaces list
16-
pwshTimeout = 120 * time.Second
18+
pwshTimeout = 120 * time.Second
19+
hnsRegistryPath = `SYSTEM\CurrentControlSet\Services\HNS\wcna_state\config`
20+
prefixOnNicRegistryPath = `SYSTEM\CurrentControlSet\Services\HNS\wcna_state\config\PrefixOnNic`
21+
infraNicIfName = "eth0"
22+
enableSNAT = false
1723
)
1824

1925
var errUnsupportedAPI = errors.New("unsupported api")
@@ -75,3 +81,91 @@ func (service *HTTPRestService) getPrimaryNICMACAddress() (string, error) {
7581
}
7682
return macAddress, nil
7783
}
84+
85+
func (service *HTTPRestService) enablePrefixOnNic(enabled bool) error {
86+
return service.setRegistryValue(prefixOnNicRegistryPath, "enabled", enabled)
87+
}
88+
89+
func (service *HTTPRestService) setInfraNicMacAddress(macAddress string) error {
90+
return service.setRegistryValue(prefixOnNicRegistryPath, "infra_nic_mac_address", macAddress)
91+
}
92+
93+
func (service *HTTPRestService) setInfraNicIfName(ifName string) error {
94+
return service.setRegistryValue(prefixOnNicRegistryPath, "infra_nic_ifname", ifName)
95+
}
96+
97+
func (service *HTTPRestService) setEnableSNAT(enabled bool) error {
98+
return service.setRegistryValue(hnsRegistryPath, "EnableSNAT", enabled)
99+
}
100+
101+
func (service *HTTPRestService) setPrefixOnNICRegistry(enablePrefixOnNic bool, infraNicMacAddress string) error {
102+
if err := service.enablePrefixOnNic(enablePrefixOnNic); err != nil {
103+
return fmt.Errorf("failed to set enablePrefixOnNic key to windows registry: %w", err)
104+
}
105+
106+
if err := service.setInfraNicMacAddress(infraNicMacAddress); err != nil {
107+
return fmt.Errorf("failed to set InfraNicMacAddress key to windows registry: %w", err)
108+
}
109+
110+
if err := service.setInfraNicIfName(infraNicIfName); err != nil {
111+
return fmt.Errorf("failed to set InfraNicIfName key to windows registry: %w", err)
112+
}
113+
114+
if err := service.setEnableSNAT(enableSNAT); err != nil {
115+
return fmt.Errorf("failed to set EnableSNAT key to windows registry: %w", err)
116+
}
117+
118+
return nil
119+
}
120+
121+
func (service *HTTPRestService) setRegistryValue(registryPath, keyName string, value interface{}) error {
122+
key, _, err := registry.CreateKey(registry.LOCAL_MACHINE, registryPath, registry.SET_VALUE)
123+
if err != nil {
124+
return fmt.Errorf("failed to create/open registry key %s: %w", registryPath, err)
125+
}
126+
defer key.Close()
127+
128+
switch v := value.(type) {
129+
case string:
130+
err = key.SetStringValue(keyName, v)
131+
case bool:
132+
dwordValue := uint32(0)
133+
if v {
134+
dwordValue = 1
135+
}
136+
err = key.SetDWordValue(keyName, dwordValue)
137+
case uint32:
138+
err = key.SetDWordValue(keyName, v)
139+
case int:
140+
err = key.SetDWordValue(keyName, uint32(v))
141+
default:
142+
return fmt.Errorf("unsupported value type for registry key %s: %T", keyName, value)
143+
}
144+
145+
if err != nil {
146+
return fmt.Errorf("failed to set registry value '%s': %w", keyName, err)
147+
}
148+
149+
logger.Printf("[setRegistryValue] Set %s\\%s = %v", registryPath, keyName, value)
150+
// have to remove this log later
151+
// test, _ := service.getPrefixOnNicEnabled()
152+
// logger.Printf("winDebug: setRegistryValue getPrefixOnNicEnabled %v", test)
153+
return nil
154+
}
155+
156+
// for testing purpose, will remove it later
157+
158+
// func (service *HTTPRestService) getPrefixOnNicEnabled() (bool, error) {
159+
// key, err := registry.OpenKey(registry.LOCAL_MACHINE, prefixOnNicRegistryPath, registry.QUERY_VALUE)
160+
// if err != nil {
161+
// return false, nil // Key doesn't exist, default to false
162+
// }
163+
// defer key.Close()
164+
165+
// value, _, err := key.GetIntegerValue("enabled")
166+
// if err != nil {
167+
// return false, nil // Value doesn't exist, default to false
168+
// }
169+
170+
// return value == 1, nil
171+
// }

0 commit comments

Comments
 (0)