diff --git a/cni/network/network_windows.go b/cni/network/network_windows.go index 24aad4add7..aa9f04b348 100644 --- a/cni/network/network_windows.go +++ b/cni/network/network_windows.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net" + "net/netip" "os" "path/filepath" "strconv" @@ -154,9 +155,14 @@ func (plugin *NetPlugin) getNetworkName(netNs string, ipamAddResult *IPAMAddResu // This will happen during ADD call if ipamAddResult != nil && ipamAddResult.ncResponse != nil { // networkName will look like ~ azure-vlan1-172-28-1-0_24 - subnet := ipamAddResult.ipv4Result.IPs[0].Address - networkName := strings.Replace(subnet.String(), ".", "-", -1) - networkName = strings.Replace(networkName, "/", "_", -1) + ipAddrNet := ipamAddResult.ipv4Result.IPs[0].Address + prefix, err := netip.ParsePrefix(ipAddrNet.String()) + if err != nil { + log.Printf("Error parsing %s network CIDR: %v.", ipAddrNet.String(), err) + return "", errors.Wrapf(err, "cns returned invalid CIDR %s", ipAddrNet.String()) + } + networkName := strings.ReplaceAll(prefix.Masked().String(), ".", "-") + networkName = strings.ReplaceAll(networkName, "/", "_") networkName = fmt.Sprintf("%s-vlan%v-%v", nwCfg.Name, ipamAddResult.ncResponse.MultiTenancyInfo.ID, networkName) return networkName, nil } diff --git a/cni/network/network_windows_test.go b/cni/network/network_windows_test.go index 7cb7f7424e..c622a9811b 100644 --- a/cni/network/network_windows_test.go +++ b/cni/network/network_windows_test.go @@ -301,3 +301,201 @@ func TestDSRPolciy(t *testing.T) { }) } } + +func TestGetNetworkNameFromCNS(t *testing.T) { + plugin, _ := cni.NewPlugin("name", "0.3.0") + tests := []struct { + name string + plugin *NetPlugin + netNs string + nwCfg *cni.NetworkConfig + ipamAddResult *IPAMAddResult + want string + wantErr bool + }{ + { + name: "Get Network Name from CNS with correct CIDR", + plugin: &NetPlugin{ + Plugin: plugin, + nm: network.NewMockNetworkmanager(), + ipamInvoker: NewMockIpamInvoker(false, false, false), + report: &telemetry.CNIReport{}, + tb: &telemetry.TelemetryBuffer{}, + }, + netNs: "net", + nwCfg: &cni.NetworkConfig{ + CNIVersion: "0.3.0", + Name: "azure", + MultiTenancy: true, + }, + ipamAddResult: &IPAMAddResult{ + ncResponse: &cns.GetNetworkContainerResponse{ + MultiTenancyInfo: cns.MultiTenancyInfo{ + ID: 1, + }, + }, + ipv4Result: &cniTypesCurr.Result{ + IPs: []*cniTypesCurr.IPConfig{ + { + Address: net.IPNet{ + IP: net.ParseIP("10.240.0.5"), + Mask: net.CIDRMask(24, 32), + }, + }, + }, + }, + }, + want: "azure-vlan1-10-240-0-0_24", + wantErr: false, + }, + { + name: "Get Network Name from CNS with malformed CIDR #1", + plugin: &NetPlugin{ + Plugin: plugin, + nm: network.NewMockNetworkmanager(), + ipamInvoker: NewMockIpamInvoker(false, false, false), + report: &telemetry.CNIReport{}, + tb: &telemetry.TelemetryBuffer{}, + }, + netNs: "net", + nwCfg: &cni.NetworkConfig{ + CNIVersion: "0.3.0", + Name: "azure", + MultiTenancy: true, + }, + ipamAddResult: &IPAMAddResult{ + ncResponse: &cns.GetNetworkContainerResponse{ + MultiTenancyInfo: cns.MultiTenancyInfo{ + ID: 1, + }, + }, + ipv4Result: &cniTypesCurr.Result{ + IPs: []*cniTypesCurr.IPConfig{ + { + Address: net.IPNet{ + IP: net.ParseIP(""), + Mask: net.CIDRMask(24, 32), + }, + }, + }, + }, + }, + want: "", + wantErr: true, + }, + { + name: "Get Network Name from CNS with malformed CIDR #2", + plugin: &NetPlugin{ + Plugin: plugin, + nm: network.NewMockNetworkmanager(), + ipamInvoker: NewMockIpamInvoker(false, false, false), + report: &telemetry.CNIReport{}, + tb: &telemetry.TelemetryBuffer{}, + }, + netNs: "net", + nwCfg: &cni.NetworkConfig{ + CNIVersion: "0.3.0", + Name: "azure", + MultiTenancy: true, + }, + ipamAddResult: &IPAMAddResult{ + ncResponse: &cns.GetNetworkContainerResponse{ + MultiTenancyInfo: cns.MultiTenancyInfo{ + ID: 1, + }, + }, + ipv4Result: &cniTypesCurr.Result{ + IPs: []*cniTypesCurr.IPConfig{ + { + Address: net.IPNet{ + IP: net.ParseIP("10.0.00.6"), + Mask: net.CIDRMask(24, 32), + }, + }, + }, + }, + }, + want: "", + wantErr: true, + }, + { + name: "Get Network Name from CNS without NetNS", + plugin: &NetPlugin{ + Plugin: plugin, + nm: network.NewMockNetworkmanager(), + ipamInvoker: NewMockIpamInvoker(false, false, false), + report: &telemetry.CNIReport{}, + tb: &telemetry.TelemetryBuffer{}, + }, + netNs: "", + nwCfg: &cni.NetworkConfig{ + CNIVersion: "0.3.0", + Name: "azure", + MultiTenancy: true, + }, + ipamAddResult: &IPAMAddResult{ + ncResponse: &cns.GetNetworkContainerResponse{ + MultiTenancyInfo: cns.MultiTenancyInfo{ + ID: 1, + }, + }, + ipv4Result: &cniTypesCurr.Result{ + IPs: []*cniTypesCurr.IPConfig{ + { + Address: net.IPNet{ + IP: net.ParseIP("10.0.0.6"), + Mask: net.CIDRMask(24, 32), + }, + }, + }, + }, + }, + want: "", + wantErr: true, + }, + { + name: "Get Network Name from CNS without multitenancy", + plugin: &NetPlugin{ + Plugin: plugin, + nm: network.NewMockNetworkmanager(), + ipamInvoker: NewMockIpamInvoker(false, false, false), + report: &telemetry.CNIReport{}, + tb: &telemetry.TelemetryBuffer{}, + }, + netNs: "azure", + nwCfg: &cni.NetworkConfig{ + CNIVersion: "0.3.0", + Name: "azure", + MultiTenancy: false, + }, + ipamAddResult: &IPAMAddResult{ + ncResponse: &cns.GetNetworkContainerResponse{}, + ipv4Result: &cniTypesCurr.Result{ + IPs: []*cniTypesCurr.IPConfig{ + { + Address: net.IPNet{ + IP: net.ParseIP("10.0.0.6"), + Mask: net.CIDRMask(24, 32), + }, + }, + }, + }, + }, + want: "azure", + wantErr: false, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + networkName, err := tt.plugin.getNetworkName(tt.netNs, tt.ipamAddResult, tt.nwCfg) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.want, networkName) + } + }) + } +}