diff --git a/cns/hnsclient/hnsclient_windows.go b/cns/hnsclient/hnsclient_windows.go index 076270274e..58bf884b74 100644 --- a/cns/hnsclient/hnsclient_windows.go +++ b/cns/hnsclient/hnsclient_windows.go @@ -17,6 +17,7 @@ import ( "github.com/pkg/errors" ) +// TODO redesign hnsclient on windows const ( // Name of the external hns network ExtHnsNetworkName = "ext" @@ -53,6 +54,9 @@ const ( // Name of the loopback adapter needed to create Host NC apipa network hostNCLoopbackAdapterName = "LoopbackAdapterHostNCConnectivity" + // HNS rehydration issue requires this GW to be different than the loopback adapter ip, so we set it to .2 + defaultHnsGwIPAddress = "169.254.128.2" + hnsLoopbackAdapterIPAddress = "169.254.128.1" // protocolTCP indicates the TCP protocol identifier in HCN protocolTCP = "6" @@ -301,7 +305,7 @@ func createHostNCApipaNetwork( if interfaceExists, _ := networkcontainers.InterfaceExists(hostNCLoopbackAdapterName); !interfaceExists { ipconfig := cns.IPConfiguration{ IPSubnet: cns.IPSubnet{ - IPAddress: localIPConfiguration.GatewayIPAddress, + IPAddress: hnsLoopbackAdapterIPAddress, PrefixLength: localIPConfiguration.IPSubnet.PrefixLength, }, GatewayIPAddress: localIPConfiguration.GatewayIPAddress, @@ -510,7 +514,7 @@ func configureHostNCApipaEndpoint( endpointPolicies, err := configureAclSettingHostNCApipaEndpoint( protocolList, networkContainerApipaIP, - hostApipaIP, + hnsLoopbackAdapterIPAddress, allowNCToHostCommunication, allowHostToNCCommunication, ncPolicies) @@ -573,6 +577,7 @@ func CreateHostNCApipaEndpoint( return endpoint.Id, nil } + updateGwForLocalIPConfiguration(&localIPConfiguration) if network, err = createHostNCApipaNetwork(localIPConfiguration); err != nil { logger.Errorf("[Azure CNS] Failed to create HostNCApipaNetwork. Error: %v", err) return "", err @@ -604,6 +609,17 @@ func CreateHostNCApipaEndpoint( return endpoint.Id, nil } +// updateGwForLocalIPConfiguration applies change on gw IP address for apipa NW and endpoint. +// Currently, cns using the same ip address "169.254.128.1" for both apipa gw and loopback adapter. This cause conflict issue when hns get restarted and not able to rehydrate the apipa endpoints. +// This func is to overwrite the address to 169.254.128.2 when the gateway address is 169.254.128.1 +func updateGwForLocalIPConfiguration(localIPConfiguration *cns.IPConfiguration) { + // When gw address is 169.254.128.1, should use .2 instead. If gw address is not .1, that mean this value is + // configured from dnc, we should keep it + if localIPConfiguration.GatewayIPAddress == "169.254.128.1" { + localIPConfiguration.GatewayIPAddress = defaultHnsGwIPAddress + } +} + func getHostNCApipaEndpointName( networkContainerID string) string { return hostNCApipaEndpointNamePrefix + "-" + networkContainerID diff --git a/cns/hnsclient/hnsclient_windows_test.go b/cns/hnsclient/hnsclient_windows_test.go new file mode 100644 index 0000000000..8b01d2f839 --- /dev/null +++ b/cns/hnsclient/hnsclient_windows_test.go @@ -0,0 +1,35 @@ +package hnsclient + +import ( + "testing" + + "github.com/Azure/azure-container-networking/cns" + "github.com/stretchr/testify/assert" +) + +func TestAdhocAdjustIPConfig(t *testing.T) { + tests := []struct { + name string + ipConfig cns.IPConfiguration + expected cns.IPConfiguration + }{ + { + name: "expect no change when gw address is not 169.254.128.1", + ipConfig: cns.IPConfiguration{GatewayIPAddress: "169.254.128.3"}, + expected: cns.IPConfiguration{GatewayIPAddress: "169.254.128.3"}, + }, + { + name: "expect default gw address is set when gw address is 169.254.128.1", + ipConfig: cns.IPConfiguration{GatewayIPAddress: "169.254.128.1"}, + expected: cns.IPConfiguration{GatewayIPAddress: "169.254.128.2"}, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + updateGwForLocalIPConfiguration(&tt.ipConfig) + assert.Equal(t, tt.expected.GatewayIPAddress, tt.ipConfig.GatewayIPAddress) + }) + } +}