Skip to content

Commit

Permalink
add prefix length from mtpnc to podipinfo & gatewayip (#2828)
Browse files Browse the repository at this point in the history
* add prefix length from mtpnc to podipinfo & gatewayip

* separate getIpConfig based on OS for HNS prefix changes, add subnet in UTs

* import packages

* refactor middleware into os files after rebase w/ master

* split only the subnet-prefix assign part

* fix lint errors

* add UTs to test the function's behavior for linux vs windows

---------

Signed-off-by: Kshitija Murudi <kmurudi@microsoft.com>
Co-authored-by: paulyufan2 <paulyu01@outlook.com>
  • Loading branch information
kmurudi and paulyufan2 authored Jul 9, 2024
1 parent dc0c474 commit e3b25da
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 3 deletions.
13 changes: 10 additions & 3 deletions cns/middlewares/k8sSwiftV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodI
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}
podIPInfos = append(podIPInfos, cns.PodIpInfo{

podIPInfo := cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
Expand All @@ -230,9 +231,15 @@ func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodI
NICType: cns.DelegatedVMNIC,
SkipDefaultRoutes: false,
// InterfaceName is empty for DelegatedVMNIC
})
}
// for windows scenario, it is required to add additional fields with the exact subnetAddressSpace
// received from MTPNC, this function assigns them for windows while linux is a no-op
err = k.assignSubnetPrefixLengthFields(&podIPInfo, interfaceInfo, ip)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc subnetAddressSpace prefix")
}
podIPInfos = append(podIPInfos, podIPInfo)
}

}
}

Expand Down
6 changes: 6 additions & 0 deletions cns/middlewares/k8sSwiftV2_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/Azure/azure-container-networking/cns/configuration"
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/middlewares/utils"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -95,3 +96,8 @@ func addRoutes(cidrs []string, gatewayIP string) []cns.Route {
}
return routes
}

// assignSubnetPrefixLengthFields is a no-op for linux swiftv2 as the default prefix-length is sufficient
func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(_ *cns.PodIpInfo, _ v1alpha1.InterfaceInfo, _ string) error {
return nil
}
27 changes: 27 additions & 0 deletions cns/middlewares/k8sSwiftV2_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/middlewares/mock"
"github.com/Azure/azure-container-networking/cns/types"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"gotest.tools/v3/assert"
)

Expand Down Expand Up @@ -455,3 +456,29 @@ func TestGetSWIFTv2IPConfigMultiInterfaceSuccess(t *testing.T) {
assert.Equal(t, ipInfo.SkipDefaultRoutes, false)
}
}

func TestAssignSubnetPrefixSuccess(t *testing.T) {
middleware := K8sSWIFTv2Middleware{Cli: mock.NewClient()}

podIPInfo := cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: "20.240.1.242",
PrefixLength: 32,
},
NICType: cns.DelegatedVMNIC,
MacAddress: "12:34:56:78:9a:bc",
}

intInfo := v1alpha1.InterfaceInfo{
GatewayIP: "20.240.1.1",
SubnetAddressSpace: "20.240.1.0/16",
}

ipInfo := podIPInfo
err := middleware.assignSubnetPrefixLengthFields(&ipInfo, intInfo, ipInfo.PodIPConfig.IPAddress)
assert.Equal(t, err, nil)
// assert that the function for linux does not modify any fields
assert.Equal(t, ipInfo.PodIPConfig.PrefixLength, uint8(32))
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Gateway, "")
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Subnet, "")
}
28 changes: 28 additions & 0 deletions cns/middlewares/k8sSwiftV2_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package middlewares
import (
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/middlewares/utils"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"github.com/pkg/errors"
)

// for AKS L1VH, do not set default route on infraNIC to avoid customer pod reaching all infra vnet services
Expand All @@ -14,3 +17,28 @@ func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
}
return nil
}

