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
  public NicProfile createGuestNicProfileForVpcRouter(
      final RouterDeploymentDefinition vpcRouterDeploymentDefinition, final Network guestNetwork) {
    final NicProfile guestNic = new NicProfile();

    if (vpcRouterDeploymentDefinition.isRedundant()) {
      guestNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
    } else {
      guestNic.setIPv4Address(guestNetwork.getGateway());
    }

    guestNic.setBroadcastUri(guestNetwork.getBroadcastUri());
    guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
    guestNic.setIsolationUri(guestNetwork.getBroadcastUri());
    guestNic.setMode(guestNetwork.getMode());
    final String gatewayCidr = guestNetwork.getCidr();
    guestNic.setIPv4Netmask(NetUtils.getCidrNetmask(gatewayCidr));

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