diff --git a/include/AddressRange.h b/include/AddressRange.h index 34096db7cd..8e46fb1b4c 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -35,8 +35,6 @@ class AddressRange { public: - AddressRange(unsigned int _id):id(_id),next(0),used_addr(0){}; - virtual ~AddressRange(){}; // ************************************************************************* @@ -103,8 +101,12 @@ public: * SIZE = 1024, * ULA_PREFIX = "fd00:0:0:1::", * GLOBAL_PREFIX = "2001::"] + * + * NOTE: This function is part of the AddressRange interface. The AR + * implementation may contact an external IPAM to complete or validate + * the AR allocation request. */ - int from_vattr(VectorAttribute * attr, string& error_msg); + virtual int from_vattr(VectorAttribute * attr, string& error_msg) = 0; /** * Builds an Address Range from a vector attribute stored in the DB @@ -276,7 +278,7 @@ public: */ unsigned int get_used_addr() const { - return used_addr; + return allocated.size(); } /** @@ -284,7 +286,7 @@ public: */ unsigned int get_free_addr() const { - return size - used_addr; + return size - allocated.size(); } /** @@ -330,6 +332,11 @@ public: bool keep_restricted, string& error_msg); + /** + * Helper function to initialize restricte attributes of an AddressRange + */ + static void set_restricted_attributes(vector& ras); + /** * Get the security groups for this AR. * @return a reference to the security group set @@ -345,7 +352,64 @@ public: */ friend int AddressRangePool::add_ar(AddressRange * ar); - static void set_restricted_attributes(vector& rattrs); +protected: + /** + * Base constructor it cannot be called directly but from the + * AddressRange factory constructor. + */ + AddressRange(unsigned int _id):id(_id){}; + + /** + * Builds the AddressRange from its vector attribute representation + */ + int from_attr(VectorAttribute * attr, string& error_msg); + + /* ---------------------------------------------------------------------- */ + /* Implementation specific address management interface */ + /* ---------------------------------------------------------------------- */ + /** + * Sets the given range of addresses (by index) as used + * @param index the first address to set as used + * @param sz number of addresses to set + * @param msg describing the error if any + * + * @return 0 if success + */ + virtual int allocate_addr(unsigned int index, unsigned int sz, string& msg) = 0; + /** + * Gets a range of free addresses + * @param index the first address in the range + * @param size number of addresses requested in the range + * @param msg describing the error if any + * + * @return 0 if success + */ + virtual int get_addr(unsigned int& index, unsigned int sz, string& msg) = 0; + + /** + * Sets the given address (by index) as free + * @param index of the address + * @param msg describing the error if any + * + * @return 0 if success + */ + virtual int free_addr(unsigned int index, string& msg) = 0; + + /* ---------------------------------------------------------------------- */ + /* Allocated addresses */ + /* ---------------------------------------------------------------------- */ + /** + * Map to store the allocated address indexed by the address index relative + * to the mac/ip values. It contains also the type and id of the object + * owning the address. + * + * +--------------------+--------------------+ + * index ----> | ObjectType(32bits) | Object ID (32bits) | + * +--------------------+--------------------+ + * + * Address = First Address + index + */ + map allocated; private: /* ---------------------------------------------------------------------- */ @@ -399,6 +463,34 @@ private: /* ---------------------------------------------------------------------- */ /* NIC setup functions */ /* ---------------------------------------------------------------------- */ + + /** + * Check if the given MAC is valid for this address range by verifying: + * - Correct : notation + * - Part of the AR + * + * @param index of the MAC in the AR + * @param mac_s string representation of the MAC in : notation + * @param check_free apart from previous checks + * + * @return true if the MAC is valid + */ + bool is_valid_mac(unsigned int& index, const string& mac_s, bool check_free); + + /** + * Check if the given IP is valid for this address range by verifying: + * - AR is of type IP4 or IP4_6 + * - Correct . notation + * - Part of the AR + * + * @param index of the IP in the AR + * @param ip_s string representation of the IP in . notation + * @param check_free apart from previous checks + * + * @return true if the IP is valid + */ + bool is_valid_ip(unsigned int& index, const string& ip_s, bool check_free); + /** * Writes MAC address to the given NIC attribute * @param addr_index internal index for the lease @@ -450,13 +542,29 @@ private: /** * Adds a new allocated address to the map. Updates the ALLOCATED attribute */ - void allocate_addr(PoolObjectSQL::ObjectType ot, int obid, + void set_allocated_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int addr_index); + /** + * Sets the address lease as used and fills a NIC attribute with the + * configuration parameters from the address range. + * @param index of the lease in the address range + * @param ot the type of the object allocating the address + * @param obid the id of the object + * @param nic the VM NIC attribute + * @param inherit attributes to be added to the NIC attribute + * @return 0 if success + */ + void allocate_by_index(unsigned int index, + PoolObjectSQL::ObjectType ot, + int obid, + VectorAttribute* nic, + const vector& inherit); + /** * Frees an address from the map. Updates the ALLOCATED attribute */ - int free_addr(PoolObjectSQL::ObjectType ot, int obid, + int free_allocated_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int addr_index); /** @@ -528,26 +636,17 @@ private: */ set security_groups; + /** + * The name of the IPAM driver (internal for OpenNebula built-in) + */ + string ipam_mad; + /** * The Address Range attributes as a Template VectorAttribute. This is * used to generate XML or a template representation of the AR. */ VectorAttribute * attr; - /* ---------------------------------------------------------------------- */ - /* Allocated address & control */ - /* ---------------------------------------------------------------------- */ - /** - * Map to store the allocated address indexed by the address index relative - * to the mac/ip values. It contains also the type and id of the object - * owning the address ObjectType(32bits) | Object ID (32) - */ - map allocated; - - unsigned int next; - - unsigned int used_addr; - /* ---------------------------------------------------------------------- */ /* Restricted Attributes */ /* ---------------------------------------------------------------------- */ diff --git a/include/AddressRangeIPAM.h b/include/AddressRangeIPAM.h new file mode 100644 index 0000000000..6dbee8d028 --- /dev/null +++ b/include/AddressRangeIPAM.h @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef ADDRESS_RANGE_IPAM_H_ +#define ADDRESS_RANGE_IPAM_H_ + +#include + +#include "AddressRange.h" +#include "AddressRangePool.h" + +class VectorAttribute; + +class AddressRangeIPAM : public AddressRange +{ +public: + AddressRangeIPAM(unsigned int _id):AddressRange(_id){}; + + virtual ~AddressRangeIPAM(){}; + + /* ---------------------------------------------------------------------- */ + /* AddressRange Interface **TODO contact IPAM** */ + /* ---------------------------------------------------------------------- */ + int from_vattr(VectorAttribute * attr, std::string& error_msg) + { + error_msg = "Not Implemented"; + return -1; + }; + + int allocate_addr(unsigned int index, unsigned int size, string& error_msg) + { + error_msg = "Not Implemented"; + return -1; + }; + + int get_addr(unsigned int& index, unsigned int rsize, string& error_msg) + { + error_msg = "Not Implemented"; + return -1; + }; + + int free_addr(unsigned int index, string& error_msg) + { + error_msg = "Not Implemented"; + return -1; + }; +}; + +#endif diff --git a/include/AddressRangeInternal.h b/include/AddressRangeInternal.h new file mode 100644 index 0000000000..fae392e472 --- /dev/null +++ b/include/AddressRangeInternal.h @@ -0,0 +1,116 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef ADDRESS_RANGE_INTERNAL_H_ +#define ADDRESS_RANGE_INTERNAL_H_ + +#include + +#include "AddressRange.h" +#include "AddressRangePool.h" + +class VectorAttribute; + +class AddressRangeInternal : public AddressRange +{ +public: + AddressRangeInternal(unsigned int _id):AddressRange(_id), next(0){}; + + virtual ~AddressRangeInternal(){}; + + /* ---------------------------------------------------------------------- */ + /* AddressRange Interface */ + /* ---------------------------------------------------------------------- */ + + /** + * Init an Address Range based on a vector attribute. + * @param attr the description of the AddressRange + * @param error_msg description if error + * @return 0 on success + */ + int from_vattr(VectorAttribute * attr, std::string& error_msg) + { + return AddressRange::from_attr(attr, error_msg); + } + + /** + * Sets the given range of addresses (by index) as used + * @param index the first address to set as used + * @param sz number of addresses to set + * @param msg describing the error if any + * + * @return 0 if success + */ + int allocate_addr(unsigned int index, unsigned int size, string& error_msg) + { + return 0; + } + + /** + * Gets a range of free addresses + * @param index the first address in the range + * @param size number of addresses requested in the range + * @param msg describing the error if any + * + * @return 0 if success + */ + int get_addr(unsigned int& index, unsigned int rsize, string& error_msg) + { + if ( rsize == 1 ) + { + return get_single_addr(index, error_msg); + } + + return get_range_addr(index, rsize, error_msg); + } + + /** + * Sets the given address (by index) as free + * @param index of the address + * @param msg describing the error if any + * + * @return 0 if success + */ + int free_addr(unsigned int index, string& msg) + { + return 0; + }; + +private: + /** + * Lookup index for the next free address lease + */ + unsigned int next; + + /** + * Get a free lease + * @param index of the free lease, undefined if error + * @param msg with error description if any + * @return 0 on success -1 otherwise + */ + int get_single_addr(unsigned int& index, std::string& msg); + + /** + * Get a free and continuous range of leases + * @param index of the first free lease in range, undefined if error + * @param sz of the range + * @param msg with error description if any + * @return 0 on success -1 otherwise + */ + int get_range_addr(unsigned int& index, unsigned int sz, std::string& msg); +}; + +#endif diff --git a/include/AddressRangePool.h b/include/AddressRangePool.h index 38550d832d..b9335df0da 100644 --- a/include/AddressRangePool.h +++ b/include/AddressRangePool.h @@ -82,14 +82,16 @@ public: * the reason. * @return 0 on success */ - int update_ar(vector ars, bool keep_restricted, string& error_msg); - + int update_ar(vector ars, bool keep_restricted, + string& error_msg); /** * Allocates a new *empty* address range. It is not added to the pool as it * needs to be initialized. Only the AR_ID is set. + * @param ipam_mad sets the type of AddressRange to be created: internal, + * IPAM... * @return the new address range. */ - AddressRange * allocate_ar(); + AddressRange * allocate_ar(const string& ipam_mad); /** * Adds a new address range to the pool. It should be allocated by the @@ -369,6 +371,16 @@ private: * Used addresses */ unsigned int used_addr; + + /** + * Allocates a new *empty* address range. It is not added to the pool as it + * needs to be initialized. + * @param ipam_mad sets the type of AddressRange to be created: internal, + * IPAM... + * @param ar_id for the AddressRange + * @return the new address range. + */ + AddressRange * allocate_ar(const string& ipam_mad, unsigned int ar_id); }; #endif diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 8f7b511f54..03e9ea9512 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -158,9 +158,9 @@ public: * ar_pool * @return pointer to the new address range */ - AddressRange * allocate_ar() + AddressRange * allocate_ar(const string& ipam_mad) { - return ar_pool.allocate_ar(); + return ar_pool.allocate_ar(ipam_mad); } /** diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index ce955264ea..6fd05ec7ac 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -70,7 +70,7 @@ AddressRange::AddressType AddressRange::str_to_type(string& str_type) /* ************************************************************************** */ /* ************************************************************************** */ -int AddressRange::from_vattr(VectorAttribute *vattr, string& error_msg) +int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg) { string value; @@ -293,8 +293,6 @@ int AddressRange::update_attributes( return -1; } - - next = 0; } else { @@ -461,7 +459,7 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, } } - oss << "" << used_addr << ""; + oss << "" << get_used_addr() << ""; if (allocated.empty()) { @@ -749,6 +747,67 @@ int AddressRange::ip6_to_s(const unsigned int prefix[], const unsigned int mac[] /* ************************************************************************** */ /* ************************************************************************** */ +bool AddressRange::is_valid_mac(unsigned int& index, const string& mac_s, + bool check_free) +{ + unsigned int mac_i[2]; + + if (mac_to_i(mac_s, mac_i) == -1) + { + return false; + } + + if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0])) + { + return false; + } + + index = mac_i[0] - mac[0]; + + if ((check_free && allocated.count(index) != 0) || (index >= size)) + { + return false; + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool AddressRange::is_valid_ip(unsigned int& index, const string& ip_s, + bool check_free) +{ + if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + { + return false; + } + + unsigned int ip_i; + + if (ip_to_i(ip_s, ip_i) == -1) + { + return false; + } + + if (ip_i < ip) + { + return false; + } + + index = ip_i - ip; + + if ((check_free && allocated.count(index) != 0) || (index >= size)) + { + return false; + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRange::set_mac(unsigned int addr_index, VectorAttribute * nic) const { unsigned int new_mac[2]; @@ -895,11 +954,9 @@ int AddressRange::attr_to_allocated(const string& allocated_s) } allocated.insert(make_pair(addr_index,object_pack)); - - used_addr++; } - if ( used_addr > size ) + if ( get_used_addr() > size ) { return -1; } @@ -909,21 +966,19 @@ int AddressRange::attr_to_allocated(const string& allocated_s) /* -------------------------------------------------------------------------- */ -void AddressRange::allocate_addr(PoolObjectSQL::ObjectType ot, int obid, +void AddressRange::set_allocated_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int addr_index) { long long lobid = obid & 0x00000000FFFFFFFFLL; allocated.insert(make_pair(addr_index,ot|lobid)); - used_addr++; - allocated_to_attr(); } /* -------------------------------------------------------------------------- */ -int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, +int AddressRange::free_allocated_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int addr_index) { long long lobid = obid & 0x00000000FFFFFFFFLL; @@ -937,8 +992,6 @@ int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, allocated.erase(it); allocated_to_attr(); - used_addr--; - return 0; } @@ -948,73 +1001,12 @@ int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, /* ************************************************************************** */ /* ************************************************************************** */ -int AddressRange::allocate_addr( +void AddressRange::allocate_by_index(unsigned int index, PoolObjectSQL::ObjectType ot, int obid, VectorAttribute* nic, const vector& inherit) { - if ( used_addr >= size ) - { - return -1; - } - - for ( unsigned int i=0; i& inherit) -{ - unsigned int mac_i[2]; - - if (mac_to_i(mac_s, mac_i) == -1) - { - return -1; - } - - if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0])) - { - return -1; - } - - unsigned int index = mac_i[0] - mac[0]; - - if ((allocated.count(index) != 0) || (index >= size)) - { - return -1; - } - set_mac(index, nic); if (type & 0x00000002 ) @@ -1029,7 +1021,60 @@ int AddressRange::allocate_by_mac( set_vnet(nic, inherit); - allocate_addr(ot, obid, index); + set_allocated_addr(ot, obid, index); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRange::allocate_addr( + PoolObjectSQL::ObjectType ot, + int obid, + VectorAttribute* nic, + const vector& inherit) +{ + unsigned int index; + string error_msg; + + if ( get_used_addr() >= size ) + { + return -1; + } + + if ( get_addr(index, 1, error_msg) != 0 ) + { + return -1; + } + + allocate_by_index(index, ot, obid, nic, inherit); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRange::allocate_by_mac( + const string& mac_s, + PoolObjectSQL::ObjectType ot, + int obid, + VectorAttribute* nic, + const vector& inherit) +{ + string error_msg; + unsigned int index; + + if (!is_valid_mac(index, mac_s, true)) + { + return -1; + } + + if (allocate_addr(index, 1, error_msg) != 0) + { + return -1; + } + + allocate_by_index(index, ot, obid, nic, inherit); return 0; } @@ -1044,45 +1089,20 @@ int AddressRange::allocate_by_ip( VectorAttribute* nic, const vector& inherit) { - if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + string error_msg; + unsigned int index; + + if (!is_valid_ip(index, ip_s, true)) { return -1; } - unsigned int ip_i; - - if (ip_to_i(ip_s, ip_i) == -1) + if (allocate_addr(index, 1, error_msg) != 0) { return -1; } - if (ip_i < ip) - { - return -1; - } - - unsigned int index = ip_i - ip; - - if (allocated.count(index) != 0 || index >= size ) - { - return -1; - } - - set_mac(index, nic); - - if (type & 0x00000002 ) - { - set_ip(index, nic); - } - - if (type & 0x00000004) - { - set_ip6(index, nic); - } - - set_vnet(nic, inherit); - - allocate_addr(ot, obid, index); + allocate_by_index(index, ot, obid, nic, inherit); return 0; } @@ -1093,18 +1113,24 @@ int AddressRange::allocate_by_ip( int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac_s) { + string error_msg; unsigned int mac_i[2]; mac_to_i(mac_s, mac_i); unsigned int index = mac_i[0] - mac[0]; - if ( index < 0) + if (index < 0 || index >= size) { return -1; } - return free_addr(ot, obid, index); + if (free_addr(index, error_msg) != 0) + { + return -1; + } + + return free_allocated_addr(ot, obid, index); } /* -------------------------------------------------------------------------- */ @@ -1113,6 +1139,8 @@ int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, const string& ip_s) { + string error_msg; + if (!(type & 0x00000002))//Not of type IP4 or IP4_6 { return -1; @@ -1127,12 +1155,17 @@ int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, unsigned int index = ip_i - ip; - if ((0 <= index ) && (index < size)) + if (index < 0 || index >= size) { - return free_addr(ot, obid, index); + return -1; } - return -1; + if (free_addr(index, error_msg) != 0) + { + return -1; + } + + return free_allocated_addr(ot, obid, index); } /* -------------------------------------------------------------------------- */ @@ -1146,16 +1179,16 @@ int AddressRange::free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid) int freed = 0; + string error_msg; + while (it != allocated.end()) { - if (it->second == obj_pack) + if (it->second == obj_pack && free_addr(it->first, error_msg) == 0) { map::iterator prev_it = it++; allocated.erase(prev_it); - used_addr--; - freed++; } else @@ -1183,6 +1216,8 @@ int AddressRange::free_addr_by_range(PoolObjectSQL::ObjectType ot, int obid, unsigned int index = mac_i[0] - mac[0]; + string error_msg; + if ((0 <= index) && (index < size)) { map::iterator it = allocated.find(index); @@ -1196,14 +1231,13 @@ int AddressRange::free_addr_by_range(PoolObjectSQL::ObjectType ot, int obid, for (unsigned int i=0; isecond == obj_pack) + if (it != allocated.end() && it->second == obj_pack && + free_addr(it->first, error_msg) == 0) { map::iterator prev_it = it++; allocated.erase(prev_it); - used_addr--; - freed++; } else @@ -1248,31 +1282,20 @@ void AddressRange::process_security_rule(VectorAttribute * rule) int AddressRange::hold_by_ip(const string& ip_s) { - if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + string error_msg; + unsigned int index; + + if (!is_valid_ip(index, ip_s, true)) { return -1; } - unsigned int ip_i; - - if (ip_to_i(ip_s, ip_i) == -1) + if (allocate_addr(index, 1, error_msg) != 0) { return -1; } - if (ip_i < ip) - { - return -1; - } - - unsigned int index = ip_i - ip; - - if (allocated.count(index) != 0 || index >= size ) - { - return -1; - } - - allocate_addr(PoolObjectSQL::VM, -1, index); + set_allocated_addr(PoolObjectSQL::VM, -1, index); return 0; } @@ -1282,26 +1305,20 @@ int AddressRange::hold_by_ip(const string& ip_s) int AddressRange::hold_by_mac(const string& mac_s) { - unsigned int mac_i[2]; + unsigned int index; + string error_msg; - if (mac_to_i(mac_s, mac_i) == -1) + if (!is_valid_mac(index, mac_s, true)) { return -1; } - if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0])) + if (allocate_addr(index, 1, error_msg) != 0) { return -1; } - unsigned int index = mac_i[0] - mac[0]; - - if ((allocated.count(index) != 0) || (index >= size)) - { - return -1; - } - - allocate_addr(PoolObjectSQL::VM, -1, index); + set_allocated_addr(PoolObjectSQL::VM, -1, index); return 0; } @@ -1312,51 +1329,21 @@ int AddressRange::hold_by_mac(const string& mac_s) int AddressRange::reserve_addr(int vid, unsigned int rsize, AddressRange *rar) { unsigned int first_index; + string error_msg; - if (rsize > (size - used_addr)) + if (rsize > get_free_addr()) { - return -1; //reservation dosen't fit + return -1; } - // --------------- Look for a continuos range of addresses ----------------- - - bool valid = true; - - for (unsigned int i=0; i= size ) - { - valid = false; - break; - } - } - - if (valid == true) - { - i -= rsize; - first_index = i; - - for (unsigned int j=0; jclone(); @@ -1384,6 +1371,8 @@ int AddressRange::reserve_addr(int vid, unsigned int rsize, AddressRange *rar) int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize, unsigned int sindex, AddressRange *rar) { + string error_msg; + /* ----------------- Allocate the new AR from sindex -------------------- */ for (unsigned int j=sindex; j< (sindex+rsize) ; j++) @@ -1394,9 +1383,14 @@ int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize, } } + if (allocate_addr(sindex, rsize, error_msg) != 0) + { + return -1; + } + for (unsigned int j=sindex; j< (sindex+rsize); j++) { - allocate_addr(PoolObjectSQL::NET, vid, j); + set_allocated_addr(PoolObjectSQL::NET, vid, j); } /* ------------------------- Initialize the new AR ---------------------- */ @@ -1426,26 +1420,9 @@ int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize, int AddressRange::reserve_addr_by_ip(int vid, unsigned int rsize, const string& ip_s, AddressRange *rar) { - if (!(type & 0x00000002))//Not of type IP4 or IP4_6 - { - return -1; - } + unsigned int sindex; - unsigned int ip_i; - - if (ip_to_i(ip_s, ip_i) == -1) - { - return -1; - } - - if (ip_i < ip) - { - return -1; - } - - unsigned int sindex = ip_i - ip; - - if (sindex >= size ) + if (!is_valid_ip(sindex, ip_s, false)) { return -1; } @@ -1459,21 +1436,9 @@ int AddressRange::reserve_addr_by_ip(int vid, unsigned int rsize, int AddressRange::reserve_addr_by_mac(int vid, unsigned int rsize, const string& mac_s, AddressRange *rar) { - unsigned int mac_i[2]; + unsigned int sindex; - if (mac_to_i(mac_s, mac_i) == -1) - { - return -1; - } - - if ((mac_i[1] != mac[1]) || (mac_i[0] < mac[0])) - { - return -1; - } - - unsigned int sindex = mac_i[0] - mac[0]; - - if (sindex >= size) + if (!is_valid_mac(sindex, mac_s, false)) { return -1; } diff --git a/src/vnm/AddressRangeInternal.cc b/src/vnm/AddressRangeInternal.cc new file mode 100644 index 0000000000..6c3398332d --- /dev/null +++ b/src/vnm/AddressRangeInternal.cc @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "AddressRangeInternal.h" + +int AddressRangeInternal::get_single_addr(unsigned int& index, std::string& msg) +{ + unsigned int ar_size = get_size(); + + for ( unsigned int i=0; i= ar_size ) + { + valid = false; + break; + } + } + + if (valid == true) + { + index = i - rsize; + return 0; + } + } + + msg = "There isn't a continuous range big enough"; + return -1; +} + diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index c2b1efcc25..b0801196ec 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -16,6 +16,8 @@ #include "AddressRangePool.h" #include "AddressRange.h" +#include "AddressRangeInternal.h" +#include "AddressRangeIPAM.h" using namespace std; @@ -37,15 +39,17 @@ AddressRangePool::~AddressRangePool() int AddressRangePool::from_vattr(VectorAttribute* va, string& error_msg) { - AddressRange * ar = new AddressRange(next_ar); + AddressRange * ar = allocate_ar(va->vector_value("IPAM_MAD")); if (ar->from_vattr(va, error_msg) != 0) { + next_ar = next_ar - 1; delete ar; + return -1; } - ar_pool.insert(make_pair(next_ar++, ar)); + ar_pool.insert(make_pair(ar->ar_id(), ar)); ar_template.set(va); @@ -55,9 +59,24 @@ int AddressRangePool::from_vattr(VectorAttribute* va, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -AddressRange * AddressRangePool::allocate_ar() +AddressRange * AddressRangePool::allocate_ar(const string& ipam_mad) { - return new AddressRange(next_ar++); + return allocate_ar(ipam_mad, next_ar++); +} + +/* -------------------------------------------------------------------------- */ + +AddressRange * AddressRangePool::allocate_ar(const string& ipam_mad, + unsigned int na) +{ + if ( ipam_mad.empty() || ipam_mad == "internal" ) + { + return new AddressRangeInternal(na); + } + else + { + return new AddressRangeIPAM(na); + } } /* -------------------------------------------------------------------------- */ @@ -134,9 +153,9 @@ int AddressRangePool::from_xml_node(const xmlNodePtr node) for (int i = 0; i < num_ar; i++) { - AddressRange * ar = new AddressRange(0); + AddressRange * ar = allocate_ar((var[i])->vector_value("IPAM_MAD"), 0); - if (ar->from_vattr_db(var[i])!= 0) + if (ar->from_vattr_db(var[i]) != 0) { return -1; } diff --git a/src/vnm/SConstruct b/src/vnm/SConstruct index e2c141ec11..000eacbb98 100644 --- a/src/vnm/SConstruct +++ b/src/vnm/SConstruct @@ -25,6 +25,7 @@ source_files=[ 'VirtualNetwork.cc', 'VirtualNetworkPool.cc', 'AddressRange.cc', + 'AddressRangeInternal.cc', 'AddressRangePool.cc', 'VirtualNetworkTemplate.cc' ] diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 72e1aaa18d..f0029a92d0 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -498,7 +498,7 @@ AddressRange * VirtualNetworkPool::allocate_ar(int rid, string &err) return 0; } - AddressRange *ar = rvn->allocate_ar(); + AddressRange *ar = rvn->allocate_ar("internal"); update(rvn);