Skip to content

Commit 962b7f3

Browse files
paulyufan2rejain789rejain456
authored
fix: route issues on Swiftv2 Windows (#3375)
* updated CNS for adding default deny acl's * added infra nic change * added unit tests * resolved pr comments * updating to fix github checks * added logging lines * removing unnecessary logging lines * removed cni circular dependency * switch from having consts to making them inline * cns changes based on update to network container contrac * fixed spelling * updated unit test * updated test * reverted a comment * updated name of function * changed policy type * added a new line * resolving pr comments * resolving pr comments * re-added back * updated creating acl code to make it more modularized * fixed golint errors * fixed golint * added tests * fixed spelling * moved an assertion line * reformated creating acl's * refactored code per pr comments * fixed lint * moved GetEndpointPolicy so that it is only run on init * updated code * updated error message * updated getEndpointPolicy placement * updated comment * fixed golint issues * refactored * fixed comments * updated return inline * updated unit test returns * corrected the go lint of file * fix swiftv2 route issues * ut fix * fix linter issue * fix comments * fix comments * fix comments * enhance comment * rename func names --------- Signed-off-by: Paul Yu <[email protected]> Co-authored-by: rejain456 <[email protected]> Co-authored-by: rejain456 <[email protected]>
1 parent 40b6c44 commit 962b7f3

File tree

5 files changed

+179
-55
lines changed

5 files changed

+179
-55
lines changed

cns/middlewares/k8sSwiftV2.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,51 @@ func (k *K8sSWIFTv2Middleware) UpdateIPConfigRequest(mtpnc v1alpha1.MultitenantP
226226

227227
return types.Success, ""
228228
}
229+
230+
func (k *K8sSWIFTv2Middleware) AddRoutes(cidrs []string, gatewayIP string) []cns.Route {
231+
routes := make([]cns.Route, len(cidrs))
232+
for i, cidr := range cidrs {
233+
routes[i] = cns.Route{
234+
IPAddress: cidr,
235+
GatewayIPAddress: gatewayIP,
236+
}
237+
}
238+
return routes
239+
}
240+
241+
// Both Linux and Windows CNS gets infravnet and service CIDRs from configuration env
242+
// GetInfravnetAndServiceCidrs() returns v4CIDRs(infravnet and service cidrs) as first []string and v6CIDRs(infravnet and service) as second []string
243+
func (k *K8sSWIFTv2Middleware) GetInfravnetAndServiceCidrs() ([]string, []string, error) { //nolint
244+
v4Cidrs := []string{}
245+
v6Cidrs := []string{}
246+
247+
// Get and parse infraVNETCIDRs from env
248+
infraVNETCIDRs, err := configuration.InfraVNETCIDRs()
249+
if err != nil {
250+
return nil, nil, errors.Wrapf(err, "failed to get infraVNETCIDRs from env")
251+
}
252+
infraVNETCIDRsv4, infraVNETCIDRsv6, err := utils.ParseCIDRs(infraVNETCIDRs)
253+
if err != nil {
254+
return nil, nil, errors.Wrapf(err, "failed to parse infraVNETCIDRs")
255+
}
256+
257+
// Add infravnet CIDRs to v4 and v6 IPs
258+
v4Cidrs = append(v4Cidrs, infraVNETCIDRsv4...)
259+
v6Cidrs = append(v6Cidrs, infraVNETCIDRsv6...)
260+
261+
// Get and parse serviceCIDRs from env
262+
serviceCIDRs, err := configuration.ServiceCIDRs()
263+
if err != nil {
264+
return nil, nil, errors.Wrapf(err, "failed to get serviceCIDRs from env")
265+
}
266+
serviceCIDRsV4, serviceCIDRsV6, err := utils.ParseCIDRs(serviceCIDRs)
267+
if err != nil {
268+
return nil, nil, errors.Wrapf(err, "failed to parse serviceCIDRs")
269+
}
270+
271+
// Add service CIDRs to v4 and v6 IPs
272+
v4Cidrs = append(v4Cidrs, serviceCIDRsV4...)
273+
v6Cidrs = append(v6Cidrs, serviceCIDRsV6...)
274+
275+
return v4Cidrs, v6Cidrs, nil
276+
}

cns/middlewares/k8sSwiftV2_linux.go

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -32,50 +32,12 @@ func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
3232
routes = append(routes, virtualGWRoute, route)
3333

3434
case cns.InfraNIC:
35-
// Get and parse infraVNETCIDRs from env
36-
infraVNETCIDRs, err := configuration.InfraVNETCIDRs()
35+
// Linux CNS middleware sets the infra routes(pod, infravnet and service cidrs) to infraNIC interface for the podIPInfo used in SWIFT V2 Linux scenario
36+
infraRoutes, err := k.getInfraRoutes(podIPInfo)
3737
if err != nil {
38-
return errors.Wrapf(err, "failed to get infraVNETCIDRs from env")
39-
}
40-
infraVNETCIDRsv4, infraVNETCIDRsv6, err := utils.ParseCIDRs(infraVNETCIDRs)
41-
if err != nil {
42-
return errors.Wrapf(err, "failed to parse infraVNETCIDRs")
43-
}
44-
45-
// Get and parse podCIDRs from env
46-
podCIDRs, err := configuration.PodCIDRs()
47-
if err != nil {
48-
return errors.Wrapf(err, "failed to get podCIDRs from env")
49-
}
50-
podCIDRsV4, podCIDRv6, err := utils.ParseCIDRs(podCIDRs)
51-
if err != nil {
52-
return errors.Wrapf(err, "failed to parse podCIDRs")
53-
}
54-
55-
// Get and parse serviceCIDRs from env
56-
serviceCIDRs, err := configuration.ServiceCIDRs()
57-
if err != nil {
58-
return errors.Wrapf(err, "failed to get serviceCIDRs from env")
59-
}
60-
serviceCIDRsV4, serviceCIDRsV6, err := utils.ParseCIDRs(serviceCIDRs)
61-
if err != nil {
62-
return errors.Wrapf(err, "failed to parse serviceCIDRs")
63-
}
64-
65-
ip, err := netip.ParseAddr(podIPInfo.PodIPConfig.IPAddress)
66-
if err != nil {
67-
return errors.Wrapf(err, "failed to parse podIPConfig IP address %s", podIPInfo.PodIPConfig.IPAddress)
68-
}
69-
70-
if ip.Is4() {
71-
routes = append(routes, addRoutes(podCIDRsV4, overlayGatewayv4)...)
72-
routes = append(routes, addRoutes(serviceCIDRsV4, overlayGatewayv4)...)
73-
routes = append(routes, addRoutes(infraVNETCIDRsv4, overlayGatewayv4)...)
74-
} else {
75-
routes = append(routes, addRoutes(podCIDRv6, overlayGatewayV6)...)
76-
routes = append(routes, addRoutes(serviceCIDRsV6, overlayGatewayV6)...)
77-
routes = append(routes, addRoutes(infraVNETCIDRsv6, overlayGatewayV6)...)
38+
return errors.Wrap(err, "failed to get infra routes for infraNIC interface")
7839
}
40+
routes = infraRoutes
7941
podIPInfo.SkipDefaultRoutes = true
8042

8143
case cns.NodeNetworkInterfaceBackendNIC: //nolint:exhaustive // ignore exhaustive types check
@@ -88,22 +50,68 @@ func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
8850
return nil
8951
}
9052

