@Override public NicProfile allocate( Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { if (_networkModel.networkIsConfiguredForExternalNetworking( config.getDataCenterId(), config.getId()) && nic != null && nic.getRequestedIpv4() != null) { throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + nic); } NicProfile profile = super.allocate(config, nic, vm); boolean _isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key())); if (_isEnabled) { return null; } if (_networkModel.networkIsConfiguredForExternalNetworking( config.getDataCenterId(), config.getId())) { profile.setStrategy(ReservationStrategy.Start); /* We won't clear IP address, because router may set gateway as it IP, and it would be updated properly later */ // profile.setIp4Address(null); profile.setGateway(null); profile.setNetmask(null); } return profile; }
@Override public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { _name = name; _isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key())); if (_isEnabled) { _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS")); _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup")); _listener = new OvsTunnelListener(_tunnelDao, _hostDao); _agentMgr.registerForHostEvents(_listener, true, true, true); } return true; }
@Override public void reserve( NicProfile nic, Network config, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? "; boolean _isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key())); if (_isEnabled) { return; } DataCenter dc = _dcDao.findById(config.getDataCenterId()); if (_networkModel.networkIsConfiguredForExternalNetworking( config.getDataCenterId(), config.getId())) { nic.setBroadcastUri(config.getBroadcastUri()); nic.setIsolationUri(config.getBroadcastUri()); nic.setDns1(dc.getDns1()); nic.setDns2(dc.getDns2()); nic.setNetmask(NetUtils.cidr2Netmask(config.getCidr())); long cidrAddress = NetUtils.ip2Long(config.getCidr().split("/")[0]); int cidrSize = getGloballyConfiguredCidrSize(); nic.setGateway(config.getGateway()); if (nic.getIp4Address() == null) { String guestIp = _networkMgr.acquireGuestIpAddress(config, null); if (guestIp == null) { throw new InsufficientVirtualNetworkCapcityException( "Unable to acquire guest IP address for network " + config, DataCenter.class, dc.getId()); } nic.setIp4Address(guestIp); } else { long ipMask = NetUtils.ip2Long(nic.getIp4Address()) & ~(0xffffffffffffffffl << (32 - cidrSize)); nic.setIp4Address(NetUtils.long2Ip(cidrAddress | ipMask)); } } else { super.reserve(nic, config, vm, dest, context); } }
@Override public boolean release( NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String reservationId) { if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) { return true; } NetworkVO network = _networkDao.findById(nic.getNetworkId()); if (network != null && _networkModel.networkIsConfiguredForExternalNetworking( network.getDataCenterId(), network.getId())) { return true; } else { return super.release(nic, vm, reservationId); } }
@Override public Network design( NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) { return null; } NetworkVO config = (NetworkVO) super.design(offering, plan, userSpecified, owner); if (config == null) { return null; } else if (_networkModel.networkIsConfiguredForExternalNetworking( plan.getDataCenterId(), config.getId())) { /* In order to revert userSpecified network setup */ config.setState(State.Allocated); } return config; }
@Override @DB public void deallocate( Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) { super.deallocate(config, nic, vm); if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) { return; } if (_networkModel.networkIsConfiguredForExternalNetworking( config.getDataCenterId(), config.getId())) { nic.setIp4Address(null); nic.setGateway(null); nic.setNetmask(null); nic.setBroadcastUri(null); nic.setIsolationUri(null); } }
@Override public Network implement( Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { assert (config.getState() == State.Implementing) : "Why are we implementing " + config; if (Boolean.parseBoolean(_configDao.getValue(Config.OvsTunnelNetwork.key()))) { return null; } if (!_networkModel.networkIsConfiguredForExternalNetworking( config.getDataCenterId(), config.getId())) { return super.implement(config, offering, dest, context); } DataCenter zone = dest.getDataCenter(); NetworkVO implemented = new NetworkVO( config.getTrafficType(), config.getMode(), config.getBroadcastDomainType(), config.getNetworkOfferingId(), State.Allocated, config.getDataCenterId(), config.getPhysicalNetworkId()); // Get a vlan tag int vlanTag; if (config.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet( zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), context.getReservationId()); try { vlanTag = Integer.parseInt(vnet); } catch (NumberFormatException e) { throw new CloudRuntimeException( "Obtained an invalid guest vlan tag. Exception: " + e.getMessage()); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanTag)); ActionEventUtils.onCompletedActionEvent( UserContext.current().getCallerUserId(), config.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + config.getId(), 0); } else { vlanTag = Integer.parseInt(config.getBroadcastUri().getHost()); implemented.setBroadcastUri(config.getBroadcastUri()); } // Determine the new gateway and CIDR String[] oldCidr = config.getCidr().split("/"); String oldCidrAddress = oldCidr[0]; int cidrSize = Integer.parseInt(oldCidr[1]); long newCidrAddress = (NetUtils.ip2Long(oldCidrAddress)); // if the implementing network is for vpc, no need to generate newcidr, use the cidr that came // from super cidr if (config.getVpcId() != null) { implemented.setGateway(config.getGateway()); implemented.setCidr(config.getCidr()); implemented.setState(State.Implemented); } else { // Determine the offset from the lowest vlan tag int offset = getVlanOffset(config.getPhysicalNetworkId(), vlanTag); cidrSize = getGloballyConfiguredCidrSize(); // If the offset has more bits than there is room for, return null long bitsInOffset = 32 - Integer.numberOfLeadingZeros(offset); if (bitsInOffset > (cidrSize - 8)) { throw new CloudRuntimeException( "The offset " + offset + " needs " + bitsInOffset + " bits, but only have " + (cidrSize - 8) + " bits to work with."); } newCidrAddress = (NetUtils.ip2Long(oldCidrAddress) & 0xff000000) | (offset << (32 - cidrSize)); implemented.setGateway(NetUtils.long2Ip(newCidrAddress + 1)); implemented.setCidr(NetUtils.long2Ip(newCidrAddress) + "/" + cidrSize); implemented.setState(State.Implemented); } // Mask the Ipv4 address of all nics that use this network with the new guest VLAN offset List<NicVO> nicsInNetwork = _nicDao.listByNetworkId(config.getId()); for (NicVO nic : nicsInNetwork) { if (nic.getIp4Address() != null) { long ipMask = getIpMask(nic.getIp4Address(), cidrSize); nic.setIp4Address(NetUtils.long2Ip(newCidrAddress | ipMask)); _nicDao.persist(nic); } } // Mask the destination address of all port forwarding rules in this network with the new guest // VLAN offset List<PortForwardingRuleVO> pfRulesInNetwork = _pfRulesDao.listByNetwork(config.getId()); for (PortForwardingRuleVO pfRule : pfRulesInNetwork) { if (pfRule.getDestinationIpAddress() != null) { long ipMask = getIpMask(pfRule.getDestinationIpAddress().addr(), cidrSize); String maskedDestinationIpAddress = NetUtils.long2Ip(newCidrAddress | ipMask); pfRule.setDestinationIpAddress(new Ip(maskedDestinationIpAddress)); _pfRulesDao.update(pfRule.getId(), pfRule); } } return implemented; }