@@ -3,8 +3,6 @@ package middlewares
33import (
44 "context"
55 "fmt"
6- "net/netip"
7-
86 "github.com/Azure/azure-container-networking/cns"
97 "github.com/Azure/azure-container-networking/cns/configuration"
108 "github.com/Azure/azure-container-networking/cns/logger"
@@ -39,17 +37,17 @@ var _ cns.IPConfigsHandlerMiddleware = (*K8sSWIFTv2Middleware)(nil)
3937
4038// IPConfigsRequestHandlerWrapper is the middleware function for handling SWIFT v2 IP configs requests for AKS-SWIFT. This function wrapped the default SWIFT request
4139// and release IP configs handlers.
42- func (m * K8sSWIFTv2Middleware ) IPConfigsRequestHandlerWrapper (defaultHandler , failureHandler cns.IPConfigsHandlerFunc ) cns.IPConfigsHandlerFunc {
40+ func (k * K8sSWIFTv2Middleware ) IPConfigsRequestHandlerWrapper (defaultHandler , failureHandler cns.IPConfigsHandlerFunc ) cns.IPConfigsHandlerFunc {
4341 return func (ctx context.Context , req cns.IPConfigsRequest ) (* cns.IPConfigsResponse , error ) {
44- podInfo , respCode , message := m .validateIPConfigsRequest (ctx , & req )
42+ podInfo , respCode , message := k .validateIPConfigsRequest (ctx , & req )
4543
4644 if respCode != types .Success {
4745 return & cns.IPConfigsResponse {
4846 Response : cns.Response {
4947 ReturnCode : respCode ,
5048 Message : message ,
5149 },
52- }, errors .New ("failed to validate ip configs request" )
50+ }, errors .New ("failed to validate IP configs request" )
5351 }
5452 ipConfigsResp , err := defaultHandler (ctx , req )
5553 // If the pod is not v2, return the response from the handler
@@ -69,7 +67,7 @@ func (m *K8sSWIFTv2Middleware) IPConfigsRequestHandlerWrapper(defaultHandler, fa
6967 if err != nil {
7068 return ipConfigsResp , err
7169 }
72- SWIFTv2PodIPInfo , err := m .getIPConfig (ctx , podInfo )
70+ SWIFTv2PodIPInfos , err := k .getIPConfig (ctx , podInfo )
7371 if err != nil {
7472 return & cns.IPConfigsResponse {
7573 Response : cns.Response {
@@ -79,11 +77,11 @@ func (m *K8sSWIFTv2Middleware) IPConfigsRequestHandlerWrapper(defaultHandler, fa
7977 PodIPInfo : []cns.PodIpInfo {},
8078 }, errors .Wrapf (err , "failed to get SWIFTv2 IP config : %v" , req )
8179 }
82- ipConfigsResp .PodIPInfo = append (ipConfigsResp .PodIPInfo , SWIFTv2PodIPInfo )
80+ ipConfigsResp .PodIPInfo = append (ipConfigsResp .PodIPInfo , SWIFTv2PodIPInfos ... )
8381 // Set routes for the pod
8482 for i := range ipConfigsResp .PodIPInfo {
8583 ipInfo := & ipConfigsResp .PodIPInfo [i ]
86- err = m .setRoutes (ipInfo )
84+ err = k .setRoutes (ipInfo )
8785 if err != nil {
8886 return & cns.IPConfigsResponse {
8987 Response : cns.Response {
@@ -100,7 +98,7 @@ func (m *K8sSWIFTv2Middleware) IPConfigsRequestHandlerWrapper(defaultHandler, fa
10098
10199// validateIPConfigsRequest validates if pod is multitenant by checking the pod labels, used in SWIFT V2 AKS scenario.
102100// nolint
103- func (m * K8sSWIFTv2Middleware ) validateIPConfigsRequest (ctx context.Context , req * cns.IPConfigsRequest ) (podInfo cns.PodInfo , respCode types.ResponseCode , message string ) {
101+ func (k * K8sSWIFTv2Middleware ) validateIPConfigsRequest (ctx context.Context , req * cns.IPConfigsRequest ) (podInfo cns.PodInfo , respCode types.ResponseCode , message string ) {
104102 // Retrieve the pod from the cluster
105103 podInfo , err := cns .UnmarshalPodInfo (req .OrchestratorContext )
106104 if err != nil {
@@ -110,7 +108,7 @@ func (m *K8sSWIFTv2Middleware) validateIPConfigsRequest(ctx context.Context, req
110108 logger .Printf ("[SWIFTv2Middleware] validate ipconfigs request for pod %s" , podInfo .Name ())
111109 podNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
112110 pod := v1.Pod {}
113- if err := m .Cli .Get (ctx , podNamespacedName , & pod ); err != nil {
111+ if err := k .Cli .Get (ctx , podNamespacedName , & pod ); err != nil {
114112 errBuf := errors .Wrapf (err , "failed to get pod %+v" , podNamespacedName )
115113 return nil , types .UnexpectedError , errBuf .Error ()
116114 }
@@ -121,11 +119,11 @@ func (m *K8sSWIFTv2Middleware) validateIPConfigsRequest(ctx context.Context, req
121119 // Check if the MTPNC CRD exists for the pod, if not, return error
122120 mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
123121 mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
124- if err := m .Cli .Get (ctx , mtpncNamespacedName , & mtpnc ); err != nil {
122+ if err := k .Cli .Get (ctx , mtpncNamespacedName , & mtpnc ); err != nil {
125123 return nil , types .UnexpectedError , fmt .Errorf ("failed to get pod's mtpnc from cache : %w" , err ).Error ()
126124 }
127125 // Check if the MTPNC CRD is ready. If one of the fields is empty, return error
128- if mtpnc .Status . PrimaryIP == "" || mtpnc . Status . MacAddress == "" || mtpnc . Status . NCID == "" || mtpnc . Status . GatewayIP == "" {
126+ if ! mtpnc .IsReady () {
129127 return nil , types .UnexpectedError , errMTPNCNotReady .Error ()
130128 }
131129 }
@@ -135,150 +133,78 @@ func (m *K8sSWIFTv2Middleware) validateIPConfigsRequest(ctx context.Context, req
135133}
136134
137135// getIPConfig returns the pod's SWIFT V2 IP configuration.
138- func (m * K8sSWIFTv2Middleware ) getIPConfig (ctx context.Context , podInfo cns.PodInfo ) (cns.PodIpInfo , error ) {
136+ func (k * K8sSWIFTv2Middleware ) getIPConfig (ctx context.Context , podInfo cns.PodInfo ) ([] cns.PodIpInfo , error ) {
139137 // Check if the MTPNC CRD exists for the pod, if not, return error
140138 mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
141139 mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
142- if err := m .Cli .Get (ctx , mtpncNamespacedName , & mtpnc ); err != nil {
143- return cns. PodIpInfo {} , errors .Wrapf (err , "failed to get pod's mtpnc from cache" )
140+ if err := k .Cli .Get (ctx , mtpncNamespacedName , & mtpnc ); err != nil {
141+ return nil , errors .Wrapf (err , "failed to get pod's mtpnc from cache" )
144142 }
145143
146144 // Check if the MTPNC CRD is ready. If one of the fields is empty, return error
147- if mtpnc .Status . PrimaryIP == "" || mtpnc . Status . MacAddress == "" || mtpnc . Status . NCID == "" || mtpnc . Status . GatewayIP == "" {
148- return cns. PodIpInfo {} , errMTPNCNotReady
145+ if ! mtpnc .IsReady () {
146+ return nil , errMTPNCNotReady
149147 }
150148 logger .Printf ("[SWIFTv2Middleware] mtpnc for pod %s is : %+v" , podInfo .Name (), mtpnc )
151149
152- // Parse MTPNC primaryIP to get the IP address and prefix length
153- p , err := netip .ParsePrefix (mtpnc .Status .PrimaryIP )
154- if err != nil {
155- return cns.PodIpInfo {}, errors .Wrapf (err , "failed to parse mtpnc primaryIP %s" , mtpnc .Status .PrimaryIP )
156- }
157- // Get the IP address and prefix length
158- ip := p .Addr ()
159- prefixSize := p .Bits ()
160- if prefixSize != prefixLength {
161- return cns.PodIpInfo {}, errors .Wrapf (errInvalidMTPNCPrefixLength , "mtpnc primaryIP prefix length is %d" , prefixSize )
162- }
163- podIPInfo := cns.PodIpInfo {
164- PodIPConfig : cns.IPSubnet {
165- IPAddress : ip .String (),
166- PrefixLength : uint8 (prefixSize ),
167- },
168- MacAddress : mtpnc .Status .MacAddress ,
169- NICType : cns .DelegatedVMNIC ,
170- SkipDefaultRoutes : false ,
171- // InterfaceName is empty for DelegatedVMNIC
172- }
173-
174- return podIPInfo , nil
175- }
176-
177- // setRoutes sets the routes for podIPInfo used in SWIFT V2 scenario.
178- func (m * K8sSWIFTv2Middleware ) setRoutes (podIPInfo * cns.PodIpInfo ) error {
179- logger .Printf ("[SWIFTv2Middleware] set routes for pod with nic type : %s" , podIPInfo .NICType )
180- podIPInfo .Routes = []cns.Route {}
181- switch podIPInfo .NICType {
182- case cns .DelegatedVMNIC :
183- virtualGWRoute := cns.Route {
184- IPAddress : fmt .Sprintf ("%s/%d" , virtualGW , prefixLength ),
185- }
186- // default route via SWIFT v2 interface
187- route := cns.Route {
188- IPAddress : "0.0.0.0/0" ,
189- GatewayIPAddress : virtualGW ,
190- }
191- podIPInfo .Routes = []cns.Route {virtualGWRoute , route }
192- case cns .InfraNIC :
193- // Get and parse infraVNETCIDRs from env
194- infraVNETCIDRs , err := configuration .InfraVNETCIDRs ()
195- if err != nil {
196- return errors .Wrapf (err , "failed to get infraVNETCIDRs from env" )
197- }
198- infraVNETCIDRsv4 , infraVNETCIDRsv6 , err := utils .ParseCIDRs (infraVNETCIDRs )
199- if err != nil {
200- return errors .Wrapf (err , "failed to parse infraVNETCIDRs" )
201- }
202-
203- // Get and parse podCIDRs from env
204- podCIDRs , err := configuration .PodCIDRs ()
205- if err != nil {
206- return errors .Wrapf (err , "failed to get podCIDRs from env" )
207- }
208- podCIDRsV4 , podCIDRv6 , err := utils .ParseCIDRs (podCIDRs )
209- if err != nil {
210- return errors .Wrapf (err , "failed to parse podCIDRs" )
211- }
150+ var podIPInfos []cns.PodIpInfo
212151
213- // Get and parse serviceCIDRs from env
214- serviceCIDRs , err := configuration .ServiceCIDRs ()
152+ if len (mtpnc .Status .InterfaceInfos ) == 0 {
153+ // Use fields from mtpnc.Status if InterfaceInfos is empty
154+ ip , prefixSize , err := utils .ParseIPAndPrefix (mtpnc .Status .PrimaryIP )
215155 if err != nil {
216- return errors .Wrapf (err , "failed to get serviceCIDRs from env" )
217- }
218- serviceCIDRsV4 , serviceCIDRsV6 , err := utils .ParseCIDRs (serviceCIDRs )
219- if err != nil {
220- return errors .Wrapf (err , "failed to parse serviceCIDRs" )
221- }
222- // Check if the podIPInfo is IPv4 or IPv6
223- ip , err := netip .ParseAddr (podIPInfo .PodIPConfig .IPAddress )
224- if err != nil {
225- return errors .Wrapf (err , "failed to parse podIPConfig IP address %s" , podIPInfo .PodIPConfig .IPAddress )
226- }
227- if ip .Is4 () {
228- // routes for IPv4 podCIDR traffic
229- for _ , podCIDRv4 := range podCIDRsV4 {
230- podCIDRv4Route := cns.Route {
231- IPAddress : podCIDRv4 ,
232- GatewayIPAddress : overlayGatewayv4 ,
233- }
234- podIPInfo .Routes = append (podIPInfo .Routes , podCIDRv4Route )
235- }
236- // route for IPv4 serviceCIDR traffic
237- for _ , serviceCIDRv4 := range serviceCIDRsV4 {
238- serviceCIDRv4Route := cns.Route {
239- IPAddress : serviceCIDRv4 ,
240- GatewayIPAddress : overlayGatewayv4 ,
241- }
242- podIPInfo .Routes = append (podIPInfo .Routes , serviceCIDRv4Route )
243- }
244- // route for IPv4 infraVNETCIDR traffic
245- for _ , infraVNETCIDRv4 := range infraVNETCIDRsv4 {
246- infraVNETCIDRv4Route := cns.Route {
247- IPAddress : infraVNETCIDRv4 ,
248- GatewayIPAddress : overlayGatewayv4 ,
249- }
250- podIPInfo .Routes = append (podIPInfo .Routes , infraVNETCIDRv4Route )
156+ return nil , errors .Wrap (err , "failed to parse mtpnc primary IP and prefix" )
157+ }
158+ if prefixSize != prefixLength {
159+ return nil , errors .Wrapf (errInvalidMTPNCPrefixLength , "mtpnc primaryIP prefix length is %d" , prefixSize )
160+ }
161+
162+ podIPInfos = append (podIPInfos , cns.PodIpInfo {
163+ PodIPConfig : cns.IPSubnet {
164+ IPAddress : ip ,
165+ PrefixLength : uint8 (prefixSize ),
166+ },
167+ MacAddress : mtpnc .Status .MacAddress ,
168+ NICType : cns .DelegatedVMNIC ,
169+ SkipDefaultRoutes : false ,
170+ // InterfaceName is empty for DelegatedVMNIC
171+ })
172+ } else {
173+ // Use InterfaceInfos if not empty
174+ podIPInfos = make ([]cns.PodIpInfo , len (mtpnc .Status .InterfaceInfos ))
175+ for i , interfaceInfo := range mtpnc .Status .InterfaceInfos {
176+ // Parse MTPNC primaryIP to get the IP address and prefix length
177+ ip , prefixSize , err := utils .ParseIPAndPrefix (interfaceInfo .PrimaryIP )
178+ if err != nil {
179+ return nil , errors .Wrap (err , "failed to parse mtpnc primary IP and prefix" )
251180 }
252- } else {
253- // routes for IPv6 podCIDR traffic
254- for _ , podCIDRv6 := range podCIDRv6 {
255- podCIDRv6Route := cns.Route {
256- IPAddress : podCIDRv6 ,
257- GatewayIPAddress : overlayGatewayV6 ,
258- }
259- podIPInfo .Routes = append (podIPInfo .Routes , podCIDRv6Route )
181+ if prefixSize != prefixLength {
182+ return nil , errors .Wrapf (errInvalidMTPNCPrefixLength , "mtpnc primaryIP prefix length is %d" , prefixSize )
260183 }
261- // route for IPv6 serviceCIDR traffic
262- for _ , serviceCIDRv6 := range serviceCIDRsV6 {
263- serviceCIDRv6Route := cns.Route {
264- IPAddress : serviceCIDRv6 ,
265- GatewayIPAddress : overlayGatewayV6 ,
266- }
267- podIPInfo .Routes = append (podIPInfo .Routes , serviceCIDRv6Route )
184+
185+ var nicType cns.NICType
186+ switch {
187+ case interfaceInfo .DeviceType == v1alpha1 .DeviceTypeVnetNIC && ! interfaceInfo .AccelnetEnabled :
188+ nicType = cns .DelegatedVMNIC
189+ case interfaceInfo .DeviceType == v1alpha1 .DeviceTypeVnetNIC && interfaceInfo .AccelnetEnabled :
190+ nicType = cns .NodeNetworkInterfaceAccelnetFrontendNIC
191+ case interfaceInfo .DeviceType == v1alpha1 .DeviceTypeInfiniBandNIC :
192+ nicType = cns .NodeNetworkInterfaceBackendNIC
193+ default :
194+ nicType = cns .DelegatedVMNIC
268195 }
269- // route for IPv6 infraVNETCIDR traffic
270- for _ , infraVNETCIDRv6 := range infraVNETCIDRsv6 {
271- infraVNETCIDRv6Route := cns.Route {
272- IPAddress : infraVNETCIDRv6 ,
273- GatewayIPAddress : overlayGatewayV6 ,
274- }
275- podIPInfo .Routes = append (podIPInfo .Routes , infraVNETCIDRv6Route )
196+
197+ podIPInfos [i ] = cns.PodIpInfo {
198+ PodIPConfig : cns.IPSubnet {
199+ IPAddress : ip ,
200+ PrefixLength : uint8 (prefixSize ),
201+ },
202+ MacAddress : interfaceInfo .MacAddress ,
203+ NICType : nicType ,
204+ SkipDefaultRoutes : false ,
276205 }
277206 }
278- podIPInfo .SkipDefaultRoutes = true
279- case cns .BackendNIC :
280- default :
281- return errInvalidSWIFTv2NICType
282207 }
283- return nil
208+
209+ return podIPInfos , nil
284210}
0 commit comments