91-
func addRoutes(cidrs []string, gatewayIP string) []cns.Route {
92-
routes := make([]cns.Route, len(cidrs))
93-
for i, cidr := range cidrs {
94-
routes[i] = cns.Route{
95-
IPAddress: cidr,
96-
GatewayIPAddress: gatewayIP,
97-
}
53+
// Linux CNS gets pod CIDRs from configuration env
54+
// Containerd reassigns the IP to the adapter and kernel configures the pod cidr route by default on Windows VM
55+
// Hence the windows swiftv2 scenario does not require pod cidr
56+
// GetPodCidrs() will return v4PodCidrs as first []string and v6PodCidrs as second []string
57+
func (k *K8sSWIFTv2Middleware) GetPodCidrs() ([]string, []string, error) { //nolint
58+
v4PodCidrs := []string{}
59+
v6PodCidrs := []string{}
60+
61+
// Get and parse podCIDRs from env
62+
podCIDRs, err := configuration.PodCIDRs()
63+
if err != nil {
64+
return nil, nil, errors.Wrapf(err, "failed to get podCIDRs from env")
65+
}
66+
podCIDRsV4, podCIDRv6, err := utils.ParseCIDRs(podCIDRs)
67+
if err != nil {
68+
return nil, nil, errors.Wrapf(err, "failed to parse podCIDRs")
69+
}
70+
71+
v4PodCidrs = append(v4PodCidrs, podCIDRsV4...)
72+
v6PodCidrs = append(v6PodCidrs, podCIDRv6...)
73+
74+
return v4PodCidrs, v6PodCidrs, nil
75+
}
76+
77+
// getInfraRoutes() returns the infra routes including infravnet/pod/service cidrs for the podIPInfo used in SWIFT V2 Linux scenario
78+
// Linux uses 169.254.1.1 as the default ipv4 gateway and fe80::1234:5678:9abc as the default ipv6 gateway
79+
func (k *K8sSWIFTv2Middleware) getInfraRoutes(podIPInfo *cns.PodIpInfo) ([]cns.Route, error) {
80+
var routes []cns.Route
81+
82+
ip, err := netip.ParseAddr(podIPInfo.PodIPConfig.IPAddress)
83+
if err != nil {
84+
return nil, errors.Wrapf(err, "failed to parse podIPConfig IP address %s", podIPInfo.PodIPConfig.IPAddress)
9885
}
99-
return routes
86+
87+
v4IPs, v6IPs, err := k.GetInfravnetAndServiceCidrs()
88+
if err != nil {
89+
return nil, errors.Wrap(err, "failed to get infravnet and service CIDRs")
90+
}
91+
92+
v4PodIPs, v6PodIPs, err := k.GetPodCidrs()
93+
if err != nil {
94+
return nil, errors.Wrap(err, "failed to get pod CIDRs")
95+
}
96+
97+
v4IPs = append(v4IPs, v4PodIPs...)
98+
v6IPs = append(v6IPs, v6PodIPs...)
99+
100+
if ip.Is4() {
101+
routes = append(routes, k.AddRoutes(v4IPs, overlayGatewayv4)...)
102+
} else {
103+
routes = append(routes, k.AddRoutes(v6IPs, overlayGatewayV6)...)
104+
}
105+
106+
return routes, nil
100107
}
101108

102109
// assignSubnetPrefixLengthFields is a no-op for linux swiftv2 as the default prefix-length is sufficient
103110
func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(_ *cns.PodIpInfo, _ v1alpha1.InterfaceInfo, _ string) error {
104111
return nil
105112
}
106113

114+
// add default route is done on setRoutes() for Linux swiftv2
107115
func (k *K8sSWIFTv2Middleware) addDefaultRoute(*cns.PodIpInfo, string) {}
108116

109117
// IPConfigsRequestHandlerWrapper is the middleware function for handling SWIFT v2 IP configs requests for AKS-SWIFT. This function wrapped the default SWIFT request

cns/middlewares/k8sSwiftV2_linux_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/Azure/azure-container-networking/cns/middlewares/mock"
1212
"github.com/Azure/azure-container-networking/cns/types"
1313
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
14+
"github.com/google/go-cmp/cmp"
1415
"gotest.tools/v3/assert"
1516
)
1617

@@ -342,10 +343,10 @@ func TestSetRoutesSuccess(t *testing.T) {
342343
} else {
343344
assert.Equal(t, ipInfo.SkipDefaultRoutes, false)
344345
}
345-
346346
}
347+
347348
for i := range podIPInfo {
348-
assert.DeepEqual(t, podIPInfo[i].Routes, desiredPodIPInfo[i].Routes)
349+
cmp.Equal(podIPInfo[i].Routes, desiredPodIPInfo[i].Routes)
349350
}
350351
}
351352

