Skip to content

Commit 5f47ac9

Browse files
sureshanapartiLocharla, Sandeep
authored andcommitted
MAC address assignment improvements (apache#12349)
1 parent 91bc65e commit 5f47ac9

File tree

19 files changed

+114
-29
lines changed

19 files changed

+114
-29
lines changed

api/src/main/java/com/cloud/network/NetworkModel.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public interface NetworkModel {
125125
*/
126126
String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
127127

128+
String getUniqueMacAddress(long macAddress, long networkId, long datacenterId) throws InsufficientAddressCapacityException;
129+
130+
boolean isMACUnique(String mac, long networkId);
131+
128132
PublicIpAddress getPublicIpAddress(long ipAddressId);
129133

130134
List<? extends Vlan> listPodVlans(long podId);
@@ -364,4 +368,8 @@ List<String[]> generateVmData(String userData, String userDataDetails, String se
364368

365369
boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter zone, List<Long> networkIds,
366370
List<Long> securityGroupsIds);
371+
372+
default long getMacIdentifier(Long dataCenterId) {
373+
return 0;
374+
}
367375
}

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ protected void configureNicProfileBasedOnRequestedIp(NicProfile requestedNicProf
12831283
nicProfile.setIPv4Gateway(ipv4Gateway);
12841284
nicProfile.setIPv4Netmask(ipv4Netmask);
12851285

1286-
if (nicProfile.getMacAddress() == null) {
1286+
if (nicProfile.getMacAddress() == null || !_networkModel.isMACUnique(nicProfile.getMacAddress(), network.getId())) {
12871287
try {
12881288
String macAddress = _networkModel.getNextAvailableMacAddressInNetwork(network.getId());
12891289
nicProfile.setMacAddress(macAddress);

engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestratorTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ private void configureTestConfigureNicProfileBasedOnRequestedIpTests(NicProfile
396396
when(testOrchestrator._ipAddressDao.acquireInLockTable(Mockito.anyLong())).thenReturn(ipVoSpy);
397397
when(testOrchestrator._ipAddressDao.update(Mockito.anyLong(), Mockito.any(IPAddressVO.class))).thenReturn(true);
398398
when(testOrchestrator._ipAddressDao.releaseFromLockTable(Mockito.anyLong())).thenReturn(true);
399+
when(testOrchestrator._networkModel.isMACUnique(Mockito.anyString(), Mockito.anyLong())).thenReturn(true);
399400
try {
400401
when(testOrchestrator._networkModel.getNextAvailableMacAddressInNetwork(Mockito.anyLong())).thenReturn(macAddress);
401402
} catch (InsufficientAddressCapacityException e) {

engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,8 @@ public List<NetworkVO> listByNetworkDomainsAndDomainIds(Set<String> uniqueNtwkDo
462462
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
463463
final SequenceFetcher fetch = SequenceFetcher.getInstance();
464464
long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
465-
if(zoneMacIdentifier != null && zoneMacIdentifier.intValue() != 0 ){
466-
seq = seq | _prefix << 40 | (long)zoneMacIdentifier << 32 | networkConfigId << 16 & 0x00000000ffff0000l;
465+
if (zoneMacIdentifier != null && zoneMacIdentifier != 0) {
466+
seq = seq | _prefix << 40 | (long)zoneMacIdentifier << 32 | networkConfigId << 16 & 0x00000000ffff0000L;
467467
}
468468
return NetUtils.long2Mac(seq);
469469
}

engine/schema/src/main/java/com/cloud/vm/dao/NicDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public interface NicDao extends GenericDao<NicVO, Long> {
9595

9696
List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword);
9797

98-
NicVO findByMacAddress(String macAddress);
98+
NicVO findByMacAddress(String macAddress, long networkId);
9999

100100
NicVO findByNetworkIdAndMacAddressIncludingRemoved(long networkId, String mac);
101101

engine/schema/src/main/java/com/cloud/vm/dao/NicDaoImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,10 @@ public List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword) {
420420
}
421421

422422
@Override
423-
public NicVO findByMacAddress(String macAddress) {
423+
public NicVO findByMacAddress(String macAddress, long networkId) {
424424
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
425425
sc.setParameters("macAddress", macAddress);
426+
sc.setParameters("network", networkId);
426427
return findOneBy(sc);
427428
}
428429

server/src/main/java/com/cloud/network/IpAddressManagerImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,7 +2409,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Insuff
24092409
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
24102410
nic.setFormat(AddressFormat.Ip4);
24112411
nic.setReservationId(String.valueOf(ip.getVlanTag()));
2412-
if(nic.getMacAddress() == null) {
2412+
if (nic.getMacAddress() == null) {
24132413
nic.setMacAddress(ip.getMacAddress());
24142414
}
24152415
}
@@ -2460,7 +2460,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) throws Insuff
24602460

24612461
nic.setBroadcastUri(network.getBroadcastUri());
24622462
nic.setFormat(AddressFormat.Ip4);
2463-
if(nic.getMacAddress() == null) {
2463+
if (nic.getMacAddress() == null || !_networkModel.isMACUnique(nic.getMacAddress(), network.getId())) {
24642464
nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
24652465
}
24662466
}

server/src/main/java/com/cloud/network/Ipv6AddressManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ private void setNicPropertiesFromNetwork(NicProfile nic, Network network) throws
241241
if (nic.getBroadCastUri() == null) {
242242
nic.setBroadcastUri(network.getBroadcastUri());
243243
}
244-
if (nic.getMacAddress() == null) {
244+
if (nic.getMacAddress() == null || !_networkModel.isMACUnique(nic.getMacAddress(), network.getId())) {
245245
nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
246246
}
247247
}

server/src/main/java/com/cloud/network/NetworkModelImpl.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -594,22 +594,34 @@ public List<? extends Nic> getNics(long vmId) {
594594
@Override
595595
public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
596596
NetworkVO network = _networksDao.findById(networkId);
597-
Integer zoneIdentifier = MACIdentifier.value();
598-
if (zoneIdentifier.intValue() == 0) {
599-
zoneIdentifier = Long.valueOf(network.getDataCenterId()).intValue();
597+
if (network == null) {
598+
throw new CloudRuntimeException("Could not find network with id " + networkId);
600599
}
600+
601+
Integer zoneMacIdentifier = Long.valueOf(getMacIdentifier(network.getDataCenterId())).intValue();
601602
String mac;
602603
do {
603-
mac = _networksDao.getNextAvailableMacAddress(networkId, zoneIdentifier);
604+
mac = _networksDao.getNextAvailableMacAddress(networkId, zoneMacIdentifier);
604605
if (mac == null) {
605606
throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
606607
}
607-
} while(! isMACUnique(mac));
608+
} while (!isMACUnique(mac, networkId));
608609
return mac;
609610
}
610611

611-
private boolean isMACUnique(String mac) {
612-
return (_nicDao.findByMacAddress(mac) == null);
612+
@Override
613+
public String getUniqueMacAddress(long macAddress, long networkId, long datacenterId) throws InsufficientAddressCapacityException {
614+
String macAddressStr = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(macAddress, getMacIdentifier(datacenterId)));
615+
if (!isMACUnique(macAddressStr, networkId)) {
616+
macAddressStr = getNextAvailableMacAddressInNetwork(networkId);
617+
}
618+
return macAddressStr;
619+
}
620+
621+
@Override
622+
public boolean isMACUnique(String mac, long networkId) {
623+
return (_nicDao.findByMacAddress(mac, networkId) == null);
624+
613625
}
614626

615627
@Override
@@ -2818,4 +2830,18 @@ public boolean checkSecurityGroupSupportForNetwork(Account account, DataCenter z
28182830
}
28192831
return false;
28202832
}
2833+
2834+
@Override
2835+
public long getMacIdentifier(Long dataCenterId) {
2836+
long macAddress = 0;
2837+
if (dataCenterId == null) {
2838+
macAddress = NetworkModel.MACIdentifier.value();
2839+
} else {
2840+
macAddress = NetworkModel.MACIdentifier.valueIn(dataCenterId);
2841+
if (macAddress == 0) {
2842+
macAddress = dataCenterId;
2843+
}
2844+
}
2845+
return macAddress;
2846+
}
28212847
}

server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfil
293293
allocateDirectIp(nic, network, vm, dc, nic.getRequestedIPv4(), nic.getRequestedIPv6());
294294
nic.setReservationStrategy(ReservationStrategy.Create);
295295

296-
if (nic.getMacAddress() == null) {
296+
if (nic.getMacAddress() == null || !_networkModel.isMACUnique(nic.getMacAddress(), network.getId())) {
297297
nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
298298
if (nic.getMacAddress() == null) {
299299
throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", Network.class, network.getId());

0 commit comments

Comments
 (0)