@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 Network design(
      final NetworkOffering offering,
      final DeploymentPlan plan,
      final Network userSpecified,
      final Account owner) {
    // Check of the isolation type of the related physical network is supported
    final PhysicalNetworkVO physnet = physicalNetworkDao.findById(plan.getPhysicalNetworkId());
    final DataCenter dc = _dcDao.findById(plan.getDataCenterId());
    if (!canHandle(offering, dc.getNetworkType(), physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }

    final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physnet.getId());
    if (devices.isEmpty()) {
      s_logger.error("No NiciraNvp Controller on physical network " + physnet.getName());
      return null;
    }
    s_logger.debug(
        "Nicira Nvp " + devices.get(0).getUuid() + " found on physical network " + physnet.getId());

    s_logger.debug(
        "Physical isolation type is supported, asking GuestNetworkGuru to design this network");
    final NetworkVO networkObject = (NetworkVO) super.design(offering, plan, userSpecified, owner);
    if (networkObject == null) {
      return null;
    }
    networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch);

    return networkObject;
  }
 /**
  * @param networks
  * @param offerings
  * @throws ConcurrentOperationException
  */
 private void mockMgrs() throws ConcurrentOperationException {
   final Service service = Service.Connectivity;
   testNetwork.setState(Network.State.Implementing);
   testNetwork.setTrafficType(TrafficType.Guest);
   when(_networkMdl.isProviderEnabledInPhysicalNetwork(0L, "VirtualRouter")).thenReturn(true);
   when(_networkMdl.isProviderSupportServiceInNetwork(
           testNetwork.getId(), service, Network.Provider.VirtualRouter))
       .thenReturn(true);
   when(_networkMdl.isProviderForNetwork(Network.Provider.VirtualRouter, 0L)).thenReturn(true);
   when(testVMProfile.getType()).thenReturn(VirtualMachine.Type.User);
   when(testVMProfile.getHypervisorType()).thenReturn(HypervisorType.XenServer);
   final List<NetworkVO> networks = new ArrayList<NetworkVO>(1);
   networks.add(testNetwork);
   final List<NetworkOfferingVO> offerings = new ArrayList<NetworkOfferingVO>(1);
   offerings.add(testOffering);
   doReturn(offerings)
       .when(_networkModel)
       .getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
   doReturn(networks)
       .when(_networkMgr)
       .setupNetwork(
           any(Account.class),
           any(NetworkOffering.class),
           any(DeploymentPlan.class),
           any(String.class),
           any(String.class),
           anyBoolean());
   // being anti-social and testing my own case first
   doReturn(HypervisorType.XenServer).when(_resourceMgr).getDefaultHypervisor(anyLong());
   doReturn(new AccountVO()).when(_accountMgr).getAccount(testNetwork.getAccountId());
 }
  public DomainRouterVO deployLoadBalancerVM(Long networkId, IPAddressVO ipAddr, Long accountId) {
    NetworkVO network = _networkDao.findById(networkId);
    DataCenter dc = _dcDao.findById(network.getDataCenterId());
    Long podId = getPodIdForDirectIp(ipAddr);
    Pod pod = podId == null ? null : _podDao.findById(podId);
    Map<VirtualMachineProfile.Param, Object> params =
        new HashMap<VirtualMachineProfile.Param, Object>(1);
    params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
    Account owner = _accountService.getActiveAccountByName("system", new Long(1));
    DeployDestination dest = new DeployDestination(dc, pod, null, null);
    s_logger.debug("About to deploy ELB vm ");

    try {
      DomainRouterVO elbVm = deployELBVm(network, dest, owner, params);
      if (elbVm == null) {
        throw new InvalidParameterValueException("Could not deploy or find existing ELB VM");
      }
      s_logger.debug("Deployed ELB  vm = " + elbVm);

      return elbVm;

    } catch (Throwable t) {
      s_logger.warn("Error while deploying ELB VM:  ", t);
      return null;
    }
  }
  /** @param network */
  private void mockDAOs(final NetworkVO network, final NetworkOfferingVO offering) {
    when(_networkDao.acquireInLockTable(
            network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()))
        .thenReturn(network);
    when(_networksDao.acquireInLockTable(
            network.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()))
        .thenReturn(network);
    when(_physicalProviderDao.findByServiceProvider(0L, "VirtualRouter"))
        .thenReturn(new PhysicalNetworkServiceProviderVO());
    when(_vrProviderDao.findByNspIdAndType(0L, Type.VirtualRouter))
        .thenReturn(new VirtualRouterProviderVO());
    when(_networkOfferingDao.findById(0L)).thenReturn(offering);
    // watchit: (in this test) there can be only one
    when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(0L);
    final ServiceOfferingVO svcoff =
        new ServiceOfferingVO(
            "name",
            /* cpu */ 1,
            /* ramsize */ 1024 * 1024,
            /* (clock?)speed */ 1024 * 1024 * 1024,
            /* rateMbps */ 1,
            /* multicastRateMbps */ 0,
            /* offerHA */ false,
            "displayText",
            ProvisioningType.THIN,
            /* useLocalStorage */ false,
            /* recreatable */ false,
            "tags",
            /* systemUse */ false,
            VirtualMachine.Type.DomainRouter,
            /* defaultUse */ false);
    when(_serviceOfferingDao.findById(0L)).thenReturn(svcoff);
    final DomainRouterVO router =
        new DomainRouterVO(
            /* id */ 1L,
            /* serviceOfferingId */ 1L,
            /* elementId */ 0L,
            "name",
            /* templateId */ 0L,
            HypervisorType.XenServer,
            /* guestOSId */ 0L,
            /* domainId */ 0L,
            /* accountId */ 1L,
            /* userId */ 1L,
            /* isRedundantRouter */ false,
            RedundantState.UNKNOWN,
            /* haEnabled */ false,
            /* stopPending */ false,
            /* vpcId */ null);

    when(_routerDao.getNextInSequence(Long.class, "id")).thenReturn(1L);
    when(_templateDao.findRoutingTemplate(
            HypervisorType.XenServer, "SystemVM Template (XenServer)"))
        .thenReturn(new VMTemplateVO());
    when(_routerDao.persist(any(DomainRouterVO.class))).thenReturn(router);
    when(_routerDao.findById(router.getId())).thenReturn(router);
  }
  @Override
  public void shutdown(NetworkProfile profile, NetworkOffering offering) {
    NetworkVO networkObject = _networkDao.findById(profile.getId());
    if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Vswitch
        || networkObject.getBroadcastUri() == null) {
      s_logger.warn(
          "BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
      return;
    }

    super.shutdown(profile, offering);
  }
  @Override
  public boolean applyDefaultEgressFirewallRule(Long networkId, boolean defaultPolicy)
      throws ResourceUnavailableException {

    if (defaultPolicy == false) {
      // If default policy is false no need apply rules on backend because firewall provider blocks
      // by default
      return true;
    }
    s_logger.debug("applying default firewall egress rules ");

    NetworkVO network = _networkDao.findById(networkId);
    List<String> sourceCidr = new ArrayList<String>();

    sourceCidr.add(NetUtils.ALL_CIDRS);
    FirewallRuleVO ruleVO =
        new FirewallRuleVO(
            null,
            null,
            null,
            null,
            "all",
            networkId,
            network.getAccountId(),
            network.getDomainId(),
            Purpose.Firewall,
            sourceCidr,
            null,
            null,
            null,
            FirewallRule.TrafficType.Egress,
            FirewallRuleType.System);
    List<FirewallRuleVO> rules = new ArrayList<FirewallRuleVO>();
    rules.add(ruleVO);

    try {
      // this is not required to store in db because we don't to add this rule along with the normal
      // rules
      if (!applyRules(rules, false, false)) {
        return false;
      }
    } catch (ResourceUnavailableException ex) {
      s_logger.warn("Failed to apply default egress rules for guest network due to ", ex);
      return false;
    }
    return true;
  }
  @Override
  public void shutdown(final NetworkProfile profile, final NetworkOffering offering) {
    final NetworkVO networkObject = networkDao.findById(profile.getId());
    if (networkObject.getBroadcastDomainType() != BroadcastDomainType.Lswitch
        || networkObject.getBroadcastUri() == null) {
      s_logger.warn(
          "BroadcastUri is empty or incorrect for guestnetwork " + networkObject.getDisplayText());
      return;
    }

    final List<NiciraNvpDeviceVO> devices =
        niciraNvpDao.listByPhysicalNetwork(networkObject.getPhysicalNetworkId());
    if (devices.isEmpty()) {
      s_logger.error(
          "No NiciraNvp Controller on physical network " + networkObject.getPhysicalNetworkId());
      return;
    }
    final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
    final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId());

    final DeleteLogicalSwitchCommand cmd =
        new DeleteLogicalSwitchCommand(
            BroadcastDomainType.getValue(networkObject.getBroadcastUri()));
    final DeleteLogicalSwitchAnswer answer =
        (DeleteLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd);

    if (answer == null || !answer.getResult()) {
      s_logger.error("DeleteLogicalSwitchCommand failed");
    }

    super.shutdown(profile, offering);
  }
  @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) {

    PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
    DataCenter dc = _dcDao.findById(plan.getDataCenterId());
    if (!canHandle(offering, dc.getNetworkType(), physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }
    NetworkVO config = (NetworkVO) super.design(offering, plan, userSpecified, owner);
    if (config == null) {
      return null;
    }

    config.setBroadcastDomainType(BroadcastDomainType.Vswitch);

    return config;
  }
  @Override
  public boolean applyNetworkACL(long aclId) throws ResourceUnavailableException {
    boolean handled = true;
    boolean aclApplyStatus = true;

    List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(aclId);
    // Find all networks using this ACL and apply the ACL
    List<NetworkVO> networks = _networkDao.listByAclId(aclId);
    for (NetworkVO network : networks) {
      if (!applyACLItemsToNetwork(network.getId(), rules)) {
        handled = false;
        break;
      }
    }

    List<VpcGatewayVO> vpcGateways =
        _vpcGatewayDao.listByAclIdAndType(aclId, VpcGateway.Type.Private);
    for (VpcGatewayVO vpcGateway : vpcGateways) {
      PrivateGateway privateGateway = _vpcMgr.getVpcPrivateGateway(vpcGateway.getId());
      if (!applyACLToPrivateGw(privateGateway)) {
        aclApplyStatus = false;
        s_logger.debug(
            "failed to apply network acl item on private gateway "
                + privateGateway.getId()
                + "acl id "
                + aclId);
        break;
      }
    }

    if (handled && aclApplyStatus) {
      for (NetworkACLItem rule : rules) {
        if (rule.getState() == NetworkACLItem.State.Revoke) {
          removeRule(rule);
        } else if (rule.getState() == NetworkACLItem.State.Add) {
          NetworkACLItemVO ruleVO = _networkACLItemDao.findById(rule.getId());
          ruleVO.setState(NetworkACLItem.State.Active);
          _networkACLItemDao.update(ruleVO.getId(), ruleVO);
        }
      }
    }
    return handled && aclApplyStatus;
  }
  @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
  public boolean replaceNetworkACL(NetworkACL acl, NetworkVO network)
      throws ResourceUnavailableException {

    NetworkOffering guestNtwkOff =
        _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());

    if (guestNtwkOff == null) {
      throw new InvalidParameterValueException(
          "Can't find network offering associated with network: " + network.getUuid());
    }

    // verify that ACLProvider is supported by network offering
    if (!_ntwkModel.areServicesSupportedByNetworkOffering(
        guestNtwkOff.getId(), Service.NetworkACL)) {
      throw new InvalidParameterValueException(
          "Cannot apply NetworkACL. Network Offering does not support NetworkACL service");
    }

    if (network.getNetworkACLId() != null) {
      // Revoke ACL Items of the existing ACL if the new ACL is empty
      // Existing rules won't be removed otherwise
      List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(acl.getId());
      if (aclItems == null || aclItems.isEmpty()) {
        s_logger.debug("New network ACL is empty. Revoke existing rules before applying ACL");
        if (!revokeACLItemsForNetwork(network.getId())) {
          throw new CloudRuntimeException(
              "Failed to replace network ACL. Error while removing existing ACL items for network: "
                  + network.getId());
        }
      }
    }

    network.setNetworkACLId(acl.getId());
    // Update Network ACL
    if (_networkDao.update(network.getId(), network)) {
      s_logger.debug(
          "Updated network: "
              + network.getId()
              + " with Network ACL Id: "
              + acl.getId()
              + ", Applying ACL items");
      // Apply ACL to network
      return applyACLToNetwork(network.getId());
    }
    return false;
  }
  @Override
  public Network implement(
      Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
      throws InsufficientVirtualNetworkCapcityException {
    assert (network.getState() == State.Implementing) : "Why are we implementing " + network;

    long dcId = dest.getDataCenter().getId();
    NetworkType nwType = dest.getDataCenter().getNetworkType();
    // get physical network id
    Long physicalNetworkId = network.getPhysicalNetworkId();
    // physical network id can be null in Guest Network in Basic zone, so
    // locate the physical network
    if (physicalNetworkId == null) {
      physicalNetworkId =
          _networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
    }
    PhysicalNetworkVO physnet = _physicalNetworkDao.findById(physicalNetworkId);

    if (!canHandle(offering, nwType, physnet)) {
      s_logger.debug("Refusing to design this network");
      return null;
    }
    NetworkVO implemented = (NetworkVO) super.implement(network, offering, dest, context);

    if (network.getGateway() != null) {
      implemented.setGateway(network.getGateway());
    }

    if (network.getCidr() != null) {
      implemented.setCidr(network.getCidr());
    }
    String name = network.getName();
    if (name == null || name.isEmpty()) {
      name = ((NetworkVO) network).getUuid();
    }

    // do we need to create switch right now?

    implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);

    return implemented;
  }
  private boolean preparePxeInBasicZone(
      VirtualMachineProfile profile,
      NicProfile nic,
      DeployDestination dest,
      ReservationContext context)
      throws AgentUnavailableException, OperationTimedoutException {
    NetworkVO nwVO = _nwDao.findById(nic.getNetworkId());
    QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
    sc.and(sc.entity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString());
    sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, nwVO.getPhysicalNetworkId());
    BaremetalPxeVO pxeVo = sc.find();
    if (pxeVo == null) {
      throw new CloudRuntimeException(
          "No kickstart PXE server found in pod: "
              + dest.getPod().getId()
              + ", you need to add it before starting VM");
    }
    VMTemplateVO template = _tmpDao.findById(profile.getTemplateId());
    List<String> tuple = parseKickstartUrl(profile);

    String ks = tuple.get(0);
    String kernel = tuple.get(1);
    String initrd = tuple.get(2);

    PrepareKickstartPxeServerCommand cmd = new PrepareKickstartPxeServerCommand();
    cmd.setKsFile(ks);
    cmd.setInitrd(initrd);
    cmd.setKernel(kernel);
    cmd.setMac(nic.getMacAddress());
    cmd.setTemplateUuid(template.getUuid());
    Answer aws = _agentMgr.send(pxeVo.getHostId(), cmd);
    if (!aws.getResult()) {
      s_logger.warn(
          "Unable to set host: "
              + dest.getHost().getId()
              + " to PXE boot because "
              + aws.getDetails());
      return false;
    }

    return true;
  }
  @Override
  public Network implement(
      final Network network,
      final NetworkOffering offering,
      final DeployDestination dest,
      final ReservationContext context)
      throws InsufficientVirtualNetworkCapacityException {
    assert network.getState() == State.Implementing : "Why are we implementing " + network;

    final long dcId = dest.getDataCenter().getId();

    Long physicalNetworkId = network.getPhysicalNetworkId();

    // physical network id can be null in Guest Network in Basic zone, so locate the physical
    // network
    if (physicalNetworkId == null) {
      physicalNetworkId =
          networkModel.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType());
    }

    final NetworkVO implemented =
        new NetworkVO(
            network.getTrafficType(),
            network.getMode(),
            network.getBroadcastDomainType(),
            network.getNetworkOfferingId(),
            State.Allocated,
            network.getDataCenterId(),
            physicalNetworkId,
            offering.getRedundantRouter());

    if (network.getGateway() != null) {
      implemented.setGateway(network.getGateway());
    }

    if (network.getCidr() != null) {
      implemented.setCidr(network.getCidr());
    }

    // Name is either the given name or the uuid
    String name = network.getName();
    if (name == null || name.isEmpty()) {
      name = ((NetworkVO) network).getUuid();
    }
    if (name.length() > MAX_NAME_LENGTH) {
      name = name.substring(0, MAX_NAME_LENGTH - 1);
    }

    final List<NiciraNvpDeviceVO> devices = niciraNvpDao.listByPhysicalNetwork(physicalNetworkId);
    if (devices.isEmpty()) {
      s_logger.error("No NiciraNvp Controller on physical network " + physicalNetworkId);
      return null;
    }
    final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
    final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId());
    hostDao.loadDetails(niciraNvpHost);
    final String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid");
    final String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype");

    final CreateLogicalSwitchCommand cmd =
        new CreateLogicalSwitchCommand(
            transportzoneuuid,
            transportzoneisotype,
            name,
            context.getDomain().getName() + "-" + context.getAccount().getAccountName());
    final CreateLogicalSwitchAnswer answer =
        (CreateLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd);

    if (answer == null || !answer.getResult()) {
      s_logger.error("CreateLogicalSwitchCommand failed");
      return null;
    }

    try {
      implemented.setBroadcastUri(new URI("lswitch", answer.getLogicalSwitchUuid(), null));
      implemented.setBroadcastDomainType(BroadcastDomainType.Lswitch);
      s_logger.info(
          "Implemented OK, network linked to  = " + implemented.getBroadcastUri().toString());
    } catch (final URISyntaxException e) {
      s_logger.error(
          "Unable to store logical switch id in broadcast uri, uuid = " + implemented.getUuid(), e);
      return null;
    }

    return implemented;
  }
  @Override
  public boolean finalizeVirtualMachineProfile(
      VirtualMachineProfile<DomainRouterVO> profile,
      DeployDestination dest,
      ReservationContext context) {
    DomainRouterVO elbVm = profile.getVirtualMachine();

    List<NicProfile> elbNics = profile.getNics();
    Long guestNtwkId = null;
    for (NicProfile routerNic : elbNics) {
      if (routerNic.getTrafficType() == TrafficType.Guest) {
        guestNtwkId = routerNic.getNetworkId();
        break;
      }
    }

    NetworkVO guestNetwork = _networkDao.findById(guestNtwkId);

    DataCenter dc = dest.getDataCenter();

    StringBuilder buf = profile.getBootArgsBuilder();
    buf.append(" template=domP type=" + _systemVmType);
    buf.append(" name=").append(profile.getHostName());
    NicProfile controlNic = null;
    String defaultDns1 = null;
    String defaultDns2 = null;

    for (NicProfile nic : profile.getNics()) {
      int deviceId = nic.getDeviceId();
      buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
      buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
      if (nic.isDefaultNic()) {
        buf.append(" gateway=").append(nic.getGateway());
        defaultDns1 = nic.getDns1();
        defaultDns2 = nic.getDns2();
      }
      if (nic.getTrafficType() == TrafficType.Management) {
        buf.append(" localgw=").append(dest.getPod().getGateway());
      } else if (nic.getTrafficType() == TrafficType.Control) {
        //  control command is sent over management network in VMware
        if (dest.getHost().getHypervisorType() == HypervisorType.VMware) {
          if (s_logger.isInfoEnabled()) {
            s_logger.info(
                "Check if we need to add management server explicit route to ELB vm. pod cidr: "
                    + dest.getPod().getCidrAddress()
                    + "/"
                    + dest.getPod().getCidrSize()
                    + ", pod gateway: "
                    + dest.getPod().getGateway()
                    + ", management host: "
                    + _mgmtHost);
          }

          if (s_logger.isDebugEnabled()) {
            s_logger.debug("Added management server explicit route to ELB vm.");
          }
          // always add management explicit route, for basic networking setup
          buf.append(" mgmtcidr=").append(_mgmtCidr);
          buf.append(" localgw=").append(dest.getPod().getGateway());

          if (dc.getNetworkType() == NetworkType.Basic) {
            // ask elb vm to setup SSH on guest network
            buf.append(" sshonguest=true");
          }
        }

        controlNic = nic;
      }
    }
    String domain = guestNetwork.getNetworkDomain();
    if (domain != null) {
      buf.append(" domain=" + domain);
    }

    buf.append(" dns1=").append(defaultDns1);
    if (defaultDns2 != null) {
      buf.append(" dns2=").append(defaultDns2);
    }

    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
    }

    if (controlNic == null) {
      throw new CloudRuntimeException("Didn't start a control port");
    }

    return true;
  }
  @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;
  }