Using different MAC for a pair of redundant routers In the past, we use same MAC address therefore once MASTER is down, the packet to the same MAC would go to BACKUP ASAP.
But now we also have arping after BACKUP become MASTER, which should update the ARP cache of public gateway router quickly. Though it would be a little delay(likely less than 1 second), it's still fine for different MAC. And it would solve some cache issue for same mac on vSwitch different ports. Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/9f257aa6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/9f257aa6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/9f257aa6 Branch: refs/heads/api_refactoring Commit: 9f257aa60b62f24193bba3f7c902e7779632e01e Parents: 7926e66 Author: Sheng Yang <[email protected]> Authored: Fri Nov 9 18:59:32 2012 -0800 Committer: Sheng Yang <[email protected]> Committed: Fri Dec 21 15:21:53 2012 -0800 ---------------------------------------------------------------------- .../router/VirtualNetworkApplianceManagerImpl.java | 26 ++++++++++++--- server/src/com/cloud/vm/dao/NicDao.java | 2 + server/src/com/cloud/vm/dao/NicDaoImpl.java | 8 ++++ 3 files changed, 31 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9f257aa6/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 208bd9b..a91eda6 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1409,15 +1409,31 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian offeringId = _offering.getId(); } - PublicIp sourceNatIp = null; - if (publicNetwork) { - sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); - } - // 3) deploy virtual router(s) int count = routerCount - routers.size(); DeploymentPlan plan = planAndRouters.first(); for (int i = 0; i < count; i++) { + PublicIp sourceNatIp = null; + if (publicNetwork) { + int failCount = 0; + // Generate different MAC for VR + while (sourceNatIp == null) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + NicVO nic = _nicDao.findByMacAddress(sourceNatIp.getMacAddress()); + // We got duplicate MAC here, so regenerate the mac + if (nic != null) { + s_logger.debug("Failed to find a different mac for redundant router. Try again. The current mac is " + sourceNatIp.getMacAddress()); + sourceNatIp = null; + failCount ++; + } + //Prevent infinite loop + if (failCount > 3) { + s_logger.error("Failed to find a different mac for redundant router! Abort operation!"); + throw new InsufficientAddressCapacityException("Failed to find a different mac for redundant router", null, offeringId); + } + } + } + List<Pair<NetworkVO, NicProfile>> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, new Pair<Boolean, PublicIp>(publicNetwork, sourceNatIp)); //don't start the router as we are holding the network lock that needs to be released at the end of router allocation http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9f257aa6/server/src/com/cloud/vm/dao/NicDao.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 762048b..af3c7b3 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -58,4 +58,6 @@ public interface NicDao extends GenericDao<NicVO, Long> { NicVO findByNetworkIdInstanceIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri); NicVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, long instanceId, String ip4Address); + + NicVO findByMacAddress(String macAddress); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/9f257aa6/server/src/com/cloud/vm/dao/NicDaoImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 3cd7fa6..00da2eb 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -50,6 +50,7 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao { AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ); AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().isDefaultNic(), Op.EQ); AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); + AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.EQ); AllFieldsSearch.done(); IpSearch = createSearchBuilder(String.class); @@ -199,4 +200,11 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao { sc.setParameters("address", ip4Address); return findOneBy(sc); } + + @Override + public NicVO findByMacAddress(String macAddress) { + SearchCriteria<NicVO> sc = AllFieldsSearch.create(); + sc.setParameters("macAddress", macAddress); + return findOneBy(sc); + } }
