/// <summary> /// Assigns a vlan tag to a vif. /// </summary> /// <returns>The vlan tag.</returns> /// <param name="range">Vlan tag range from which to assign the vlan</param> private int AssignVlanTag(VlanTagRange range) { int?vlanTag = Enumerable.Range(range.StartValue, range.EndValue - range.StartValue) .Except(this._vifs.Select(vif => vif.VlanTag)) .FirstOrDefault(); if (!vlanTag.HasValue) { throw new AttachmentDomainException($"Failed to allocate a free vlan tag from range '{range.Name}'. " + "Please contact your administrator to report this issue, or try another range."); } return(vlanTag.Value); }
/// <summary> /// Adds a vif to the attachment. /// </summary> /// <param name="role">Role of the vif</param> /// <param name="vlanTagRange">Vlan tag range for assignment of a vlan tag to the vif</param> /// <param name="mtu">Maximum transmission unit for the vif </param> /// <param name="contractBandwidthPool">An existing contract bandwidth pool to allocate to the vif</param> /// <param name="contractBandwidth">Contract bandwidth denoting the bandwidth requested for the vif</param> /// <param name="ipv4Addresses">Ipv4 addresses to be assigned to the layer 3 vif.</param> /// <param name="tenantId">Tenant identifier denoting the tenant for which the vif is assigned</param> /// <param name="vlanTag">Vlan tag to be assigned to the vif. It not provided one will be assigned.</param> public void AddVif(int tenantId, VifRole role, VlanTagRange vlanTagRange, Mtu mtu, ContractBandwidthPool contractBandwidthPool, AttachmentBandwidth attachmentBandwidth, ContractBandwidth contractBandwidth, List <Ipv4AddressAndMask> ipv4Addresses, bool trustReceivedCosAndDscp = false, int?vlanTag = null) { // The supplied vif role must be compatible with the attachment if (role.AttachmentRole.Id != this._attachmentRoleId) { throw new AttachmentDomainException($"Vif role '{role.Name}' is not valid for attachment '{this.Name}' "); } // Attachment must be 'tagged' in order to create a vif if (!role.AttachmentRole.IsTaggedRole) { throw new AttachmentDomainException($"A Vif cannot be created for attachment '{this.Name}' because the attachment is not enabled for tagging. "); } // Supplied attachment bandwidth must match that set for the attachment if (attachmentBandwidth.Id != this._attachmentBandwidthId) { throw new AttachmentDomainException($"Attachment bandwidth '{attachmentBandwidth.BandwidthGbps}' is not valid for attachment '{this.Name}' "); } // If a vlan tag is supplied, validate that it is in the correct range if (vlanTag.HasValue) { if (vlanTag < 2 || vlanTag > 4094) { throw new AttachmentDomainException("The vlan tag must be between 2 and 4094."); } // Validate that the supplied vlan tag is unique if (this._vifs.Select(v => v.VlanTag).Contains(vlanTag.Value)) { throw new AttachmentDomainException($"Vlan tag '{vlanTag}' is already used."); } } else { // Assign a free vlan tag from the supplied range vlanTag = AssignVlanTag(vlanTagRange); } var vlans = CreateVlans(role.AttachmentRole, ipv4Addresses); if (contractBandwidthPool == null && contractBandwidth == null) { throw new AttachmentDomainException("Either a contract bandwidth or an existing contract bandwidth pool is needed to create a vif."); } if (contractBandwidthPool != null) { // Validate the contract bandwidth pool belongs to this attachment if (!this.GetContractBandwidthPools().Contains(contractBandwidthPool)) { throw new AttachmentDomainException($"The supplied contract bandwidth pool does not exist or does not belong to " + "attachment '{this.Name}'."); } } if (contractBandwidth != null) { // Validate there is sufficient attachment bandwidth available var usedBandwidthMbps = this._vifs.Select(v => v.ContractBandwidthPool.ContractBandwidth.BandwidthMbps).Sum(); var availableBandwidthMbps = attachmentBandwidth.BandwidthGbps * 1000 - usedBandwidthMbps; if (availableBandwidthMbps < contractBandwidth.BandwidthMbps) { throw new AttachmentDomainException($"Insufficient bandwidth remaining. Attachment '{this.Name}' has '{availableBandwidthMbps}' " + "Mbps available."); } contractBandwidthPool = new ContractBandwidthPool(contractBandwidth, trustReceivedCosAndDscp, tenantId); } var vif = new Vif(this.Id, tenantId, role, mtu, vlans, vlanTag.Value, contractBandwidthPool, trustReceivedCosAndDscp); this._vifs.Add(vif); }