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

add prefix length from mtpnc to podipinfo & gatewayip #2828

Merged
merged 9 commits into from
Jul 10, 2024
81 changes: 0 additions & 81 deletions cns/middlewares/k8sSwiftV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/Azure/azure-container-networking/cns"
"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/cns/types"
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
"github.com/pkg/errors"
Expand Down Expand Up @@ -132,83 +131,3 @@ func (k *K8sSWIFTv2Middleware) validateIPConfigsRequest(ctx context.Context, req
// retrieve podinfo from orchestrator context
return podInfo, types.Success, ""
}

// getIPConfig returns the pod's SWIFT V2 IP configuration.
func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodInfo) ([]cns.PodIpInfo, error) {
kmurudi marked this conversation as resolved.
Show resolved Hide resolved
// Check if the MTPNC CRD exists for the pod, if not, return error
mtpnc := v1alpha1.MultitenantPodNetworkConfig{}
mtpncNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
if err := k.Cli.Get(ctx, mtpncNamespacedName, &mtpnc); err != nil {
return nil, errors.Wrapf(err, "failed to get pod's mtpnc from cache")
}

// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
if !mtpnc.IsReady() {
return nil, errMTPNCNotReady
}
logger.Printf("[SWIFTv2Middleware] mtpnc for pod %s is : %+v", podInfo.Name(), mtpnc)

var podIPInfos []cns.PodIpInfo

if len(mtpnc.Status.InterfaceInfos) == 0 {
// Use fields from mtpnc.Status if InterfaceInfos is empty
ip, prefixSize, err := utils.ParseIPAndPrefix(mtpnc.Status.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}

podIPInfos = append(podIPInfos, cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
},
MacAddress: mtpnc.Status.MacAddress,
NICType: cns.DelegatedVMNIC,
SkipDefaultRoutes: false,
// InterfaceName is empty for DelegatedVMNIC
})
} else {
// Use InterfaceInfos if not empty
podIPInfos = make([]cns.PodIpInfo, len(mtpnc.Status.InterfaceInfos))
for i, interfaceInfo := range mtpnc.Status.InterfaceInfos {
// Parse MTPNC primaryIP to get the IP address and prefix length
ip, prefixSize, err := utils.ParseIPAndPrefix(interfaceInfo.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}

var nicType cns.NICType
switch {
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && !interfaceInfo.AccelnetEnabled:
nicType = cns.DelegatedVMNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && interfaceInfo.AccelnetEnabled:
nicType = cns.NodeNetworkInterfaceAccelnetFrontendNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeInfiniBandNIC:
nicType = cns.NodeNetworkInterfaceBackendNIC
default:
nicType = cns.DelegatedVMNIC
}

podIPInfos[i] = cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
},
MacAddress: interfaceInfo.MacAddress,
NICType: nicType,
SkipDefaultRoutes: false,
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: interfaceInfo.GatewayIP,
},
}
}
}

return podIPInfos, nil
}
83 changes: 83 additions & 0 deletions cns/middlewares/k8sSwiftV2_linux.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,99 @@
package middlewares

import (
"context"
"fmt"
"net/netip"

"github.com/Azure/azure-container-networking/cns"
"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"
k8stypes "k8s.io/apimachinery/pkg/types"
)

// getIPConfig returns the pod's SWIFT V2 IP configuration.
func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodInfo) ([]cns.PodIpInfo, error) {
// Check if the MTPNC CRD exists for the pod, if not, return error
mtpnc := v1alpha1.MultitenantPodNetworkConfig{}
mtpncNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
if err := k.Cli.Get(ctx, mtpncNamespacedName, &mtpnc); err != nil {
return nil, errors.Wrapf(err, "failed to get pod's mtpnc from cache")
}

// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
if !mtpnc.IsReady() {
return nil, errMTPNCNotReady
}
logger.Printf("[SWIFTv2Middleware] mtpnc for pod %s is : %+v", podInfo.Name(), mtpnc)

var podIPInfos []cns.PodIpInfo

if len(mtpnc.Status.InterfaceInfos) == 0 {
// Use fields from mtpnc.Status if InterfaceInfos is empty
ip, prefixSize, err := utils.ParseIPAndPrefix(mtpnc.Status.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}

podIPInfos = append(podIPInfos, cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
},
MacAddress: mtpnc.Status.MacAddress,
NICType: cns.DelegatedVMNIC,
SkipDefaultRoutes: false,
// InterfaceName is empty for DelegatedVMNIC
})
} else {
// Use InterfaceInfos if not empty
podIPInfos = make([]cns.PodIpInfo, len(mtpnc.Status.InterfaceInfos))
for i, interfaceInfo := range mtpnc.Status.InterfaceInfos {
// Parse MTPNC primaryIP to get the IP address and prefix length
ip, prefixSize, err := utils.ParseIPAndPrefix(interfaceInfo.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}

var nicType cns.NICType
switch {
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && !interfaceInfo.AccelnetEnabled:
nicType = cns.DelegatedVMNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && interfaceInfo.AccelnetEnabled:
nicType = cns.NodeNetworkInterfaceAccelnetFrontendNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeInfiniBandNIC:
nicType = cns.NodeNetworkInterfaceBackendNIC
default:
nicType = cns.DelegatedVMNIC
}

podIPInfos[i] = cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
},
MacAddress: interfaceInfo.MacAddress,
NICType: nicType,
SkipDefaultRoutes: false,
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: interfaceInfo.GatewayIP,
},
}
}
}

