@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; }
@Override @ActionEvent( eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true) public boolean revokeFirewallRulesForVm(long vmId) { boolean success = true; UserVmVO vm = _vmDao.findByIdIncludingRemoved(vmId); if (vm == null) { return false; } List<PortForwardingRuleVO> pfRules = _pfRulesDao.listByVm(vmId); List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(vm.getId()); List<FirewallRuleVO> firewallRules = new ArrayList<FirewallRuleVO>(); // Make a list of firewall rules to reprogram for (PortForwardingRuleVO pfRule : pfRules) { FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(pfRule.getId()); if (relatedRule != null) { firewallRules.add(relatedRule); } } for (FirewallRuleVO staticNatRule : staticNatRules) { FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(staticNatRule.getId()); if (relatedRule != null) { firewallRules.add(relatedRule); } } Set<Long> ipsToReprogram = new HashSet<Long>(); if (firewallRules.isEmpty()) { s_logger.debug("No firewall rules are found for vm id=" + vmId); return true; } else { s_logger.debug("Found " + firewallRules.size() + " to cleanup for vm id=" + vmId); } for (FirewallRuleVO rule : firewallRules) { // Mark firewall rules as Revoked, but don't revoke it yet (apply=false) revokeFirewallRule( rule.getId(), false, _accountMgr.getSystemAccount(), Account.ACCOUNT_ID_SYSTEM); ipsToReprogram.add(rule.getSourceIpAddressId()); } // apply rules for all ip addresses for (Long ipId : ipsToReprogram) { s_logger.debug( "Applying firewall rules for ip address id=" + ipId + " as a part of vm expunge"); try { success = success && applyIngressFirewallRules(ipId, _accountMgr.getSystemAccount()); } catch (ResourceUnavailableException ex) { s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId); success = false; } } return success; }