Skip to content

Commit 7eea445

Browse files
committed
CLOUDSTACK-9723: Enable unique mac address across the zones
1 parent bb274a1 commit 7eea445

File tree

16 files changed

+86
-20
lines changed

16 files changed

+86
-20
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.cloud.vm.Nic;
3939
import com.cloud.vm.NicProfile;
4040
import com.cloud.vm.VirtualMachine;
41+
import org.apache.cloudstack.framework.config.ConfigKey;
4142

4243
/**
4344
* The NetworkModel presents a read-only view into the Network data such as L2 networks,
@@ -47,6 +48,9 @@
4748
*/
4849
public interface NetworkModel {
4950

51+
static final ConfigKey<Integer> MACIdentifier = new ConfigKey<Integer>("Advanced",Integer.class, "mac.identifier", "0",
52+
"This value will be used while generating the mac addresses for isolated and shared networks. The hexadecimal equivalent value will be present at the 2nd octet of the mac address. Default value is null which means this feature is disabled.Its scope is global.", true, ConfigKey.Scope.Global);
53+
5054
/**
5155
* Lists IP addresses that belong to VirtualNetwork VLANs
5256
*

engine/api/src/com/cloud/vm/VirtualMachineGuru.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.cloud.agent.manager.Commands;
2121
import com.cloud.deploy.DeployDestination;
2222
import com.cloud.exception.ResourceUnavailableException;
23-
2423
/**
2524
* A VirtualMachineGuru knows how to process a certain type of virtual machine.
2625
*

engine/components-api/src/com/cloud/network/addr/PublicIp.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.cloud.dc.VlanVO;
2222
import com.cloud.network.IpAddress;
23+
import com.cloud.network.NetworkModel;
2324
import com.cloud.network.PublicIpAddress;
2425
import com.cloud.network.dao.IPAddressVO;
2526
import com.cloud.utils.net.Ip;
@@ -39,7 +40,7 @@ public PublicIp(IPAddressVO addr, VlanVO vlan, long macAddress) {
3940
}
4041

4142
public static PublicIp createFromAddrAndVlan(IPAddressVO addr, VlanVO vlan) {
42-
return new PublicIp(addr, vlan, NetUtils.createSequenceBasedMacAddress(addr.getMacAddress()));
43+
return new PublicIp(addr, vlan, NetUtils.createSequenceBasedMacAddress(addr.getMacAddress(), NetworkModel.MACIdentifier.value()));
4344
}
4445

4546
@Override
@@ -249,7 +250,9 @@ public Date getCreated() {
249250
}
250251

251252
@Override
252-
public Class<?> getEntityType() {
253+
public Class<?> getEntityType()
254+
{
253255
return IpAddress.class;
254256
}
257+
255258
}

engine/schema/src/com/cloud/network/dao/NetworkDao.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
5454
*
5555
* @param networkConfigId
5656
* id
57+
* @param zoneMacIdentifier
5758
* @return mac address if there is one. null if not.
5859
*/
59-
String getNextAvailableMacAddress(long networkConfigId);
60+
String getNextAvailableMacAddress(long networkConfigId, Integer zoneMacIdentifier);
6061

6162
List<NetworkVO> listBy(long accountId, long networkId);
6263

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,15 @@ public List<NetworkVO> getNetworksForOffering(final long offeringId, final long
377377
}
378378

379379
@Override
380-
public String getNextAvailableMacAddress(final long networkConfigId) {
380+
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
381381
final SequenceFetcher fetch = SequenceFetcher.getInstance();
382-
383382
long seq = fetch.getNextSequence(Long.class, _tgMacAddress, networkConfigId);
384-
seq = seq | _prefix << 40 | _rand.nextInt(Short.MAX_VALUE) << 16 & 0x00000000ffff0000l;
383+
if(zoneMacIdentifier != null && zoneMacIdentifier.intValue() != 0 ){
384+
seq = seq | _prefix << 40 | (long)zoneMacIdentifier << 32 | networkConfigId << 16 & 0x00000000ffff0000l;
385+
}
386+
else {
387+
seq = seq | _prefix << 40 | _rand.nextInt(Short.MAX_VALUE) << 16 & 0x00000000ffff0000l;
388+
}
385389
return NetUtils.long2Mac(seq);
386390
}
387391

server/src/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ private String validateConfigurationValue(final String name, String value, final
740740
} else {
741741
type = c.getType();
742742
}
743-
743+
//no need to validate further if a
744+
//config can have null value.
744745
String errMsg = null;
745746
try {
746747
if (type.equals(Integer.class)) {
@@ -789,6 +790,20 @@ private String validateConfigurationValue(final String name, String value, final
789790
return null;
790791
}
791792

793+
if (type.equals(Integer.class) && NetworkModel.MACIdentifier.key().equalsIgnoreCase(name)) {
794+
try {
795+
final int val = Integer.parseInt(value);
796+
//The value need to be between 0 to 255 because the mac generation needs a value of 8 bit
797+
//0 value is considered as disable.
798+
if(val < 0 || val > 255){
799+
throw new InvalidParameterValueException(name+" value should be between 0 and 255. 0 value will disable this feature");
800+
}
801+
} catch (final NumberFormatException e) {
802+
s_logger.error("There was an error trying to parse the integer value for:" + name);
803+
throw new InvalidParameterValueException("There was an error trying to parse the integer value for:" + name);
804+
}
805+
}
806+
792807
if (type.equals(Integer.class) && configValuesForValidation.contains(name)) {
793808
try {
794809
final int val = Integer.parseInt(value);

server/src/com/cloud/network/Ipv6AddressManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.cloud.utils.component.Manager;
2323

2424
public interface Ipv6AddressManager extends Manager {
25+
2526
public UserIpv6Address assignDirectIp6Address(long dcId, Account owner, Long networkId, String requestedIp6) throws InsufficientAddressCapacityException;
2627

2728
public void revokeDirectIpv6Address(long networkId, String ip6Address);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public UserIpv6Address assignDirectIp6Address(long dcId, Account owner, Long net
132132
dc.setMacAddress(nextMac);
133133
_dcDao.update(dc.getId(), dc);
134134

135-
String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac));
135+
String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac,NetworkModel.MACIdentifier.value()));
136136
UserIpv6AddressVO ipVO = new UserIpv6AddressVO(ip, dcId, macAddress, ipVlan.getId());
137137
ipVO.setPhysicalNetworkId(network.getPhysicalNetworkId());
138138
ipVO.setSourceNetworkId(networkId);

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import javax.naming.ConfigurationException;
3535

3636
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
37+
import org.apache.cloudstack.framework.config.ConfigKey;
38+
import org.apache.cloudstack.framework.config.Configurable;
3739
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
3840
import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao;
3941
import org.apache.commons.codec.binary.Base64;
@@ -124,7 +126,7 @@
124126
import com.cloud.vm.dao.NicSecondaryIpDao;
125127
import com.cloud.vm.dao.VMInstanceDao;
126128

127-
public class NetworkModelImpl extends ManagerBase implements NetworkModel {
129+
public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable {
128130
static final Logger s_logger = Logger.getLogger(NetworkModelImpl.class);
129131
@Inject
130132
EntityManager _entityMgr;
@@ -561,7 +563,8 @@ public List<? extends Nic> getNics(long vmId) {
561563

562564
@Override
563565
public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
564-
String mac = _networksDao.getNextAvailableMacAddress(networkId);
566+
NetworkVO network = _networksDao.findById(networkId);
567+
String mac = _networksDao.getNextAvailableMacAddress(networkId, MACIdentifier.value());
565568
if (mac == null) {
566569
throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
567570
}
@@ -2359,4 +2362,14 @@ public List<String[]> generateVmData(String userData, String serviceOffering, St
23592362

23602363
return vmData;
23612364
}
2365+
2366+
@Override
2367+
public String getConfigComponentName() {
2368+
return NetworkModel.class.getSimpleName();
2369+
}
2370+
2371+
@Override
2372+
public ConfigKey<?>[] getConfigKeys() {
2373+
return new ConfigKey<?>[] {MACIdentifier};
2374+
}
23622375
}

server/src/com/cloud/network/guru/PodBasedNetworkGuru.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import javax.inject.Inject;
2222

23+
import com.cloud.network.NetworkModel;
2324
import org.apache.log4j.Logger;
2425

2526
import com.cloud.dc.Pod;
@@ -53,6 +54,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
5354
DataCenterDao _dcDao;
5455
@Inject
5556
StorageNetworkManager _sNwMgr;
57+
5658
Random _rand = new Random(System.currentTimeMillis());
5759

5860
private static final TrafficType[] TrafficTypes = {TrafficType.Management};
@@ -123,7 +125,7 @@ public void reserve(NicProfile nic, Network config, VirtualMachineProfile vm, De
123125
}
124126

125127
nic.setIPv4Address(ip.first());
126-
nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.second())));
128+
nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.second(), NetworkModel.MACIdentifier.value())));
127129
nic.setIPv4Gateway(pod.getGateway());
128130
nic.setFormat(AddressFormat.Ip4);
129131
String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());

0 commit comments

Comments
 (0)