private DomainRouterVO getVirtualRouter(Network network) {
    List<DomainRouterVO> routers =
        _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);

    if (routers.isEmpty()) {
      throw new CloudRuntimeException(
          String.format(
              "cannot find any running virtual router on network[id:%s, uuid:%s]",
              network.getId(), network.getUuid()));
    }

    if (routers.size() > 1) {
      throw new CloudRuntimeException(
          String.format("baremetal hasn't supported redundant router yet"));
    }

    DomainRouterVO vr = routers.get(0);
    if (!Hypervisor.HypervisorType.VMware.equals(vr.getHypervisorType())) {
      throw new CloudRuntimeException(
          String.format(
              "baremetal only support vmware virtual router, but get %s", vr.getHypervisorType()));
    }

    return vr;
  }
  @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 applyLBRules(final Network network, final List<LoadBalancingRule> rules)
      throws ResourceUnavailableException {
    boolean result = true;
    if (canHandle(network, Service.Lb)) {
      if (!canHandleLbRules(rules)) {
        return false;
      }

      final List<DomainRouterVO> routers =
          _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
      if (routers == null || routers.isEmpty()) {
        s_logger.debug(
            "Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual "
                + "router doesn't exist in the network "
                + network.getId());
        return true;
      }

      final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
      final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);

      for (final DomainRouterVO domainRouterVO : routers) {
        result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
        if (!result) {
          s_logger.debug("Failed to apply load balancing rules in network " + network.getId());
        }
      }
    }
    return result;
  }
  @Override
  public boolean removeVpcRouterFromGuestNetwork(final VirtualRouter router, final Network network)
      throws ConcurrentOperationException, ResourceUnavailableException {
    if (network.getTrafficType() != TrafficType.Guest) {
      s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
      return false;
    }

    boolean result = true;
    try {
      // Check if router is a part of the Guest network
      if (!_networkModel.isVmPartOfNetwork(router.getId(), network.getId())) {
        s_logger.debug("Router " + router + " is not a part of the Guest network " + network);
        return result;
      }

      result =
          setupVpcGuestNetwork(
              network, router, false, _networkModel.getNicProfile(router, network.getId(), null));
      if (!result) {
        s_logger.warn("Failed to destroy guest network config " + network + " on router " + router);
        return false;
      }

      result = result && _itMgr.removeVmFromNetwork(router, network, null);
    } finally {
      if (result) {
        _routerDao.removeRouterFromGuestNetwork(router.getId(), network.getId());
      }
    }

    return result;
  }
  protected boolean canHandle(final Network network, final Service service) {
    s_logger.debug(
        "Checking if OvsElement can handle service "
            + service.getName()
            + " on network "
            + network.getDisplayText());
    if (network.getBroadcastDomainType() != BroadcastDomainType.Vswitch) {
      return false;
    }

    if (!_networkModel.isProviderForNetwork(getProvider(), network.getId())) {
      s_logger.debug("OvsElement is not a provider for network " + network.getDisplayText());
      return false;
    }

    if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(
        network.getId(), service, Network.Provider.Ovs)) {
      s_logger.debug(
          "OvsElement can't provide the "
              + service.getName()
              + " service on network "
              + network.getDisplayText());
      return false;
    }

    return true;
  }
 public boolean applyACLItemsToNetwork(long networkId, List<NetworkACLItemVO> rules)
     throws ResourceUnavailableException {
   Network network = _networkDao.findById(networkId);
   boolean handled = false;
   boolean foundProvider = false;
   for (NetworkACLServiceProvider element : _networkAclElements) {
     Network.Provider provider = element.getProvider();
     boolean isAclProvider =
         _networkModel.isProviderSupportServiceInNetwork(
             network.getId(), Service.NetworkACL, provider);
     if (!isAclProvider) {
       continue;
     }
     foundProvider = true;
     s_logger.debug(
         "Applying NetworkACL for network: "
             + network.getId()
             + " with Network ACL service provider");
     handled = element.applyNetworkACLs(network, rules);
     if (handled) break;
   }
   if (!foundProvider) {
     s_logger.debug("Unable to find NetworkACL service provider for network: " + network.getId());
   }
   return handled;
 }
 @Override
 public boolean applyRules(Network network, Purpose purpose, List<? extends FirewallRule> rules)
     throws ResourceUnavailableException {
   boolean handled = false;
   switch (purpose) {
       /* StaticNatRule would be applied by Firewall provider, since the incompatible of two object */
     case StaticNat:
     case Firewall:
       for (FirewallServiceProvider fwElement : _firewallElements) {
         Network.Provider provider = fwElement.getProvider();
         boolean isFwProvider =
             _networkModel.isProviderSupportServiceInNetwork(
                 network.getId(), Service.Firewall, provider);
         if (!isFwProvider) {
           continue;
         }
         handled = fwElement.applyFWRules(network, rules);
         if (handled) break;
       }
       break;
     case PortForwarding:
       for (PortForwardingServiceProvider element : _pfElements) {
         Network.Provider provider = element.getProvider();
         boolean isPfProvider =
             _networkModel.isProviderSupportServiceInNetwork(
                 network.getId(), Service.PortForwarding, provider);
         if (!isPfProvider) {
           continue;
         }
         handled = element.applyPFRules(network, (List<PortForwardingRule>) rules);
         if (handled) break;
       }
       break;
       /*        case NetworkACL:
       for (NetworkACLServiceProvider element: _networkAclElements) {
           Network.Provider provider = element.getProvider();
           boolean  isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
           if (!isAclProvider) {
               continue;
           }
           handled = element.applyNetworkACLs(network, rules);
           if (handled)
               break;
       }
       break;*/
     default:
       assert (false) : "Unexpected fall through in applying rules to the network elements";
       s_logger.error("FirewallManager cannot process rules of type " + purpose);
       throw new CloudRuntimeException("FirewallManager cannot process rules of type " + purpose);
   }
   return handled;
 }
  @Override
  public boolean applyLoadBalancerRules(Network network, List<? extends FirewallRule> rules)
      throws ResourceUnavailableException {
    if (rules == null || rules.isEmpty()) {
      return true;
    }
    if (rules.get(0).getPurpose() != Purpose.LoadBalancing) {
      s_logger.warn("ELB: Not handling non-LB firewall rules");
      return false;
    }

    DomainRouterVO elbVm = findElbVmForLb(rules.get(0));

    if (elbVm == null) {
      s_logger.warn(
          "Unable to apply lb rules, ELB vm  doesn't exist in the network " + network.getId());
      throw new ResourceUnavailableException(
          "Unable to apply lb rules", DataCenter.class, network.getDataCenterId());
    }

    if (elbVm.getState() == State.Running) {
      // resend all rules for the public ip
      List<LoadBalancerVO> lbs = _lbDao.listByIpAddress(rules.get(0).getSourceIpAddressId());
      List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
      for (LoadBalancerVO lb : lbs) {
        List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
        List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
        List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId());
        LoadBalancingRule loadBalancing =
            new LoadBalancingRule(lb, dstList, policyList, hcPolicyList);
        lbRules.add(loadBalancing);
      }
      return applyLBRules(elbVm, lbRules, network.getId());
    } else if (elbVm.getState() == State.Stopped || elbVm.getState() == State.Stopping) {
      s_logger.debug(
          "ELB VM is in "
              + elbVm.getState()
              + ", so not sending apply LoadBalancing rules commands to the backend");
      return true;
    } else {
      s_logger.warn(
          "Unable to apply loadbalancing rules, ELB VM is not in the right state "
              + elbVm.getState());
      throw new ResourceUnavailableException(
          "Unable to apply loadbalancing rules, ELB VM is not in the right state",
          VirtualRouter.class,
          elbVm.getId());
    }
  }
  @Override
  public boolean applyNetworkACLs(
      final Network network,
      final List<? extends NetworkACLItem> rules,
      final VirtualRouter router,
      final boolean isPrivateGateway)
      throws ResourceUnavailableException {

    if (rules == null || rules.isEmpty()) {
      s_logger.debug("No network ACLs to be applied for network " + network.getId());
      return true;
    }

    s_logger.debug("APPLYING NETWORK ACLs RULES");

    final String typeString = "network acls";
    final boolean isPodLevelException = false;
    final boolean failWhenDisconnect = false;
    final Long podId = null;

    final NetworkAclsRules aclsRules = new NetworkAclsRules(network, rules, isPrivateGateway);

    final boolean result =
        applyRules(
            network,
            router,
            typeString,
            isPodLevelException,
            podId,
            failWhenDisconnect,
            new RuleApplierWrapper<RuleApplier>(aclsRules));
    return result;
  }
 public NetworkProfile(Network network) {
   this.id = network.getId();
   this.uuid = network.getUuid();
   this.broadcastUri = network.getBroadcastUri();
   this.dataCenterId = network.getDataCenterId();
   this.ownerId = network.getAccountId();
   this.state = network.getState();
   this.name = network.getName();
   this.mode = network.getMode();
   this.broadcastDomainType = network.getBroadcastDomainType();
   this.trafficType = network.getTrafficType();
   this.gateway = network.getGateway();
   this.cidr = network.getCidr();
   this.networkOfferingId = network.getNetworkOfferingId();
   this.related = network.getRelated();
   this.displayText = network.getDisplayText();
   this.reservationId = network.getReservationId();
   this.networkDomain = network.getNetworkDomain();
   this.domainId = network.getDomainId();
   this.guestType = network.getGuestType();
   this.physicalNetworkId = network.getPhysicalNetworkId();
   this.aclType = network.getAclType();
   this.restartRequired = network.isRestartRequired();
   this.specifyIpRanges = network.getSpecifyIpRanges();
   this.vpcId = network.getVpcId();
 }
 @Override
 protected void allocateVnet(
     Network network,
     NetworkVO implemented,
     long dcId,
     long physicalNetworkId,
     String reservationId)
     throws InsufficientVirtualNetworkCapcityException {
   if (network.getBroadcastUri() == null) {
     String vnet =
         _dcDao.allocateVnet(
             dcId,
             physicalNetworkId,
             network.getAccountId(),
             reservationId,
             UseSystemGuestVlans.valueIn(network.getAccountId()));
     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));
     ActionEventUtils.onCompletedActionEvent(
         CallContext.current().getCallingUserId(),
         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
  public void reserve(
      NicProfile nic,
      Network config,
      VirtualMachineProfile<? extends VirtualMachine> vm,
      DeployDestination dest,
      ReservationContext context)
      throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {
    assert nic.getTrafficType() == TrafficType.Control;

    if (dest.getHost().getHypervisorType() == HypervisorType.VmWare
        && vm.getType() == VirtualMachine.Type.DomainRouter) {
      super.reserve(nic, config, vm, dest, context);

      String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
      nic.setMacAddress(mac);
      return;
    }

    String ip =
        _dcDao.allocateLinkLocalIpAddress(
            dest.getDataCenter().getId(),
            dest.getPod().getId(),
            nic.getId(),
            context.getReservationId());
    nic.setIp4Address(ip);
    nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40)));
    nic.setNetmask("255.255.0.0");
    nic.setFormat(AddressFormat.Ip4);
    nic.setGateway(NetUtils.getLinkLocalGateway());
  }
 private boolean canHandle(Network network) {
   if (canHandle(_physicalNetworkDao.findById(network.getPhysicalNetworkId()))) {
     if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(
         network.getId(), Service.Connectivity, getProvider())) {
       s_logger.info("SSP is implicitly active for " + network);
     }
     return true;
   }
   return false;
 }
  private boolean canHandle(Network config) {
    DataCenter zone = _configMgr.getZone(config.getDataCenterId());
    if ((zone.getNetworkType() == NetworkType.Advanced
            && config.getGuestType() != Network.GuestType.Isolated)
        || (zone.getNetworkType() == NetworkType.Basic
            && config.getGuestType() != Network.GuestType.Shared)) {
      s_logger.trace("Not handling network type = " + config.getGuestType());
      return false;
    }

    return _networkManager.networkIsConfiguredForExternalNetworking(zone.getId(), config.getId());
  }
 @Override
 public boolean validateLBRule(final Network network, final LoadBalancingRule rule) {
   final List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>();
   rules.add(rule);
   if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) {
     final List<DomainRouterVO> routers =
         _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
     if (routers == null || routers.isEmpty()) {
       return true;
     }
     return validateHAProxyLBRule(rule);
   }
   return true;
 }
 @Override
 public CiscoAsa1000vDevice assignAsa1000vToNetwork(Network network) {
   List<CiscoAsa1000vDeviceVO> asaList =
       _ciscoAsa1000vDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
   for (CiscoAsa1000vDeviceVO asa : asaList) {
     NetworkAsa1000vMapVO assignedToNetwork = _networkAsa1000vMapDao.findByAsa1000vId(asa.getId());
     if (assignedToNetwork == null) {
       NetworkAsa1000vMapVO networkAsaMap = new NetworkAsa1000vMapVO(network.getId(), asa.getId());
       _networkAsa1000vMapDao.persist(networkAsaMap);
       return asa;
     }
   }
   return null;
 }
  @Override
  public boolean applyIps(
      final Network network,
      final List<? extends PublicIpAddress> ipAddress,
      final Set<Service> services)
      throws ResourceUnavailableException {
    boolean canHandle = true;
    for (final Service service : services) {
      // check if Ovs can handle services except SourceNat & Firewall
      if (!canHandle(network, service)
          && service != Service.SourceNat
          && service != Service.Firewall) {
        canHandle = false;
        break;
      }
    }
    boolean result = true;
    if (canHandle) {
      final List<DomainRouterVO> routers =
          _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
      if (routers == null || routers.isEmpty()) {
        s_logger.debug(
            "Virtual router element doesn't need to associate ip addresses on the backend; virtual "
                + "router doesn't exist in the network "
                + network.getId());
        return true;
      }

      final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
      final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);

      for (final DomainRouterVO domainRouterVO : routers) {
        result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
      }
    }
    return result;
  }
  @DB
  public PublicIp allocDirectIp(Account account, long guestNetworkId)
      throws InsufficientAddressCapacityException {
    Network frontEndNetwork = _networkModel.getNetwork(guestNetworkId);
    Transaction txn = Transaction.currentTxn();
    txn.start();

    PublicIp ip =
        _networkMgr.assignPublicIpAddress(
            frontEndNetwork.getDataCenterId(),
            null,
            account,
            VlanType.DirectAttached,
            frontEndNetwork.getId(),
            null,
            true);
    IPAddressVO ipvo = _ipAddressDao.findById(ip.getId());
    ipvo.setAssociatedWithNetworkId(frontEndNetwork.getId());
    _ipAddressDao.update(ipvo.getId(), ipvo);
    txn.commit();
    s_logger.info("Acquired frontend IP for ELB " + ip);

    return ip;
  }
  @Override
  public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules)
      throws ResourceUnavailableException {
    if (!canHandle(network, Service.StaticNat)) {
      return false;
    }
    final List<DomainRouterVO> routers =
        _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
    if (routers == null || routers.isEmpty()) {
      s_logger.debug(
          "Ovs element doesn't need to apply static nat on the backend; virtual "
              + "router doesn't exist in the network "
              + network.getId());
      return true;
    }

    final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
    boolean result = true;
    for (final DomainRouterVO domainRouterVO : routers) {
      result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
    }
    return result;
  }
 @Override
 @DB
 public void addRouterToGuestNetwork(VirtualRouter router, Network guestNetwork) {
   if (_routerNetworkDao.findByRouterAndNetwork(router.getId(), guestNetwork.getId()) == null) {
     NetworkOffering off = _offDao.findById(guestNetwork.getNetworkOfferingId());
     if (!(off.getName().equalsIgnoreCase(NetworkOffering.SystemPrivateGatewayNetworkOffering))) {
       TransactionLegacy txn = TransactionLegacy.currentTxn();
       txn.start();
       // 1) add router to network
       RouterNetworkVO routerNtwkMap =
           new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType());
       _routerNetworkDao.persist(routerNtwkMap);
       // 2) create user stats entry for the network
       UserStatisticsVO stats =
           _userStatsDao.findBy(
               router.getAccountId(),
               router.getDataCenterId(),
               guestNetwork.getId(),
               null,
               router.getId(),
               router.getType().toString());
       if (stats == null) {
         stats =
             new UserStatisticsVO(
                 router.getAccountId(),
                 router.getDataCenterId(),
                 null,
                 router.getId(),
                 router.getType().toString(),
                 guestNetwork.getId());
         _userStatsDao.persist(stats);
       }
       txn.commit();
     }
   }
 }
  @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 associatePublicIP(
      final Network network,
      final List<? extends PublicIpAddress> ipAddresses,
      final VirtualRouter router)
      throws ResourceUnavailableException {

    if (ipAddresses == null || ipAddresses.isEmpty()) {
      s_logger.debug("No ip association rules to be applied for network " + network.getId());
      return true;
    }

    if (network.getVpcId() == null) {
      return super.associatePublicIP(network, ipAddresses, router);
    }

    s_logger.debug("APPLYING VPC IP RULES");

    final String typeString = "vpc ip association";
    final boolean isPodLevelException = false;
    final boolean failWhenDisconnect = false;
    final Long podId = null;

    final NicPlugInOutRules nicPlugInOutRules = new NicPlugInOutRules(network, ipAddresses);
    nicPlugInOutRules.accept(_advancedVisitor, router);

    final VpcIpAssociationRules ipAssociationRules =
        new VpcIpAssociationRules(network, ipAddresses);
    final boolean result =
        applyRules(
            network,
            router,
            typeString,
            isPodLevelException,
            podId,
            failWhenDisconnect,
            new RuleApplierWrapper<RuleApplier>(ipAssociationRules));

    if (result) {
      _advancedVisitor.visit(nicPlugInOutRules);
    }

    return result;
  }
  @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 boolean prepare(
      Network network,
      NicProfile nic,
      VirtualMachineProfile vm,
      DeployDestination dest,
      ReservationContext context)
      throws ConcurrentOperationException, ResourceUnavailableException,
          InsufficientCapacityException {
    if (vm.getType() != Type.User) {
      return false;
    }

    // ensure that there is an ASA 1000v assigned to this network
    NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
    if (asaForNetwork == null) {
      return false;
    }

    return true;
  }
  public boolean createNetwork(
      Network network,
      NetworkOffering offering,
      DeployDestination dest,
      ReservationContext context) {
    if (_sspUuidDao.findUuidByNetwork(network) != null) {
      s_logger.info("Network already has ssp TenantNetwork uuid :" + network.toString());
      return true;
    }
    if (!canHandle(network)) {
      return false;
    }

    String tenantUuid = _sspTenantDao.findUuidByZone(network.getDataCenterId());
    if (tenantUuid == null) {
      tenantUuid = _configDao.getValueAndInitIfNotExist("ssp.tenant", "Network", null);
    }

    boolean processed = false;
    for (SspClient client :
        fetchSspClients(network.getPhysicalNetworkId(), network.getDataCenterId(), true)) {
      SspClient.TenantNetwork sspNet = client.createTenantNetwork(tenantUuid, network.getName());
      if (sspNet != null) {
        SspUuidVO uuid = new SspUuidVO();
        uuid.setUuid(sspNet.uuid);
        uuid.setObjClass(SspUuidVO.objClassNetwork);
        uuid.setObjId(network.getId());
        _sspUuidDao.persist(uuid);
        return true;
      }
      processed = true;
    }
    if (processed) {
      s_logger.error("Could not allocate an uuid for network " + network.toString());
      return false;
    } else {
      s_logger.error("Skipping #createNetwork() for " + network.toString());
      return true;
    }
  }
  @Override
  public NicProfile allocate(
      Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
      throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException {

    if (config.getTrafficType() != TrafficType.Control) {
      return null;
    }

    if (vm.getHypervisorType() == HypervisorType.VmWare
        && vm.getType() != VirtualMachine.Type.DomainRouter) {
      NicProfile nicProf = new NicProfile(ReservationStrategy.Create, null, null, null, null);
      String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId());
      nicProf.setMacAddress(mac);
      return nicProf;
    }

    if (nic != null) {
      throw new CloudRuntimeException("Does not support nic specification at this time: " + nic);
    }

    return new NicProfile(ReservationStrategy.Start, null, null, null, null);
  }
  @Override
  public boolean destroyPrivateGateway(final PrivateGateway gateway, final VirtualRouter router)
      throws ConcurrentOperationException, ResourceUnavailableException {

    if (!_networkModel.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) {
      s_logger.debug(
          "Router doesn't have nic for gateway " + gateway + " so no need to removed it");
      return true;
    }

    final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());

    s_logger.debug("Releasing private ip for gateway " + gateway + " from " + router);
    boolean result =
        setupVpcPrivateNetwork(
            router, false, _networkModel.getNicProfile(router, privateNetwork.getId(), null));
    if (!result) {
      s_logger.warn("Failed to release private ip for gateway " + gateway + " on router " + router);
      return false;
    }

    // revoke network acl on the private gateway.
    if (!_networkACLMgr.revokeACLItemsForPrivateGw(gateway)) {
      s_logger.debug("Failed to delete network acl items on " + gateway + " from router " + router);
      return false;
    }

    s_logger.debug(
        "Removing router "
            + router
            + " from private network "
            + privateNetwork
            + " as a part of delete private gateway");
    result = result && _itMgr.removeVmFromNetwork(router, privateNetwork, null);
    s_logger.debug("Private gateawy " + gateway + " is removed from router " + router);
    return result;
  }
  @Override
  public boolean revokeACLItemsForNetwork(long networkId) throws ResourceUnavailableException {
    Network network = _networkDao.findById(networkId);
    if (network.getNetworkACLId() == null) {
      return true;
    }
    List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(network.getNetworkACLId());
    if (aclItems.isEmpty()) {
      s_logger.debug("Found no network ACL Items for network id=" + networkId);
      return true;
    }

    if (s_logger.isDebugEnabled()) {
      s_logger.debug(
          "Releasing " + aclItems.size() + " Network ACL Items for network id=" + networkId);
    }

    for (NetworkACLItemVO aclItem : aclItems) {
      // Mark all Network ACLs rules as Revoke, but don't update in DB
      if (aclItem.getState() == State.Add || aclItem.getState() == State.Active) {
        aclItem.setState(State.Revoke);
      }
    }

    boolean success = applyACLItemsToNetwork(network.getId(), aclItems);

    if (s_logger.isDebugEnabled() && success) {
      s_logger.debug(
          "Successfully released Network ACLs for network id="
              + networkId
              + " and # of rules now = "
              + aclItems.size());
    }

    return success;
  }
  @Override
  @DB
  public RemoteAccessVpn createRemoteAccessVpn(
      final long publicIpId, String ipRange, boolean openFirewall, final Boolean forDisplay)
      throws NetworkRuleConflictException {
    CallContext ctx = CallContext.current();
    final Account caller = ctx.getCallingAccount();

    Long networkId = null;

    // make sure ip address exists
    final PublicIpAddress ipAddr = _networkMgr.getPublicIpAddress(publicIpId);
    if (ipAddr == null) {
      throw new InvalidParameterValueException(
          "Unable to create remote access vpn, invalid public IP address id" + publicIpId);
    }

    _accountMgr.checkAccess(caller, null, true, ipAddr);

    if (!ipAddr.readyToUse()) {
      throw new InvalidParameterValueException(
          "The Ip address is not ready to be used yet: " + ipAddr.getAddress());
    }

    IPAddressVO ipAddress = _ipAddressDao.findById(publicIpId);

    networkId = ipAddress.getAssociatedWithNetworkId();
    if (networkId != null) {
      _networkMgr.checkIpForService(ipAddress, Service.Vpn, null);
    }

    final Long vpcId = ipAddress.getVpcId();
    /* IP Address used for VPC must be the source NAT IP of whole VPC */
    if (vpcId != null && ipAddress.isSourceNat()) {
      assert networkId == null;
      // No firewall setting for VPC, it would be open internally
      openFirewall = false;
    }

    final boolean openFirewallFinal = openFirewall;

    if (networkId == null && vpcId == null) {
      throw new InvalidParameterValueException(
          "Unable to create remote access vpn for the ipAddress: "
              + ipAddr.getAddress().addr()
              + " as ip is not associated with any network or VPC");
    }

    RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIpId);

    if (vpnVO != null) {
      // if vpn is in Added state, return it to the api
      if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
        return vpnVO;
      }
      throw new InvalidParameterValueException(
          "A Remote Access VPN already exists for this public Ip address");
    }

    if (ipRange == null) {
      ipRange = RemoteAccessVpnClientIpRange.valueIn(ipAddr.getAccountId());
    }
    final String[] range = ipRange.split("-");
    if (range.length != 2) {
      throw new InvalidParameterValueException("Invalid ip range");
    }
    if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) {
      throw new InvalidParameterValueException("Invalid ip in range specification " + ipRange);
    }
    if (!NetUtils.validIpRange(range[0], range[1])) {
      throw new InvalidParameterValueException("Invalid ip range " + ipRange);
    }

    Pair<String, Integer> cidr = null;

    // TODO: assumes one virtual network / domr per account per zone
    if (networkId != null) {
      vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), networkId);
      if (vpnVO != null) {
        // if vpn is in Added state, return it to the api
        if (vpnVO.getState() == RemoteAccessVpn.State.Added) {
          return vpnVO;
        }
        throw new InvalidParameterValueException(
            "A Remote Access VPN already exists for this account");
      }
      // Verify that vpn service is enabled for the network
      Network network = _networkMgr.getNetwork(networkId);
      if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Vpn)) {
        throw new InvalidParameterValueException(
            "Vpn service is not supported in network id=" + ipAddr.getAssociatedWithNetworkId());
      }
      cidr = NetUtils.getCidr(network.getCidr());
    } else { // Don't need to check VPC because there is only one IP(source NAT IP) available for
             // VPN
      Vpc vpc = _vpcDao.findById(vpcId);
      cidr = NetUtils.getCidr(vpc.getCidr());
    }

    // FIXME: This check won't work for the case where the guest ip range
    // changes depending on the vlan allocated.
    String[] guestIpRange = NetUtils.getIpRangeFromCidr(cidr.first(), cidr.second());
    if (NetUtils.ipRangesOverlap(range[0], range[1], guestIpRange[0], guestIpRange[1])) {
      throw new InvalidParameterValueException(
          "Invalid ip range: "
              + ipRange
              + " overlaps with guest ip range "
              + guestIpRange[0]
              + "-"
              + guestIpRange[1]);
    }
    // TODO: check sufficient range
    // TODO: check overlap with private and public ip ranges in datacenter

    long startIp = NetUtils.ip2Long(range[0]);
    final String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1];
    final String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength);

    return Transaction.execute(
        new TransactionCallbackWithException<RemoteAccessVpn, NetworkRuleConflictException>() {
          @Override
          public RemoteAccessVpn doInTransaction(TransactionStatus status)
              throws NetworkRuleConflictException {
            if (vpcId == null) {
              _rulesMgr.reservePorts(
                  ipAddr,
                  NetUtils.UDP_PROTO,
                  Purpose.Vpn,
                  openFirewallFinal,
                  caller,
                  NetUtils.VPN_PORT,
                  NetUtils.VPN_L2TP_PORT,
                  NetUtils.VPN_NATT_PORT);
            }
            RemoteAccessVpnVO vpnVO =
                new RemoteAccessVpnVO(
                    ipAddr.getAccountId(),
                    ipAddr.getDomainId(),
                    ipAddr.getAssociatedWithNetworkId(),
                    publicIpId,
                    vpcId,
                    range[0],
                    newIpRange,
                    sharedSecret);

            if (forDisplay != null) {
              vpnVO.setDisplay(forDisplay);
            }
            return _remoteAccessVpnDao.persist(vpnVO);
          }
        });
  }
  @Override
  public LinkedHashMap<Network, List<? extends NicProfile>> configureGuestNic(
      final RouterDeploymentDefinition routerDeploymentDefinition)
      throws ConcurrentOperationException, InsufficientAddressCapacityException {

    // Form networks
    final LinkedHashMap<Network, List<? extends NicProfile>> networks =
        new LinkedHashMap<Network, List<? extends NicProfile>>(3);
    // 1) Guest network
    final Network guestNetwork = routerDeploymentDefinition.getGuestNetwork();

    if (guestNetwork != null) {
      s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork);
      String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null;
      if (!routerDeploymentDefinition.isPublicNetwork()) {
        final Nic placeholder =
            _networkModel.getPlaceholderNicForRouter(
                guestNetwork, routerDeploymentDefinition.getPodId());
        if (guestNetwork.getCidr() != null) {
          if (placeholder != null && placeholder.getIPv4Address() != null) {
            s_logger.debug(
                "Requesting ipv4 address "
                    + placeholder.getIPv4Address()
                    + " stored in placeholder nic for the network "
                    + guestNetwork);
            defaultNetworkStartIp = placeholder.getIPv4Address();
          } else {
            final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
            if (startIp != null
                && _ipAddressDao
                        .findByIpAndSourceNetworkId(guestNetwork.getId(), startIp)
                        .getAllocatedTime()
                    == null) {
              defaultNetworkStartIp = startIp;
            } else if (s_logger.isDebugEnabled()) {
              s_logger.debug(
                  "First ipv4 "
                      + startIp
                      + " in network id="
                      + guestNetwork.getId()
                      + " is already allocated, can't use it for domain router; will get random ip address from the range");
            }
          }
        }

        if (guestNetwork.getIp6Cidr() != null) {
          if (placeholder != null && placeholder.getIPv6Address() != null) {
            s_logger.debug(
                "Requesting ipv6 address "
                    + placeholder.getIPv6Address()
                    + " stored in placeholder nic for the network "
                    + guestNetwork);
            defaultNetworkStartIpv6 = placeholder.getIPv6Address();
          } else {
            final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
            if (startIpv6 != null
                && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
              defaultNetworkStartIpv6 = startIpv6;
            } else if (s_logger.isDebugEnabled()) {
              s_logger.debug(
                  "First ipv6 "
                      + startIpv6
                      + " in network id="
                      + guestNetwork.getId()
                      + " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
            }
          }
        }
      }

      final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
      if (routerDeploymentDefinition.isPublicNetwork()) {
        if (routerDeploymentDefinition.isRedundant()) {
          gatewayNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
        } else {
          gatewayNic.setIPv4Address(guestNetwork.getGateway());
        }
        gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri());
        gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
        gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri());
        gatewayNic.setMode(guestNetwork.getMode());
        final String gatewayCidr = guestNetwork.getCidr();
        gatewayNic.setIPv4Netmask(NetUtils.getCidrNetmask(gatewayCidr));
      } else {
        gatewayNic.setDefaultNic(true);
      }

      networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(gatewayNic)));
    }
    return networks;
  }