From ac052ed4f0481bbd96725f0129d165e24ceadb34 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Mar 2012 14:45:02 +0000 Subject: [PATCH] Now allocating vnets for GRE keys --- .../com/cloud/network/NetworkManagerImpl.java | 13 ++++-- .../network/guru/OvsGuestNetworkGuru.java | 16 ++++++- .../network/ovs/OvsTunnelManagerImpl.java | 45 ++++++++++--------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7578331b2cb..fb6d6bdb185 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -4823,7 +4823,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Integer newStartVnet = 0; Integer newEndVnet = 0; String[] newVnetRange = newVnetRangeString.split("-"); - + int maxVnet = 4096; + // for GRE phynets allow up to 32bits + // TODO: Not happy about this test. + // What about guru-like objects for physical networs? + if (network.getIsolationMethods().contains("GRE")) { + maxVnet = 2^32 - 1; + } if (newVnetRange.length < 2) { throw new InvalidParameterValueException("Please provide valid vnet range between 0-4096"); } @@ -4839,15 +4845,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.warn("Unable to parse vnet range:", e); throw new InvalidParameterValueException("Please provide valid vnet range between 0-4096"); } - - if (newStartVnet < 0 || newEndVnet > 4096) { + if (newStartVnet < 0 || newEndVnet > maxVnet) { throw new InvalidParameterValueException("Vnet range has to be between 0-4096"); } if (newStartVnet > newEndVnet) { throw new InvalidParameterValueException("Vnet range has to be between 0-4096 and start range should be lesser than or equal to stop range"); } - + if (physicalNetworkHasAllocatedVnets(network.getDataCenterId(), network.getId())) { String[] existingRange = network.getVnet().split("-"); int existingStartVnet = Integer.parseInt(existingRange[0]); diff --git a/server/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/server/src/com/cloud/network/guru/OvsGuestNetworkGuru.java index 222b79af37a..8babbbc9582 100644 --- a/server/src/com/cloud/network/guru/OvsGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/OvsGuestNetworkGuru.java @@ -16,8 +16,12 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; +import com.cloud.event.EventTypes; +import com.cloud.event.EventUtils; +import com.cloud.event.EventVO; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.network.Network; @@ -27,6 +31,7 @@ import com.cloud.network.ovs.OvsNetworkManager; import com.cloud.network.ovs.OvsTunnelManager; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; +import com.cloud.user.UserContext; import com.cloud.utils.component.Inject; import com.cloud.vm.Nic.ReservationStrategy; import com.cloud.vm.NicProfile; @@ -63,7 +68,16 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru { protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { - // Overriden as an empty method to avoid Vnet allocation when OVS is the network manager + if (network.getBroadcastUri() == null) { + String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); + if (vnet == null) { + throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); + } + implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vnet)); + EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); + } else { + implemented.setBroadcastUri(network.getBroadcastUri()); + } } @Override diff --git a/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java index b9f177c9336..40883ea7220 100644 --- a/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java +++ b/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java @@ -34,6 +34,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.ovs.dao.OvsTunnelNetworkDao; import com.cloud.network.ovs.dao.OvsTunnelNetworkVO; import com.cloud.network.ovs.dao.OvsTunnelDao; @@ -84,15 +85,11 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { return true; } - protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId) { + protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId, int key) { OvsTunnelNetworkVO ta = null; try { - // Use the network id as a Key - // FIXME: networkid is long, key must be integer - // This is a horrible cast, and it must be removed and replace with something better - // before committing into master - ta = new OvsTunnelNetworkVO(from, to, (int)networkId, networkId); + ta = new OvsTunnelNetworkVO(from, to, key, networkId); OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1)); if (lock == null) { s_logger.warn("Cannot lock table ovs_tunnel_account"); @@ -115,20 +112,20 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { Long from = r.getFrom(); Long to = r.getTo(); long networkId = r.getNetworkId(); - OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(from, to, networkId); - if (ta == null) { - throw new CloudRuntimeException(String.format("Unable find tunnelAccount record(from=%1$s, to=%2$s, account=%3$s", from, to, networkId)); + OvsTunnelNetworkVO tunnel = _tunnelNetworkDao.getByFromToNetwork(from, to, networkId); + if (tunnel == null) { + throw new CloudRuntimeException(String.format("Unable find tunnelNetwork record(from=%1$s, to=%2$s, account=%3$s", from, to, networkId)); } s_logger.debug("Result:" + r.getResult()); if (!r.getResult()) { - ta.setState("FAILED"); + tunnel.setState("FAILED"); s_logger.warn("Create GRE tunnel failed due to " + r.getDetails() + s); } else { - ta.setState("SUCCESS"); - ta.setPortName(r.getInPortName()); + tunnel.setState("SUCCESS"); + tunnel.setPortName(r.getInPortName()); s_logger.warn("Create GRE tunnel " + r.getDetails() + s); } - _tunnelNetworkDao.update(ta.getId(), ta); + _tunnelNetworkDao.update(tunnel.getId(), tunnel); } @DB @@ -145,6 +142,18 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { } long hostId = dest.getHost().getId(); + int key = 0; + try { + //The GRE key is actually in the host part of the URI + String keyStr = nw.getBroadcastUri().getHost(); + // The key is most certainly and int. + // So we feel quite safe in converting it into a string + key = Integer.valueOf(keyStr); + } catch (NumberFormatException e) { + s_logger.debug("Well well, how did '" + key + + "' end up in the broadcast URI for the network?"); + s_logger.warn("Unable to create GRE tunnels on host:" + hostId); + } // Find active (i.e.: not shut off) VMs with a NIC on the target network List vms = _userVmDao.listByNetworkIdAndStates(nw.getId(), State.Running, State.Starting, State.Stopping, State.Unknown, State.Migrating); @@ -157,23 +166,19 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { if (routers.size() != 0) { ins.addAll(routers); } - s_logger.debug("### Virtual Machines:" + vms.size()); - s_logger.debug("### Virtual Routers:" + routers.size()); List toHostIds = new ArrayList(); List fromHostIds = new ArrayList(); - for (VMInstanceVO v : ins) { Long rh = v.getHostId(); if (rh == null || rh.longValue() == hostId) { continue; } - //FIXME: Still using 'TunnelAccount name' - but should actually be tunnelNetwork or something like that OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), nw.getId()); // Try and create the tunnel even if a previous attempt failed if (ta == null || ta.getState().equals("FAILED")) { s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue()); if (ta == null) { - this.createTunnelRecord(hostId, rh.longValue(), nw.getId()); + this.createTunnelRecord(hostId, rh.longValue(), nw.getId(), key); } if (!toHostIds.contains(rh)) { toHostIds.add(rh); @@ -185,7 +190,7 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { if (ta == null || ta.getState().equals("FAILED")) { s_logger.debug("Attempting to create tunnel from:" + rh.longValue() + " to:" + hostId); if (ta == null) { - this.createTunnelRecord(rh.longValue(), hostId, nw.getId()); + this.createTunnelRecord(rh.longValue(), hostId, nw.getId(), key); } if (!fromHostIds.contains(rh)) { fromHostIds.add(rh); @@ -215,7 +220,7 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager { handleCreateTunnelAnswer(answers); } } catch (Exception e) { - s_logger.debug("Ovs Tunnel network created tunnel failed", e); + s_logger.warn("Ovs Tunnel network created tunnel failed", e); } }