diff --git a/cni/azure-windows.conflist b/cni/azure-windows.conflist index 395d1ec4f5..201871e68b 100644 --- a/cni/azure-windows.conflist +++ b/cni/azure-windows.conflist @@ -1,6 +1,7 @@ { "cniVersion": "0.3.0", "name": "azure", + "adapterName" : "", "plugins": [ { "type": "azure-vnet", diff --git a/cni/netconfig.go b/cni/netconfig.go index 7c6610d405..1f4042c34d 100644 --- a/cni/netconfig.go +++ b/cni/netconfig.go @@ -47,6 +47,7 @@ type NetworkConfig struct { Type string `json:"type,omitempty"` Mode string `json:"mode,omitempty"` Master string `json:"master,omitempty"` + AdapterName string `json:"adapterName,omitempty"` Bridge string `json:"bridge,omitempty"` LogLevel string `json:"logLevel,omitempty"` LogTarget string `json:"logTarget,omitempty"` diff --git a/cni/network/network.go b/cni/network/network.go index 6c0fffdf72..c3dc2ab090 100644 --- a/cni/network/network.go +++ b/cni/network/network.go @@ -489,6 +489,7 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) error { Id: networkId, Mode: nwCfg.Mode, MasterIfName: masterIfName, + AdapterName: nwCfg.AdapterName, Subnets: []network.SubnetInfo{ { Family: platform.AfINET, diff --git a/network/network.go b/network/network.go index 783cdfca5c..50c4da7784 100644 --- a/network/network.go +++ b/network/network.go @@ -57,6 +57,7 @@ type network struct { // NetworkInfo contains read-only information about a container network. type NetworkInfo struct { MasterIfName string + AdapterName string Id string Mode string Subnets []SubnetInfo diff --git a/network/network_windows.go b/network/network_windows.go index 2ccfffc326..c003032f12 100644 --- a/network/network_windows.go +++ b/network/network_windows.go @@ -63,10 +63,22 @@ func (nm *networkManager) newNetworkImplHnsV1(nwInfo *NetworkInfo, extIf *extern ) networkAdapterName := extIf.Name + + // Pass adapter name here if it is not empty, this is cause if we don't tell HNS which adapter to use + // it will just pick one randomly, this is a problem for customers that have multiple adapters + if nwInfo.AdapterName != "" { + networkAdapterName = nwInfo.AdapterName + } + // FixMe: Find a better way to check if a nic that is selected is not part of a vSwitch + // per hns team, the hns calls fails if passed a vSwitch interface if strings.HasPrefix(networkAdapterName, vEthernetAdapterPrefix) { + log.Printf("[net] vSwitch detected, setting adapter name to empty") networkAdapterName = "" } + + log.Printf("[net] Adapter name used with HNS is : %s", networkAdapterName) + // Initialize HNS network. hnsNetwork := &hcsshim.HNSNetwork{ Name: nwInfo.Id, @@ -216,8 +228,20 @@ func (nm *networkManager) configureHcnNetwork(nwInfo *NetworkInfo, extIf *extern // Set hcn network adaptor name policy // FixMe: Find a better way to check if a nic that is selected is not part of a vSwitch - if !strings.HasPrefix(extIf.Name, vEthernetAdapterPrefix) { - netAdapterNamePolicy, err := policy.GetHcnNetAdapterPolicy(extIf.Name) + // per hns team, the hns calls fails if passed a vSwitch interface + // Pass adapter name here if it is not empty, this is cause if we don't tell HNS which adapter to use + // it will just pick one randomly, this is a problem for customers that have multiple adapters + if nwInfo.AdapterName != "" || !strings.HasPrefix(extIf.Name, vEthernetAdapterPrefix) { + var adapterName string + if nwInfo.AdapterName != "" { + adapterName = nwInfo.AdapterName + } else { + adapterName = extIf.Name + } + + log.Printf("[net] Adapter name used with HNS is : %s", adapterName) + + netAdapterNamePolicy, err := policy.GetHcnNetAdapterPolicy(adapterName) if err != nil { log.Printf("[net] Failed to serialize network adapter policy due to error: %v", err) return nil, err