From bfdb88f10e404ebc9863352a143959edfef85174 Mon Sep 17 00:00:00 2001 From: Sateesh Chodapuneedi Date: Fri, 25 May 2012 18:03:45 +0530 Subject: [PATCH] CS-15073 Nexus vSwitch: Source NAT is being programmed on the wrong nic on the Virtual Router Reviewed-by: Devdeep --- .../vmware/resource/VmwareResource.java | 45 ++++++++++--------- .../hypervisor/vmware/mo/DatacenterMO.java | 20 +++++++++ .../vmware/mo/VirtualMachineMO.java | 45 ++++++++++++++----- 3 files changed, 79 insertions(+), 31 deletions(-) diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 6f0ed5c9b2d..1de54a99ab1 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -811,27 +811,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // TODO : probably need to set traffic shaping Pair networkInfo = null; - if(!_nexusVSwitch) { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", - vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); + if (!_nexusVSwitch) { + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); + } else { + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout); } - else { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", - vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout); - } - + int nicIndex = allocPublicNicIndex(vmMo); - + try { - VirtualDevice[] nicDevices = vmMo.getNicDevices(); - - VirtualEthernetCard device = (VirtualEthernetCard)nicDevices[nicIndex]; - - VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); - nicBacking.setDeviceName(networkInfo.second()); - nicBacking.setNetwork(networkInfo.first()); - device.setBacking(nicBacking); - + VirtualDevice[] nicDevices = vmMo.getNicDevices(); + + VirtualEthernetCard device = (VirtualEthernetCard) nicDevices[nicIndex]; + + if (!_nexusVSwitch) { + VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); + nicBacking.setDeviceName(networkInfo.second()); + nicBacking.setNetwork(networkInfo.first()); + device.setBacking(nicBacking); + } else { + HostMO hostMo = vmMo.getRunningHost(); + DatacenterMO dataCenterMo = new DatacenterMO(hostMo.getContext(), hostMo.getHyperHostDatacenter()); + device.setBacking(dataCenterMo.getDvPortBackingInfo(networkInfo)); + } + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); @@ -4050,9 +4055,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (mgr.getPrivateVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); if (mgr.getPublicVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) - _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); if (mgr.getGuestVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) - _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); } } catch (Exception e) { diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index c753fb793dc..0d31d2a281c 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -20,6 +20,7 @@ import com.cloud.utils.Pair; import com.vmware.apputils.vim25.ServiceUtil; import com.vmware.vim25.CustomFieldStringValue; import com.vmware.vim25.DVPortgroupConfigInfo; +import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.ObjectContent; @@ -28,6 +29,9 @@ import com.vmware.vim25.PropertyFilterSpec; import com.vmware.vim25.PropertySpec; import com.vmware.vim25.SelectionSpec; import com.vmware.vim25.TraversalSpec; +import com.vmware.vim25.VirtualDeviceBackingInfo; +import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; +import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; public class DatacenterMO extends BaseMO { @@ -444,5 +448,21 @@ public class DatacenterMO extends BaseMO { public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception { assert (dvSwitchMor != null); return (String) _context.getServiceUtil().getDynamicProperty(dvSwitchMor, "uuid"); + } + + public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair networkInfo) + throws Exception { + assert (networkInfo != null); + assert (networkInfo.first() != null && networkInfo.first().getType().equalsIgnoreCase("DistributedVirtualPortgroup")); + final VirtualEthernetCardDistributedVirtualPortBackingInfo dvPortBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo(); + final DistributedVirtualSwitchPortConnection dvPortConnection = new DistributedVirtualSwitchPortConnection(); + ManagedObjectReference dvsMor = getDvSwitchMor(networkInfo.first()); + String dvSwitchUuid = getDvSwitchUuid(dvsMor); + dvPortConnection.setSwitchUuid(dvSwitchUuid); + dvPortConnection.setPortgroupKey(networkInfo.first().get_value()); + dvPortBacking.setPort(dvPortConnection); + System.out.println("Plugging NIC device into network " + networkInfo.second() + " backed by dvSwitch: " + + dvSwitchUuid); + return dvPortBacking; } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 3319e928db6..be4ca7bb3d7 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -38,6 +38,7 @@ import com.cloud.utils.script.Script; import com.google.gson.Gson; import com.vmware.vim25.ArrayOfManagedObjectReference; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.GuestInfo; import com.vmware.vim25.HttpNfcLeaseDeviceUrl; @@ -72,6 +73,7 @@ import com.vmware.vim25.VirtualDiskSparseVer1BackingInfo; import com.vmware.vim25.VirtualDiskSparseVer2BackingInfo; import com.vmware.vim25.VirtualDiskType; import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; import com.vmware.vim25.VirtualIDEController; import com.vmware.vim25.VirtualLsiLogicController; import com.vmware.vim25.VirtualMachineCloneSpec; @@ -2002,17 +2004,38 @@ public class VirtualMachineMO extends BaseMO { return 1; return 0; } - }); - - int index = 0; - for(VirtualDevice nic : nics) { - if(((VirtualEthernetCard)nic).getDeviceInfo().getSummary().startsWith(networkNamePrefix)) - return new Pair(new Integer(index), nic); - index++; - } - return new Pair(new Integer(-1), null); - } - + }); + + int index = 0; + String attachedNetworkSummary; + String dvPortGroupName; + for (VirtualDevice nic : nics) { + attachedNetworkSummary = ((VirtualEthernetCard) nic).getDeviceInfo().getSummary(); + if (attachedNetworkSummary.startsWith(networkNamePrefix)) { + return new Pair(new Integer(index), nic); + } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary")) { + dvPortGroupName = getDvPortGroupName((VirtualEthernetCard) nic); + if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) { + s_logger.debug("Found a dvPortGroup already associated with public NIC."); + return new Pair(new Integer(index), nic); + } + } + index++; + } + return new Pair(new Integer(-1), null); + } + + public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception { + VirtualEthernetCardDistributedVirtualPortBackingInfo dvpBackingInfo = + (VirtualEthernetCardDistributedVirtualPortBackingInfo) ((VirtualEthernetCard) nic).getBacking(); + DistributedVirtualSwitchPortConnection dvsPort = (DistributedVirtualSwitchPortConnection) dvpBackingInfo.getPort(); + String dvPortGroupKey = dvsPort.getPortgroupKey(); + ManagedObjectReference dvPortGroupMor = new ManagedObjectReference(); + dvPortGroupMor.set_value(dvPortGroupKey); + dvPortGroupMor.setType("DistributedVirtualPortgroup"); + return (String) _context.getServiceUtil().getDynamicProperty(dvPortGroupMor, "name"); + } + public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { assert(deviceClasses != null);