@@ -378,9 +379,10 @@ func TestSetRoutesFailure(t *testing.T) {
378379
}
379380

380381
func TestAddRoutes(t *testing.T) {
382+
middleware := K8sSWIFTv2Middleware{Cli: mock.NewClient()}
381383
cidrs := []string{"10.0.0.0/24", "20.0.0.0/24"}
382384
gatewayIP := "192.168.1.1"
383-
routes := addRoutes(cidrs, gatewayIP)
385+
routes := middleware.AddRoutes(cidrs, gatewayIP)
384386
expectedRoutes := []cns.Route{
385387
{
386388
IPAddress: "10.0.0.0/24",

cns/middlewares/k8sSwiftV2_windows.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"net/netip"
78

89
"github.com/Azure/azure-container-networking/cns"
910
"github.com/Azure/azure-container-networking/cns/logger"
@@ -18,6 +19,10 @@ var defaultDenyEgressPolicy policy.Policy = mustGetEndpointPolicy(cns.DirectionT
1819

1920
var defaultDenyIngressPolicy policy.Policy = mustGetEndpointPolicy(cns.DirectionTypeIn)
2021

22+
const (
23+
defaultGateway = "0.0.0.0"
24+
)
25+
2126
// for AKS L1VH, do not set default route on infraNIC to avoid customer pod reaching all infra vnet services
2227
// default route is set for secondary interface NIC(i.e,delegatedNIC)
2328
func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
@@ -27,10 +32,16 @@ func (k *K8sSWIFTv2Middleware) setRoutes(podIPInfo *cns.PodIpInfo) error {
2732
// TODO: Remove this once HNS fix is ready
2833
route := cns.Route{
2934
IPAddress: "0.0.0.0/0",
30-
GatewayIPAddress: "0.0.0.0",
35+
GatewayIPAddress: defaultGateway,
3136
}
3237
podIPInfo.Routes = append(podIPInfo.Routes, route)
3338

39+
// Windows CNS middleware sets the infra routes(infravnet and service cidrs) to infraNIC interface for the podIPInfo used in SWIFT V2 Windows scenario
40+
infraRoutes, err := k.getInfraRoutes(podIPInfo)
41+
if err != nil {
42+
return errors.Wrap(err, "failed to set routes for infraNIC interface")
43+
}
44+
podIPInfo.Routes = append(podIPInfo.Routes, infraRoutes...)
3445
podIPInfo.SkipDefaultRoutes = true
3546
}
3647
return nil
@@ -208,3 +219,27 @@ func GetDefaultDenyBool(mtpnc v1alpha1.MultitenantPodNetworkConfig) bool {
208219
// returns the value of DefaultDenyACL from mtpnc
209220
return mtpnc.Status.DefaultDenyACL
210221
}
222+
223+
// getInfraRoutes() returns the infra routes including infravnet/ and service cidrs for the podIPInfo used in SWIFT V2 Windows scenario
224+
// Windows uses default route 0.0.0.0 as the gateway IP for containerd to configure;
225+
// For example, containerd would set route like: ip route 10.0.0.0/16 via 0.0.0.0 dev eth0
226+
func (k *K8sSWIFTv2Middleware) getInfraRoutes(podIPInfo *cns.PodIpInfo) ([]cns.Route, error) {
227+
var routes []cns.Route
228+
229+
ip, err := netip.ParseAddr(podIPInfo.PodIPConfig.IPAddress)
230+
if err != nil {
231+
return nil, errors.Wrapf(err, "failed to parse podIPConfig IP address %s", podIPInfo.PodIPConfig.IPAddress)
232+
}
233+
234+
// TODO: add ipv6 when supported
235+
v4IPs, _, err := k.GetInfravnetAndServiceCidrs()
236+
if err != nil {
237+
return nil, errors.Wrap(err, "failed to get infravnet and service CIDRs")
238+
}
239+
240+
if ip.Is4() {
241+
routes = append(routes, k.AddRoutes(v4IPs, defaultGateway)...)
242+
}
243+
244+
return routes, nil
245+
}

cns/middlewares/k8sSwiftV2_windows_test.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
"github.com/Azure/azure-container-networking/cns"
10+
"github.com/Azure/azure-container-networking/cns/configuration"
1011
"github.com/Azure/azure-container-networking/cns/middlewares/mock"
1112
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
1213
"github.com/Azure/azure-container-networking/network/policy"
@@ -17,11 +18,14 @@ import (
1718

1819
func TestSetRoutesSuccess(t *testing.T) {
1920
middleware := K8sSWIFTv2Middleware{Cli: mock.NewClient()}
21+
t.Setenv(configuration.EnvServiceCIDRs, "10.0.0.0/16")
22+
t.Setenv(configuration.EnvInfraVNETCIDRs, "10.240.0.10/16")
23+
t.Setenv(configuration.EnvPodCIDRs, "10.1.0.10/24") // make sure windows swiftv2 does not set pod cidr route
2024

2125
podIPInfo := []cns.PodIpInfo{
2226
{
2327
PodIPConfig: cns.IPSubnet{
24-
IPAddress: "10.0.1.10",
28+
IPAddress: "10.0.1.100",
2529
PrefixLength: 32,
2630
},
2731
NICType: cns.InfraNIC,
@@ -35,6 +39,30 @@ func TestSetRoutesSuccess(t *testing.T) {
3539
MacAddress: "12:34:56:78:9a:bc",
3640
},
3741
}
42+
43+
desiredPodIPInfo := []cns.PodIpInfo{
44+
{
45+
PodIPConfig: cns.IPSubnet{
46+
IPAddress: "10.0.1.100",
47+
PrefixLength: 32,
48+
},
49+
NICType: cns.InfraNIC,
50+
Routes: []cns.Route{
51+
{
52+
IPAddress: "10.0.0.0/16",
53+
GatewayIPAddress: "0.0.0.0",
54+
},
55+
{
56+
IPAddress: "10.240.0.10/16",
57+
GatewayIPAddress: "0.0.0.0",
58+
},
59+
{
60+
IPAddress: "0.0.0.0/0",
61+
GatewayIPAddress: "0.0.0.0",
62+
},
63+
},
64+
},
65+
}
3866
for i := range podIPInfo {
3967
ipInfo := &podIPInfo[i]
4068
err := middleware.setRoutes(ipInfo)
@@ -45,6 +73,9 @@ func TestSetRoutesSuccess(t *testing.T) {
4573
assert.Equal(t, ipInfo.SkipDefaultRoutes, false)
4674
}
4775
}
76+
77+
// check if the routes are set as expected
78+
reflect.DeepEqual(podIPInfo[0].Routes, desiredPodIPInfo[0].Routes)
4879
}
4980

5081
func TestAssignSubnetPrefixSuccess(t *testing.T) {

0 commit comments

Comments
 (0)