// assignSubnetPrefixLengthFields will assign the subnet-prefix length to some fields of podipinfo
// this is required for the windows scenario so that HNS programming is successful for pods
func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(podIPInfo *cns.PodIpInfo, interfaceInfo v1alpha1.InterfaceInfo, ip string) error {
// Parse MTPNC SubnetAddressSpace to get the subnet prefix length
subnet, subnetPrefix, err := utils.ParseIPAndPrefix(interfaceInfo.SubnetAddressSpace)
if err != nil {
return errors.Wrap(err, "failed to parse mtpnc subnetAddressSpace prefix")
}
// assign the subnet-prefix length to all fields in podipinfo
podIPInfo.PodIPConfig.PrefixLength = uint8(subnetPrefix)
podIPInfo.HostPrimaryIPInfo = cns.HostIPInfo{
Gateway: interfaceInfo.GatewayIP,
PrimaryIP: ip,
Subnet: interfaceInfo.SubnetAddressSpace,
}
podIPInfo.NetworkContainerPrimaryIPConfig = cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: subnet,
PrefixLength: uint8(subnetPrefix),
},
GatewayIPAddress: interfaceInfo.GatewayIP,
}
return nil
}
27 changes: 27 additions & 0 deletions cns/middlewares/k8sSwiftV2_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/middlewares/mock"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"gotest.tools/v3/assert"
)

Expand Down Expand Up @@ -39,3 +40,29 @@ func TestSetRoutesSuccess(t *testing.T) {
}
}
}

func TestAssignSubnetPrefixSuccess(t *testing.T) {
middleware := K8sSWIFTv2Middleware{Cli: mock.NewClient()}

podIPInfo := cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: "20.240.1.242",
PrefixLength: 32,
},
NICType: cns.DelegatedVMNIC,
MacAddress: "12:34:56:78:9a:bc",
}

intInfo := v1alpha1.InterfaceInfo{
GatewayIP: "20.240.1.1",
SubnetAddressSpace: "20.240.1.0/16",
}

ipInfo := podIPInfo
err := middleware.assignSubnetPrefixLengthFields(&ipInfo, intInfo, ipInfo.PodIPConfig.IPAddress)
assert.Equal(t, err, nil)
// assert that the function for windows modifies all the expected fields with prefix-length
assert.Equal(t, ipInfo.PodIPConfig.PrefixLength, uint8(16))
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Gateway, intInfo.GatewayIP)
assert.Equal(t, ipInfo.HostPrimaryIPInfo.Subnet, intInfo.SubnetAddressSpace)
}
4 changes: 4 additions & 0 deletions cns/middlewares/mock/mockClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func NewClient() *Client {
GatewayIP: "10.0.0.1",
DeviceType: v1alpha1.DeviceTypeVnetNIC,
AccelnetEnabled: false,
SubnetAddressSpace: "192.168.0.0/24",
}
testInterfaceInfos3 := v1alpha1.InterfaceInfo{
NCID: "testncid",
Expand All @@ -81,6 +82,7 @@ func NewClient() *Client {
GatewayIP: "10.0.0.1",
DeviceType: v1alpha1.DeviceTypeVnetNIC,
AccelnetEnabled: false,
SubnetAddressSpace: "192.168.0.0/24",
}
testInterfaceInfos5 := v1alpha1.InterfaceInfo{
NCID: "testncid",
Expand All @@ -89,6 +91,7 @@ func NewClient() *Client {
GatewayIP: "10.0.0.1",
DeviceType: v1alpha1.DeviceTypeInfiniBandNIC,
AccelnetEnabled: true,
SubnetAddressSpace: "192.168.0.0/24",
}

testMTPNC1 := v1alpha1.MultitenantPodNetworkConfig{
Expand Down Expand Up @@ -216,6 +219,7 @@ func (c *Client) SetMTPNCReady() {
GatewayIP: "10.0.0.1",
DeviceType: v1alpha1.DeviceTypeVnetNIC,
AccelnetEnabled: false,
SubnetAddressSpace: "192.168.0.0/24",
}

testMTPNC1 := v1alpha1.MultitenantPodNetworkConfig{}
Expand Down

0 comments on commit e3b25da

Please sign in to comment.