return podIPInfos, nil
}

// setRoutes sets the routes for podIPInfo used in SWIFT V2 scenario.
func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
logger.Printf("[SWIFTv2Middleware] set routes for pod with nic type : %s", podIPInfo.NICType)
Expand Down
100 changes: 100 additions & 0 deletions cns/middlewares/k8sSwiftV2_windows.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,110 @@
package middlewares

import (
"context"

"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"
k8stypes "k8s.io/apimachinery/pkg/types"
)

// getIPConfig returns the pod's SWIFT V2 IP configuration.
func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodInfo) ([]cns.PodIpInfo, error) {
// Check if the MTPNC CRD exists for the pod, if not, return error
mtpnc := v1alpha1.MultitenantPodNetworkConfig{}
mtpncNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
if err := k.Cli.Get(ctx, mtpncNamespacedName, &mtpnc); err != nil {
return nil, errors.Wrapf(err, "failed to get pod's mtpnc from cache")
}

// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
if !mtpnc.IsReady() {
return nil, errMTPNCNotReady
}
logger.Printf("[SWIFTv2Middleware] mtpnc for pod %s is : %+v", podInfo.Name(), mtpnc)

var podIPInfos []cns.PodIpInfo

if len(mtpnc.Status.InterfaceInfos) == 0 {
// Use fields from mtpnc.Status if InterfaceInfos is empty
ip, prefixSize, err := utils.ParseIPAndPrefix(mtpnc.Status.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}

podIPInfos = append(podIPInfos, cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(prefixSize),
},
MacAddress: mtpnc.Status.MacAddress,
NICType: cns.DelegatedVMNIC,
SkipDefaultRoutes: false,
// InterfaceName is empty for DelegatedVMNIC
})
} else {
// Use InterfaceInfos if not empty
podIPInfos = make([]cns.PodIpInfo, len(mtpnc.Status.InterfaceInfos))
for i, interfaceInfo := range mtpnc.Status.InterfaceInfos {
// Parse MTPNC primaryIP to get the IP address and prefix length
ip, prefixSize, err := utils.ParseIPAndPrefix(interfaceInfo.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc primary IP and prefix")
}
if prefixSize != prefixLength {
return nil, errors.Wrapf(errInvalidMTPNCPrefixLength, "mtpnc primaryIP prefix length is %d", prefixSize)
}
// Parse MTPNC SubnetAddressSpace to get the subnet prefix length
subnet, subnetPrefix, err := utils.ParseIPAndPrefix(interfaceInfo.PrimaryIP)
if err != nil {
return nil, errors.Wrap(err, "failed to parse mtpnc subnetAddressSpace prefix")
}

var nicType cns.NICType
switch {
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && !interfaceInfo.AccelnetEnabled:
nicType = cns.DelegatedVMNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC && interfaceInfo.AccelnetEnabled:
nicType = cns.NodeNetworkInterfaceAccelnetFrontendNIC
case interfaceInfo.DeviceType == v1alpha1.DeviceTypeInfiniBandNIC:
nicType = cns.NodeNetworkInterfaceBackendNIC
default:
nicType = cns.DelegatedVMNIC
}

podIPInfos[i] = cns.PodIpInfo{
PodIPConfig: cns.IPSubnet{
IPAddress: ip,
PrefixLength: uint8(subnetPrefix),
},
MacAddress: interfaceInfo.MacAddress,
NICType: nicType,
SkipDefaultRoutes: false,
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: interfaceInfo.GatewayIP,
PrimaryIP: ip,
Subnet: interfaceInfo.SubnetAddressSpace,
},
NetworkContainerPrimaryIPConfig: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: subnet,
PrefixLength: uint8(subnetPrefix),
},
GatewayIPAddress: interfaceInfo.GatewayIP,
},
}
}
}

return podIPInfos, nil
}

// for AKS L1VH, do not set default route on infraNIC to avoid customer pod reaching all infra vnet services
// default route is set for secondary interface NIC(i.e,delegatedNIC)
func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
Expand Down
4 changes: 4 additions & 0 deletions cns/middlewares/mock/mockClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,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 @@ -69,6 +70,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 @@ -77,6 +79,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 @@ -154,6 +157,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
Loading