From e6301350d05c7d375f99f8c05c30bc9f3c446a90 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 19 May 2014 17:59:06 +0200 Subject: [PATCH] feature #2858: Hold and Release for IP/MAC addresses in all Address Ranges. Keep compatibility with 4.6 interface --- include/AddressRange.h | 9 ++++ include/AddressRangePool.h | 32 +++++++++++++- src/vnm/AddressRange.cc | 34 ++++++++++++++- src/vnm/AddressRangePool.cc | 87 +++++++++++++++++++++++++++++++++---- src/vnm/VirtualNetwork.cc | 53 ++++++++++------------ 5 files changed, 173 insertions(+), 42 deletions(-) diff --git a/include/AddressRange.h b/include/AddressRange.h index 02f0d5d151..cda667500c 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -168,6 +168,15 @@ public: */ int free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac); + /** + * Frees a previous allocated address, referenced by its IP address + * @param ot the object type of the owner of the address + * @param obid the id of the owner of the address + * @param ip the IP address in string form + * @return 0 if the address was freed + */ + int free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + /** * Return the id for this address range */ diff --git a/include/AddressRangePool.h b/include/AddressRangePool.h index bee22ba2ce..80a8497ac0 100644 --- a/include/AddressRangePool.h +++ b/include/AddressRangePool.h @@ -128,7 +128,7 @@ public: int hold_by_mac(const string& mac); /** - * Frees the given address by MAC + * Frees the given address by MAC on the given address range * @param arid the ID of the address range * @param ot the type of the object requesting the address (VM or NET) * @param obid the id of the object requesting the address @@ -137,6 +137,36 @@ public: void free_addr(unsigned int arid, PoolObjectSQL::ObjectType ot, int obid, const string& mac); + /** + * Frees the given address by IP on the given address range + * @param arid the ID of the address range + * @param ot the type of the object requesting the address (VM or NET) + * @param obid the id of the object requesting the address + * @param ip the specific IP address requested + */ + void free_addr_by_ip(unsigned int arid, PoolObjectSQL::ObjectType ot, + int obid, const string& ip); + + /** + * Frees the given address by MAC from all address ranges containing + * the MAC + * @param arid the ID of the address range + * @param ot the type of the object requesting the address (VM or NET) + * @param obid the id of the object requesting the address + * @param mac the specific MAC address requested + */ + void free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac); + + /** + * Frees the given address by IP from all address ranges containing + * the IP + * @param arid the ID of the address range + * @param ot the type of the object requesting the address (VM or NET) + * @param obid the id of the object requesting the address + * @param ip the specific IP address requested + */ + void free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + /** * Return the number of used addresses */ diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index aa3465001e..b2cf9cccf1 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -624,11 +624,13 @@ void AddressRange::allocate_addr(PoolObjectSQL::ObjectType ot, int obid, int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int addr_index) { + long long lobid = obid & 0x00000000FFFFFFFFLL; + map::iterator it; it = allocated.find(addr_index); - if (it != allocated.end() && it->second == (ot|obid)) + if (it != allocated.end() && it->second == (ot|lobid)) { allocated.erase(it); allocated_to_attr(); @@ -790,7 +792,35 @@ int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, unsigned int index = mac_i[0] - mac[0]; - if ((mac_i[0] >= mac[0]) && (index < size)) + if ((0 <= index) && (index < size)) + { + return free_addr(ot, obid, index); + } + + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, + const string& ip_s) +{ + if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + { + return -1; + } + + unsigned int ip_i; + + if (ip_to_i(ip_s, ip_i) == -1) + { + return -1; + } + + unsigned int index = ip_i - ip; + + if ((0 <= index ) && (index < size)) { return free_addr(ot, obid, index); } diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index f4a614d1de..0ffd7a9e3f 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -222,6 +222,59 @@ void AddressRangePool::free_addr(unsigned int arid, PoolObjectSQL::ObjectType ot /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRangePool::free_addr_by_ip(unsigned int arid, + PoolObjectSQL::ObjectType ot, int obid, const string& ip) +{ + map::iterator it; + + it = ar_pool.find(arid); + + if (it!=ar_pool.end()) + { + if ( it->second->free_addr_by_ip(ot, obid, ip) == 0 ) + { + used_addr--; + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void AddressRangePool::free_addr(PoolObjectSQL::ObjectType ot, int obid, + const string& mac_s) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if (it->second->free_addr(ot, obid, mac_s) == 0) + { + used_addr--; + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void AddressRangePool::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, + const string& ip_s) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if (it->second->free_addr_by_ip(ot, obid, ip_s) == 0) + { + used_addr--; + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::get_attribute(const char * name, string& value, int ar_id) const { @@ -251,7 +304,14 @@ int AddressRangePool::hold_by_ip(unsigned int ar_id, const string& ip_s) return -1; } - return it->second->hold_by_ip(ip_s); + int rc = it->second->hold_by_ip(ip_s); + + if (rc == 0) + { + used_addr++; + } + + return rc; } /* -------------------------------------------------------------------------- */ @@ -260,16 +320,18 @@ int AddressRangePool::hold_by_ip(unsigned int ar_id, const string& ip_s) int AddressRangePool::hold_by_ip(const string& ip_s) { map::iterator it; + int rc = -1; for (it=ar_pool.begin(); it!=ar_pool.end(); it++) { - if (it->second->hold_by_ip(ip_s) == 0) + if (it->second->hold_by_ip(ip_s) == 0) //At least one AR hold the IP { - return 0; + used_addr++; + rc = 0; } } - return -1; + return rc; } /* -------------------------------------------------------------------------- */ @@ -286,7 +348,14 @@ int AddressRangePool::hold_by_mac(unsigned int ar_id, const string& mac_s) return -1; } - return it->second->hold_by_mac(mac_s); + int rc = it->second->hold_by_mac(mac_s); + + if (rc == 0) + { + used_addr++; + } + + return rc; } /* -------------------------------------------------------------------------- */ @@ -295,14 +364,16 @@ int AddressRangePool::hold_by_mac(unsigned int ar_id, const string& mac_s) int AddressRangePool::hold_by_mac(const string& mac_s) { map::iterator it; + int rc = -1; for (it=ar_pool.begin(); it!=ar_pool.end(); it++) { - if (it->second->hold_by_mac(mac_s) == 0) + if (it->second->hold_by_mac(mac_s) == 0) //At least one AR hold the IP { - return 0; + used_addr++; + rc = 0; } } - return -1; + return rc; } diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index ec558f5f01..1ac5f07dbd 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -651,7 +651,7 @@ int VirtualNetwork::hold_leases(VirtualNetworkTemplate * leases_template, return -1; } - if (lease->vector_value("AR_ID", ar_id) != 0) //No AR__ID hold fist address + if (lease->vector_value("AR_ID", ar_id) != 0) //No AR_ID hold all addresses { if (!mac.empty()) { @@ -706,51 +706,42 @@ int VirtualNetwork::free_leases(VirtualNetworkTemplate * leases_template, return -1; } - int rc; - unsigned int ar_id; string ip = lease->vector_value("IP"); string mac = lease->vector_value("MAC"); - if (lease->vector_value("AR_ID", ar_id) != 0) - { - error_msg = "Missing address range ID (AR_ID)."; - return -1; - } - if (!mac.empty()) - { - rc = ar_pool.hold_by_mac(ar_id, mac); - } - else if (!ip.empty()) - { - rc = ar_pool.hold_by_ip(ar_id, ip); - } - else + if (ip.empty() && mac.empty()) { error_msg = "Missing MAC or IP."; return -1; } - if (rc!=0) + if (lease->vector_value("AR_ID", ar_id) != 0) //No AR_ID free all addresses { - error_msg = "Address is not part of the address range or in use."; + if (!mac.empty()) + { + ar_pool.free_addr(PoolObjectSQL::VM, -1, mac); + } + else if (!ip.empty()) + { + ar_pool.free_addr_by_ip(PoolObjectSQL::VM, -1, ip); + } + } + else + { + if (!mac.empty()) + { + ar_pool.free_addr(ar_id, PoolObjectSQL::VM, -1, mac); + } + else if (!ip.empty()) + { + ar_pool.free_addr_by_ip(ar_id, PoolObjectSQL::VM, -1, ip); + } } - return rc; - - - - vector vector_leases; - - leases_template->get("LEASES", vector_leases); - - - - //TODO return 0; - //return leases->free_leases(vector_leases, error_msg); } /* -------------------------------------------------------------------------- */