From 83e82830c8fa6951e21f5f2d7fd8270d8dc55e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Fri, 25 Nov 2011 10:02:17 -0800 Subject: [PATCH 01/15] Feature #602: Refactor Ranged VNets to store first and last IP of the range --- include/FixedLeases.h | 8 +--- include/Leases.h | 25 ++++++----- include/RangedLeases.h | 14 ++---- include/VirtualNetwork.h | 3 ++ src/vnm/FixedLeases.cc | 2 +- src/vnm/RangedLeases.cc | 29 ++++-------- src/vnm/VirtualNetwork.cc | 92 ++++++++++++++++++++++----------------- 7 files changed, 83 insertions(+), 90 deletions(-) diff --git a/include/FixedLeases.h b/include/FixedLeases.h index 399afb02d7..d194a8130c 100644 --- a/include/FixedLeases.h +++ b/include/FixedLeases.h @@ -44,8 +44,7 @@ public: FixedLeases(SqlDB * db, int _oid, unsigned int _mac_prefix): - Leases(db,_oid,0), - mac_prefix(_mac_prefix), + Leases(db,_oid,0,_mac_prefix), current(leases.begin()){}; ~FixedLeases(){}; @@ -112,11 +111,6 @@ public: private: - /** - * The default MAC prefix for the Leases - */ - unsigned int mac_prefix; - /** * Current lease pointer */ diff --git a/include/Leases.h b/include/Leases.h index ef38c2c13b..5927f36f14 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -40,7 +40,7 @@ public: * @param _oid the virtual network unique identifier * @param _size the max number of leases */ - Leases(SqlDB * _db, int _oid, unsigned long _size): + Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix): ObjectSQL(), oid(_oid), size(_size), n_used(0), db(_db){}; @@ -230,13 +230,13 @@ protected: // Leases fields // ------------------------------------------------------------------------- /** - * Leases indentifier. Connects it to a Virtual Network - */ + * Leases identifier. Connects it to a Virtual Network + */ int oid; /** - * Number of possible leases (free + asigned) - */ + * Number of possible leases (free + assigned) + */ unsigned int size; /** @@ -249,6 +249,11 @@ protected: */ int n_used; + /** + * The default MAC prefix for the Leases + */ + unsigned int mac_prefix; + // ------------------------------------------------------------------------- // DataBase implementation variables // ------------------------------------------------------------------------- @@ -286,11 +291,11 @@ protected: friend ostream& operator<<(ostream& os, Lease& _lease); /** - * Function to print the Leases object into a string in - * XML format - * @param xml the resulting XML string - * @return a reference to the generated string - */ + * Function to print the Leases object into a string in + * XML format + * @param xml the resulting XML string + * @return a reference to the generated string + */ string& to_xml(string& xml) const; private: diff --git a/include/RangedLeases.h b/include/RangedLeases.h index 946db6f349..4f97acb821 100644 --- a/include/RangedLeases.h +++ b/include/RangedLeases.h @@ -30,9 +30,9 @@ public: // ************************************************************************* RangedLeases(SqlDB * db, int _oid, - unsigned long _size, unsigned int _mac_prefix, - const string& _network_address); + unsigned int _ip_start, + unsigned int _ip_end); ~RangedLeases(){}; @@ -105,15 +105,9 @@ public: } private: - /** - * The default MAC prefix for the Leases - */ - unsigned int mac_prefix; - /** - * The Network address to generate leases - */ - unsigned int network_address; + unsigned int ip_start; + unsigned int ip_end; unsigned int current; diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index be02e86954..9146d69f97 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -222,6 +222,9 @@ private: */ Leases * leases; + unsigned int ip_start; + unsigned int ip_end; + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/src/vnm/FixedLeases.cc b/src/vnm/FixedLeases.cc index 83180c2a92..fc14480c74 100644 --- a/src/vnm/FixedLeases.cc +++ b/src/vnm/FixedLeases.cc @@ -25,7 +25,7 @@ FixedLeases::FixedLeases( int _oid, unsigned int _mac_prefix, vector<const Attribute*>& vector_leases): - Leases(db,_oid,0),mac_prefix(_mac_prefix),current(leases.begin()) + Leases(db,_oid,0,_mac_prefix),current(leases.begin()) { const VectorAttribute * single_attr_lease; string _mac; diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index d74f599e17..c94d59118b 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -17,7 +17,6 @@ #include "RangedLeases.h" #include "Nebula.h" -#include <cmath> /* ************************************************************************** */ /* Ranged Leases class */ @@ -26,21 +25,13 @@ RangedLeases::RangedLeases( SqlDB * db, int _oid, - unsigned long _size, unsigned int _mac_prefix, - const string& _network_address): - Leases(db,_oid,_size),mac_prefix(_mac_prefix),current(0) + unsigned int _ip_start, + unsigned int _ip_end): + Leases(db,_oid,0,_mac_prefix), + ip_start(_ip_start),ip_end(_ip_end),current(0) { - unsigned int net_addr; - - Leases::Lease::ip_to_number(_network_address,net_addr); - - //size is the number of hosts in the network - size = _size + 2; - - network_address = 0xFFFFFFFF << (int) ceil(log(size)/log(2)); - - network_address &= net_addr; + size = ip_end - ip_start + 1; } /* ************************************************************************** */ @@ -52,9 +43,9 @@ int RangedLeases::get(int vid, string& ip, string& mac) unsigned int num_ip; int rc = -1; - for (unsigned int i=0; i<size; i++, current++) + for ( unsigned int i=0; i<size; i++, current = (current+1)%size ) { - num_ip = network_address + (current%(size-2)) + 1; + num_ip = ip_start + current; if (check(num_ip) == false) { @@ -85,7 +76,6 @@ int RangedLeases::set(int vid, const string& ip, string& mac) { unsigned int num_ip; unsigned int num_mac[2]; - unsigned int net; int rc; rc = Leases::Lease::ip_to_number(ip,num_ip); @@ -95,10 +85,7 @@ int RangedLeases::set(int vid, const string& ip, string& mac) return -1; } - net = 0xFFFFFFFF << (int) ceil(log(size)/log(2)); - net &= num_ip; - - if ( net != network_address ) + if ( num_ip < ip_start || ip_end < num_ip ) { return -1; } diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 520ba533b5..c3c125cbbb 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -25,6 +25,8 @@ #include "AuthManager.h" +#include <cmath> + /* ************************************************************************** */ /* Virtual Network :: Constructor/Destructor */ /* ************************************************************************** */ @@ -119,49 +121,16 @@ int VirtualNetwork::select_leases(SqlDB * db) string network_address; - unsigned int default_size = VirtualNetworkPool::default_size(); unsigned int mac_prefix = VirtualNetworkPool::mac_prefix(); //Get the leases if (type == RANGED) { - string nclass = ""; - int size = 0; - - // retrieve specific information from the template - get_template_attribute("NETWORK_ADDRESS",network_address); - - if (network_address.empty()) - { - goto error_addr; - } - - get_template_attribute("NETWORK_SIZE",nclass); - - if ( nclass == "B" || nclass == "b" ) - { - size = 65534; - } - else if ( nclass == "C" || nclass == "c" ) - { - size = 254; - } - else if (!nclass.empty()) //Assume it's a number - { - istringstream iss(nclass); - iss >> size; - } - - if (size == 0) - { - size = default_size; - } - leases = new RangedLeases(db, oid, - size, mac_prefix, - network_address); + ip_start, + ip_end); } else if(type == FIXED) { @@ -190,9 +159,6 @@ error_type: ose << "Wrong type of Virtual Network: " << type; goto error_common; -error_addr: - ose << "Network address is not defined nid: " << oid; - error_common: NebulaLog::log("VNM", Log::ERROR, ose); return -1; @@ -292,6 +258,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) string nclass = ""; string naddr = ""; int size = 0; + unsigned int net_addr; // retrieve specific information from template get_template_attribute("NETWORK_ADDRESS",naddr); @@ -311,7 +278,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) { size = 254; } - else if (!nclass.empty())//Assume its a number + else if (!nclass.empty())//Assume it's a number { istringstream iss(nclass); @@ -323,11 +290,26 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) size = default_size; } + Leases::Lease::ip_to_number(naddr,net_addr); + + int shift; + shift = (int) ceil(log(size+2)/log(2)); + size = (1 << shift) - 2; + unsigned int network_mask = 0xFFFFFFFF << shift; + + if (net_addr != (network_mask & net_addr) ) + { + // TODO: net_addr is not a valid network address, should end with 0s + } + + ip_start = net_addr + 1; + ip_end = ip_start + size -1; + leases = new RangedLeases(db, oid, - size, mac_prefix, - naddr); + ip_start, + ip_end); } else // VirtualNetwork::FIXED { @@ -527,6 +509,21 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const os << "<VLAN_ID>" << vlan_id << "</VLAN_ID>"; } + if ( type == RANGED ) + { + string st_ip_start; + string st_ip_end; + + Leases::Lease::ip_to_string(ip_start, st_ip_start); + Leases::Lease::ip_to_string(ip_end, st_ip_end); + + os << + "<RANGE>" << + "<IP_START>" << st_ip_start << "</IP_START>" << + "<IP_END>" << st_ip_end << "</IP_END>" << + "</RANGE>"; + } + os << "<PUBLIC>" << public_obj << "</PUBLIC>" << "<TOTAL_LEASES>"<< total_leases << "</TOTAL_LEASES>"<< obj_template->to_xml(template_xml); @@ -585,6 +582,19 @@ int VirtualNetwork::from_xml(const string &xml_str) ObjectXML::free_nodes(content); + // Ranged Leases + if (type == RANGED) + { + string st_ip_start; + string st_ip_end; + + rc += xpath(st_ip_start, "/VNET/RANGE/IP_START", "0"); + rc += xpath(st_ip_end, "/VNET/RANGE/IP_END", "0"); + + Leases::Lease::ip_to_number(st_ip_start, ip_start); + Leases::Lease::ip_to_number(st_ip_end, ip_end); + } + if (rc != 0) { return -1; From e894fb5d373508c789866075a9b697e9c2ae7600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Mon, 28 Nov 2011 16:30:08 +0100 Subject: [PATCH 02/15] Feature #602: Make Network size definition more flexible. The netmask is generated from the given size The Network size can be defined as: * NETWORK_ADDRESS attribute: 19.2168.30.0/24 * SIZE: Letter (a,b,c) or number of hosts * NETWORK_MASK: 255.255.255.0 creates a network of 254 hosts --- src/vnm/VirtualNetwork.cc | 115 +++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index c3c125cbbb..899154538d 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -255,53 +255,114 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) //-------------------------------------------------------------------------- if (type == VirtualNetwork::RANGED) { - string nclass = ""; - string naddr = ""; - int size = 0; + string st_size = ""; + string st_addr = ""; + string st_mask = ""; + + unsigned int size = default_size; + unsigned int host_bits; + unsigned int network_bits; + unsigned int net_addr; + unsigned int net_mask; + size_t pos; // retrieve specific information from template - get_template_attribute("NETWORK_ADDRESS",naddr); - if (naddr.empty()) + erase_template_attribute("NETWORK_ADDRESS",st_addr); + + if (st_addr.empty()) { goto error_addr; } - get_template_attribute("NETWORK_SIZE",nclass); + // Check if the IP has a network prefix + pos = st_addr.find("/"); - if ( nclass == "B" || nclass == "b" ) + if ( pos != string::npos ) { - size = 65534; - } - else if ( nclass == "C" || nclass == "c" ) - { - size = 254; - } - else if (!nclass.empty())//Assume it's a number - { - istringstream iss(nclass); + string st_network_bits; - iss >> size; + st_network_bits = st_addr.substr(pos+1); + st_addr = st_addr.substr(0,pos); + + istringstream iss(st_network_bits); + iss >> network_bits; + + if ( network_bits > 32 ) + { + // TODO wrong prefix + } + + host_bits = 32 - network_bits; + } + else + { + erase_template_attribute("NETWORK_MASK", st_mask); + + if ( !st_mask.empty() ) + { + // st_mask is in decimal format, e.g. 255.255.0.0 + // The number of trailing 0s is needed + + Leases::Lease::ip_to_number(st_mask, net_mask); + + host_bits = 0; + + while ( host_bits < 32 && + ((net_mask >> host_bits) & 1) != 1 ) + { + host_bits++; + } + } + else + { + erase_template_attribute("NETWORK_SIZE",st_size); + + if ( st_size == "C" || st_size == "c" ) + { + host_bits = 8; + } + else if ( st_size == "B" || st_size == "b" ) + { + host_bits = 16; + } + else if ( st_size == "A" || st_size == "a" ) + { + host_bits = 24; + } + else + { + size = default_size; + + if (!st_size.empty())//Assume it's a number + { + istringstream iss(st_size); + + iss >> size; + } + + host_bits = (int) ceil(log(size+2)/log(2)); + } + } } - if (size == 0) - { - size = default_size; - } + remove_template_attribute("NETWORK_SIZE"); - Leases::Lease::ip_to_number(naddr,net_addr); + // Set the network mask + net_mask = ( 0xFFFFFFFF << host_bits ) & 0xFFFFFFFF; + Leases::Lease::ip_to_string(net_mask, st_mask); + replace_template_attribute("NETWORK_MASK", st_mask); - int shift; - shift = (int) ceil(log(size+2)/log(2)); - size = (1 << shift) - 2; - unsigned int network_mask = 0xFFFFFFFF << shift; + Leases::Lease::ip_to_number(st_addr,net_addr); - if (net_addr != (network_mask & net_addr) ) + if (net_addr != (net_mask & net_addr) ) { // TODO: net_addr is not a valid network address, should end with 0s } + size = (1 << host_bits) - 2; + ip_start = net_addr + 1; ip_end = ip_start + size -1; From 4fcf406c0c8b51e05007f04ddb5bb95ffa8a06d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Mon, 28 Nov 2011 16:47:11 +0100 Subject: [PATCH 03/15] Feature #602: Show RANGE/IP_START and RANGE/IP_END in 'onevnet show' --- src/cli/one_helper/onevnet_helper.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 3d72e196af..71ead0d55f 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -66,6 +66,13 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts vn.template_str(false) + if vn.type_str == "RANGED" + puts + CLIHelper.print_header(str_h1 % ["RANGE"], false) + puts str % ["IP_START", vn['RANGE/IP_START']] + puts str % ["IP_END", vn['RANGE/IP_END']] + end + leases_str = vn.template_like_str('/VNET/LEASES', false) if !leases_str.empty? From effb4a57126b862b247916675ee71fa326fbd233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Mon, 28 Nov 2011 17:24:46 +0100 Subject: [PATCH 04/15] Feature #602: Refactorin of the Range creation code. New method RangedLeases::process_template --- include/RangedLeases.h | 12 ++++ src/vnm/RangedLeases.cc | 132 ++++++++++++++++++++++++++++++++++++++ src/vnm/VirtualNetwork.cc | 118 +++------------------------------- 3 files changed, 152 insertions(+), 110 deletions(-) diff --git a/include/RangedLeases.h b/include/RangedLeases.h index 4f97acb821..a8a81d9968 100644 --- a/include/RangedLeases.h +++ b/include/RangedLeases.h @@ -18,6 +18,7 @@ #define RANGED_LEASES_H_ #include "Leases.h" +#include "VirtualNetwork.h" using namespace std; @@ -36,6 +37,17 @@ public: ~RangedLeases(){}; + /** + * Reads (and clears) the necessary attributes to define a Ranged VNet + * @param vn Virtual Network + * @param ip_start First IP of the range + * @param ip_end Last IP of the range + * @param error_str Error reason, if any + * @return 0 on success, -1 otherwise + */ + static int process_template(VirtualNetwork * vn, + unsigned int& ip_start, unsigned int& ip_end, string& error_str); + /** * Returns an unused lease, which becomes used * @param vid identifier of the VM getting this lease diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index c94d59118b..26fb6940dd 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -18,6 +18,8 @@ #include "RangedLeases.h" #include "Nebula.h" +#include <cmath> + /* ************************************************************************** */ /* Ranged Leases class */ /* ************************************************************************** */ @@ -37,6 +39,136 @@ RangedLeases::RangedLeases( /* ************************************************************************** */ /* Ranged Leases :: Methods */ /* ************************************************************************** */ +int RangedLeases::process_template(VirtualNetwork* vn, + unsigned int& ip_start, unsigned int& ip_end, string& error_str) +{ + ostringstream oss; + + string st_size = ""; + string st_addr = ""; + string st_mask = ""; + + int default_size = VirtualNetworkPool::default_size(); + unsigned int size = default_size; + unsigned int host_bits; + unsigned int network_bits; + + unsigned int net_addr; + unsigned int net_mask; + size_t pos; + + // retrieve specific information from template + + vn->erase_template_attribute("NETWORK_ADDRESS",st_addr); + + if (st_addr.empty()) + { + goto error_addr; + } + + // Check if the IP has a network prefix + pos = st_addr.find("/"); + + if ( pos != string::npos ) + { + string st_network_bits; + + st_network_bits = st_addr.substr(pos+1); + st_addr = st_addr.substr(0,pos); + + istringstream iss(st_network_bits); + iss >> network_bits; + + if ( network_bits > 32 ) + { + // TODO wrong prefix + } + + host_bits = 32 - network_bits; + } + else + { + vn->erase_template_attribute("NETWORK_MASK", st_mask); + + if ( !st_mask.empty() ) + { + // st_mask is in decimal format, e.g. 255.255.0.0 + // The number of trailing 0s is needed + + Leases::Lease::ip_to_number(st_mask, net_mask); + + host_bits = 0; + + while ( host_bits < 32 && + ((net_mask >> host_bits) & 1) != 1 ) + { + host_bits++; + } + } + else + { + vn->erase_template_attribute("NETWORK_SIZE",st_size); + + if ( st_size == "C" || st_size == "c" ) + { + host_bits = 8; + } + else if ( st_size == "B" || st_size == "b" ) + { + host_bits = 16; + } + else if ( st_size == "A" || st_size == "a" ) + { + host_bits = 24; + } + else + { + size = default_size; + + if (!st_size.empty())//Assume it's a number + { + istringstream iss(st_size); + + iss >> size; + } + + host_bits = (int) ceil(log(size+2)/log(2)); + } + } + } + + vn->remove_template_attribute("NETWORK_SIZE"); + + // Set the network mask + net_mask = ( 0xFFFFFFFF << host_bits ) & 0xFFFFFFFF; + Lease::ip_to_string(net_mask, st_mask); + vn->replace_template_attribute("NETWORK_MASK", st_mask); + + Leases::Lease::ip_to_number(st_addr,net_addr); + + if (net_addr != (net_mask & net_addr) ) + { + // TODO: net_addr is not a valid network address, should end with 0s + } + + size = (1 << host_bits) - 2; + + ip_start = net_addr + 1; + ip_end = ip_start + size -1; + + return 0; + +error_addr: + oss << "No NETWORK_ADDRESS in template for Virtual Network."; + goto error_common; + +error_common: + error_str = oss.str(); + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int RangedLeases::get(int vid, string& ip, string& mac) { diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 899154538d..72a833d407 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -25,8 +25,6 @@ #include "AuthManager.h" -#include <cmath> - /* ************************************************************************** */ /* Virtual Network :: Constructor/Destructor */ /* ************************************************************************** */ @@ -174,8 +172,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) string pub; string s_type; + string ranged_error_str; - unsigned int default_size = VirtualNetworkPool::default_size(); unsigned int mac_prefix = VirtualNetworkPool::mac_prefix(); //-------------------------------------------------------------------------- @@ -255,117 +253,17 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) //-------------------------------------------------------------------------- if (type == VirtualNetwork::RANGED) { - string st_size = ""; - string st_addr = ""; - string st_mask = ""; - unsigned int size = default_size; - unsigned int host_bits; - unsigned int network_bits; + int rc; - unsigned int net_addr; - unsigned int net_mask; - size_t pos; + rc = RangedLeases::process_template(this, ip_start, ip_end, + ranged_error_str); - // retrieve specific information from template - - erase_template_attribute("NETWORK_ADDRESS",st_addr); - - if (st_addr.empty()) + if ( rc != 0 ) { - goto error_addr; + goto error_ranged; } - // Check if the IP has a network prefix - pos = st_addr.find("/"); - - if ( pos != string::npos ) - { - string st_network_bits; - - st_network_bits = st_addr.substr(pos+1); - st_addr = st_addr.substr(0,pos); - - istringstream iss(st_network_bits); - iss >> network_bits; - - if ( network_bits > 32 ) - { - // TODO wrong prefix - } - - host_bits = 32 - network_bits; - } - else - { - erase_template_attribute("NETWORK_MASK", st_mask); - - if ( !st_mask.empty() ) - { - // st_mask is in decimal format, e.g. 255.255.0.0 - // The number of trailing 0s is needed - - Leases::Lease::ip_to_number(st_mask, net_mask); - - host_bits = 0; - - while ( host_bits < 32 && - ((net_mask >> host_bits) & 1) != 1 ) - { - host_bits++; - } - } - else - { - erase_template_attribute("NETWORK_SIZE",st_size); - - if ( st_size == "C" || st_size == "c" ) - { - host_bits = 8; - } - else if ( st_size == "B" || st_size == "b" ) - { - host_bits = 16; - } - else if ( st_size == "A" || st_size == "a" ) - { - host_bits = 24; - } - else - { - size = default_size; - - if (!st_size.empty())//Assume it's a number - { - istringstream iss(st_size); - - iss >> size; - } - - host_bits = (int) ceil(log(size+2)/log(2)); - } - } - } - - remove_template_attribute("NETWORK_SIZE"); - - // Set the network mask - net_mask = ( 0xFFFFFFFF << host_bits ) & 0xFFFFFFFF; - Leases::Lease::ip_to_string(net_mask, st_mask); - replace_template_attribute("NETWORK_MASK", st_mask); - - Leases::Lease::ip_to_number(st_addr,net_addr); - - if (net_addr != (net_mask & net_addr) ) - { - // TODO: net_addr is not a valid network address, should end with 0s - } - - size = (1 << host_bits) - 2; - - ip_start = net_addr + 1; - ip_end = ip_start + size -1; - leases = new RangedLeases(db, oid, mac_prefix, @@ -423,8 +321,8 @@ error_update: ose << "Can not update Virtual Network."; goto error_common; -error_addr: - ose << "No NETWORK_ADDRESS in template for Virtual Network."; +error_ranged: + ose << ranged_error_str; goto error_common; error_null_leases: From 9791ece838364d7992911b98bac0d03c240d3194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Mon, 28 Nov 2011 18:10:00 +0100 Subject: [PATCH 05/15] Feature #602: Add support for IP_START and IP_END redefinition in Ranged networks --- src/vnm/Leases.cc | 5 ++++ src/vnm/RangedLeases.cc | 64 +++++++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/vnm/Leases.cc b/src/vnm/Leases.cc index 17dc998d07..fa0eedabb1 100644 --- a/src/vnm/Leases.cc +++ b/src/vnm/Leases.cc @@ -66,6 +66,11 @@ int Leases::Lease::ip_to_number(const string& _ip, unsigned int& i_ip) { iss >> dec >> tmp >> ws; + if ( tmp > 255 ) + { + return -1; + } + i_ip <<= 8; i_ip += tmp; } diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index 26fb6940dd..ce860d673b 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -48,8 +48,10 @@ int RangedLeases::process_template(VirtualNetwork* vn, string st_addr = ""; string st_mask = ""; - int default_size = VirtualNetworkPool::default_size(); - unsigned int size = default_size; + string st_ip_start = ""; + string st_ip_end = ""; + + unsigned int size = VirtualNetworkPool::default_size(); unsigned int host_bits; unsigned int network_bits; @@ -57,13 +59,41 @@ int RangedLeases::process_template(VirtualNetwork* vn, unsigned int net_mask; size_t pos; - // retrieve specific information from template + ip_start = 0; + ip_end = 0; - vn->erase_template_attribute("NETWORK_ADDRESS",st_addr); + // retrieve specific information from template + vn->erase_template_attribute("IP_START", st_ip_start); + vn->erase_template_attribute("IP_END", st_ip_end); + + if ( !st_ip_start.empty() ) + { + if ( Leases::Lease::ip_to_number(st_ip_start, ip_start) != 0 ) + { + goto error_ip_start; + } + } + + if ( !st_ip_end.empty() ) + { + if ( Leases::Lease::ip_to_number(st_ip_end, ip_end) != 0 ) + { + goto error_ip_end; + } + } + + vn->erase_template_attribute("NETWORK_ADDRESS", st_addr); if (st_addr.empty()) { - goto error_addr; + if ( ip_start != 0 && ip_end != 0 ) + { + return 0; + } + else + { + goto error_addr; + } } // Check if the IP has a network prefix @@ -123,8 +153,6 @@ int RangedLeases::process_template(VirtualNetwork* vn, } else { - size = default_size; - if (!st_size.empty())//Assume it's a number { istringstream iss(st_size); @@ -153,11 +181,29 @@ int RangedLeases::process_template(VirtualNetwork* vn, size = (1 << host_bits) - 2; - ip_start = net_addr + 1; - ip_end = ip_start + size -1; + // TODO: check that start < end; ip_start & ip_end are part of the network + + if ( ip_start == 0 ) + { + ip_start = net_addr + 1; + } + + if ( ip_end == 0 ) + { + ip_end = net_addr + size; + } return 0; + +error_ip_start: + oss << "IP_START is not a valid IP."; + goto error_common; + +error_ip_end: + oss << "IP_END is not a valid IP."; + goto error_common; + error_addr: oss << "No NETWORK_ADDRESS in template for Virtual Network."; goto error_common; From 07bc7d01549178defbef55205f22b4ce3e44ad6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Mon, 28 Nov 2011 19:07:44 +0100 Subject: [PATCH 06/15] Feature #602: Add error checks in Ranged network creation --- src/vnm/RangedLeases.cc | 78 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index ce860d673b..84c1bddaf0 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -88,6 +88,11 @@ int RangedLeases::process_template(VirtualNetwork* vn, { if ( ip_start != 0 && ip_end != 0 ) { + if ( ip_end < ip_start ) + { + goto error_greater; + } + return 0; } else @@ -111,7 +116,7 @@ int RangedLeases::process_template(VirtualNetwork* vn, if ( network_bits > 32 ) { - // TODO wrong prefix + goto error_prefix; } host_bits = 32 - network_bits; @@ -125,7 +130,10 @@ int RangedLeases::process_template(VirtualNetwork* vn, // st_mask is in decimal format, e.g. 255.255.0.0 // The number of trailing 0s is needed - Leases::Lease::ip_to_number(st_mask, net_mask); + if ( Leases::Lease::ip_to_number(st_mask, net_mask) != 0 ) + { + goto error_netmask; + } host_bits = 0; @@ -172,17 +180,19 @@ int RangedLeases::process_template(VirtualNetwork* vn, Lease::ip_to_string(net_mask, st_mask); vn->replace_template_attribute("NETWORK_MASK", st_mask); - Leases::Lease::ip_to_number(st_addr,net_addr); + if ( Leases::Lease::ip_to_number(st_addr,net_addr) != 0 ) + { + goto error_net_addr; + } if (net_addr != (net_mask & net_addr) ) { - // TODO: net_addr is not a valid network address, should end with 0s + goto error_not_base_addr; } size = (1 << host_bits) - 2; - // TODO: check that start < end; ip_start & ip_end are part of the network - + // Set IP start/end if ( ip_start == 0 ) { ip_start = net_addr + 1; @@ -193,21 +203,73 @@ int RangedLeases::process_template(VirtualNetwork* vn, ip_end = net_addr + size; } + // Check range restrictions + if ( (ip_start & net_mask) != net_addr ) + { + goto error_range_ip_start; + } + + if ( (ip_end & net_mask) != net_addr ) + { + goto error_range_ip_end; + } + + if ( ip_end < ip_start ) + { + goto error_greater; + } + return 0; error_ip_start: - oss << "IP_START is not a valid IP."; + oss << "IP_START " << st_ip_start << " is not a valid IP."; goto error_common; error_ip_end: - oss << "IP_END is not a valid IP."; + oss << "IP_END " << st_ip_end << " is not a valid IP."; + goto error_common; + +error_not_base_addr: + oss << "NETWORK_ADDRESS " << st_addr + << " is not a base address for the network mask " << st_mask << "."; + goto error_common; + +error_net_addr: + oss << "NETWORK_ADDRESS " << st_addr << " is not a valid IP."; + goto error_common; + +error_netmask: + oss << "NETWORK_MASK " << st_mask << " is not a valid network mask."; + goto error_common; + +error_prefix: + oss << "A CIDR prefix of " << network_bits << " bits is not valid."; goto error_common; error_addr: oss << "No NETWORK_ADDRESS in template for Virtual Network."; goto error_common; +error_range_ip_start: + oss << "IP_START " << st_ip_start << " is not part of the network " + << st_addr << "/" << 32-host_bits << "."; + goto error_common; + +error_range_ip_end: + oss << "IP_END " << st_ip_end << " is not part of the network " + << st_addr << "/" << 32-host_bits << "."; + goto error_common; + +error_greater: + Leases::Lease::ip_to_string(ip_start, st_ip_start); + Leases::Lease::ip_to_string(ip_end, st_ip_end); + + oss << "IP_START " << st_ip_start << " cannot be greater than the IP_END " + << st_ip_end << "."; + goto error_common; + + error_common: error_str = oss.str(); return -1; From 4904cc964beb37122f169eaaaf935f3ed24be160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Tue, 29 Nov 2011 16:12:00 +0100 Subject: [PATCH 07/15] Feature #965: New one.vn.hold and one.vn.release methods to mark IPs as used, without an associated VM. Includes Ruby OCA and CLI --- include/Leases.h | 20 +++++ include/RequestManagerVirtualNetwork.h | 38 ++++++++ include/VirtualNetwork.h | 23 ++++- src/cli/onevnet | 23 ++++- src/oca/ruby/OpenNebula/VirtualNetwork.rb | 30 ++++++- src/rm/RequestManager.cc | 4 + src/rm/RequestManagerVirtualNetwork.cc | 2 +- src/vnm/Leases.cc | 103 +++++++++++++++++++--- src/vnm/VirtualNetwork.cc | 26 ++++++ 9 files changed, 250 insertions(+), 19 deletions(-) diff --git a/include/Leases.h b/include/Leases.h index 5927f36f14..bb8453e53b 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -102,6 +102,26 @@ public: virtual int remove_leases(vector<const Attribute*>& vector_leases, string& error_msg) = 0; + /** + * Holds a Lease, marking it as used + * @param vector_leases vector of VectorAttribute objects. For the + * moment, the vector can only contain one LEASE. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int hold_leases(vector<const Attribute*>& vector_leases, string& error_msg); + + /** + * Releases a Lease on hold + * @param vector_leases vector of VectorAttribute objects. For the + * moment, the vector can only contain one LEASE. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int free_leases(vector<const Attribute*>& vector_leases, string& error_msg); + // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- diff --git a/include/RequestManagerVirtualNetwork.h b/include/RequestManagerVirtualNetwork.h index f402499ac2..4a6245754b 100644 --- a/include/RequestManagerVirtualNetwork.h +++ b/include/RequestManagerVirtualNetwork.h @@ -93,6 +93,44 @@ public: } }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkHold : public RequestManagerVirtualNetwork +{ +public: + VirtualNetworkHold(): + RequestManagerVirtualNetwork("VirtualNetworkHold", + "Holds a virtual network Lease as used"){}; + ~VirtualNetworkHold(){}; + + int leases_action(VirtualNetwork * vn, + VirtualNetworkTemplate * tmpl, + string& error_str) + { + return vn->hold_leases(tmpl, error_str); + } +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkRelease : public RequestManagerVirtualNetwork +{ +public: + VirtualNetworkRelease(): + RequestManagerVirtualNetwork("VirtualNetworkRelease", + "Releases a virtual network Lease on hold"){}; + ~VirtualNetworkRelease(){}; + + int leases_action(VirtualNetwork * vn, + VirtualNetworkTemplate * tmpl, + string& error_str) + { + return vn->free_leases(tmpl, error_str); + } +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 9146d69f97..6625c260b4 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -85,7 +85,7 @@ public: /** * Adds Leases to the virtual network (Only implemented for FIXED networks) - * @param leases_template template in the form LEASES = [IP=XX, MAC=XX]. + * @param leases template in the form LEASES = [IP=XX, MAC=XX]. * MAC is optional. The template can only contain one LEASE * definition. * @param error_msg If the action fails, this message contains the reason. @@ -96,7 +96,7 @@ public: /** * Removes Leases from the virtual network; if they are not used.(Only * implemented for FIXED networks) - * @param leases_template template in the form LEASES = [IP=XX]. + * @param leases template in the form LEASES = [IP=XX]. * The template can only contain one LEASE definition. * @param error_msg If the action fails, this message contains * the reason. @@ -104,6 +104,25 @@ public: */ int remove_leases(VirtualNetworkTemplate* leases, string& error_msg); + /** + * Holds a Lease, marking it as used + * @param leases template in the form LEASES = [IP=XX]. + * The template can only contain one LEASE definition. + * @param error_msg If the action fails, this message contains the reason. + * @return 0 on success + */ + int hold_leases(VirtualNetworkTemplate * leases, string& error_msg); + + /** + * Releases a Lease on hold + * @param leases template in the form LEASES = [IP=XX]. + * The template can only contain one LEASE definition. + * @param error_msg If the action fails, this message contains + * the reason. + * @return 0 on success + */ + int free_leases(VirtualNetworkTemplate* leases, string& error_msg); + /** * Gets a new lease for a specific VM * @param vid VM identifier diff --git a/src/cli/onevnet b/src/cli/onevnet index 72ab53716a..b2ba672371 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -93,8 +93,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do Adds a lease to the Virtual Network EOT - command :addleases, 'Adds a lease to the Virtual Network', :vnetid, :ip, - [:mac, nil] do + command :addleases, addleases_desc, :vnetid, :ip, [:mac, nil] do helper.perform_action(args[0],options,"lease added") do |vn| vn.addleases(args[1], args[2]) end @@ -110,6 +109,26 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + hold_desc = <<-EOT.unindent + Holds a Virtual Network lease, marking it as used + EOT + + command :hold, hold_desc, :vnetid, :ip do + helper.perform_action(args[0],options,"lease on hold") do |vn| + vn.hold(args[1]) + end + end + + release_desc = <<-EOT.unindent + Releases a Virtual Network lease on hold + EOT + + command :release, release_desc, :vnetid, :ip do + helper.perform_action(args[0],options,"lease released") do |vn| + vn.release(args[1]) + end + end + publish_desc = <<-EOT.unindent Publishes the given Virtual Network. A public Virtual Network can be seen and used by other Users in the Virtual Network's group diff --git a/src/oca/ruby/OpenNebula/VirtualNetwork.rb b/src/oca/ruby/OpenNebula/VirtualNetwork.rb index 7020bac0fc..b932d7cbe8 100644 --- a/src/oca/ruby/OpenNebula/VirtualNetwork.rb +++ b/src/oca/ruby/OpenNebula/VirtualNetwork.rb @@ -32,7 +32,9 @@ module OpenNebula :addleases => "vn.addleases", :rmleases => "vn.rmleases", :chown => "vn.chown", - :update => "vn.update" + :update => "vn.update", + :hold => "vn.hold", + :release => "vn.release" } VN_TYPES=%w{RANGED FIXED} @@ -128,6 +130,32 @@ module OpenNebula return rc end + # Holds a virtual network Lease as used + # @param ip [String] IP to hold + def hold(ip) + return Error.new('ID not defined') if !@pe_id + + lease_template = "LEASES = [ IP = #{ip} ]" + + rc = @client.call(VN_METHODS[:hold], @pe_id, lease_template) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + + # Releases a virtual network Lease on hold + # @param ip [String] IP to release + def release(ip) + return Error.new('ID not defined') if !@pe_id + + lease_template = "LEASES = [ IP = #{ip} ]" + + rc = @client.call(VN_METHODS[:release], @pe_id, lease_template) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Changes the owner/group # uid:: _Integer_ the new owner id. Set to -1 to leave the current one # gid:: _Integer_ the new group id. Set to -1 to leave the current one diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 6c3ca96d3e..08dd938794 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -246,6 +246,8 @@ void RequestManager::register_xml_methods() // VirtualNetwork Methods xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases()); xmlrpc_c::methodPtr vn_rmleases(new VirtualNetworkRemoveLeases()); + xmlrpc_c::methodPtr vn_hold(new VirtualNetworkHold()); + xmlrpc_c::methodPtr vn_release(new VirtualNetworkRelease()); // Update Template Methods xmlrpc_c::methodPtr image_update(new ImageUpdateTemplate()); @@ -357,6 +359,8 @@ void RequestManager::register_xml_methods() /* Network related methods*/ RequestManagerRegistry.addMethod("one.vn.addleases", vn_addleases); RequestManagerRegistry.addMethod("one.vn.rmleases", vn_rmleases); + RequestManagerRegistry.addMethod("one.vn.hold", vn_hold); + RequestManagerRegistry.addMethod("one.vn.release", vn_release); RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate); RequestManagerRegistry.addMethod("one.vn.publish", vn_publish); RequestManagerRegistry.addMethod("one.vn.update", vn_update); diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index af410a025f..b3bb5ed0b8 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -80,7 +80,7 @@ void RequestManagerVirtualNetwork:: if ( rc < 0 ) { failure_response(INTERNAL, - request_error("Error modifiying network leases",error_str), + request_error("Error modifying network leases",error_str), att); vn->unlock(); diff --git a/src/vnm/Leases.cc b/src/vnm/Leases.cc index fa0eedabb1..c159294625 100644 --- a/src/vnm/Leases.cc +++ b/src/vnm/Leases.cc @@ -386,23 +386,11 @@ int Leases::update(SqlDB * db) bool Leases::check(const string& ip) { - map<unsigned int,Lease *>::iterator it; - unsigned int _ip; Leases::Lease::ip_to_number(ip,_ip); - - it=leases.find(_ip); - - if (it!=leases.end()) - { - return it->second->used; - } - else - { - return false; - } + return check(_ip); } /* -------------------------------------------------------------------------- */ @@ -424,6 +412,95 @@ bool Leases::check(unsigned int ip) } } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Leases::hold_leases(vector<const Attribute*>& vector_leases, + string& error_msg) +{ + const VectorAttribute * single_attr_lease = 0; + + int rc; + string ip; + string mac; + + if ( vector_leases.size() > 0 ) + { + single_attr_lease = + dynamic_cast<const VectorAttribute *>(vector_leases[0]); + } + + if ( single_attr_lease == 0 ) + { + error_msg = "Empty lease description."; + return -1; + } + + ip = single_attr_lease->vector_value("IP"); + + if ( check(ip) ) + { + error_msg = "Lease is in use."; + return -1; + } + + rc = set(-1, ip, mac); + + if ( rc != 0 ) + { + error_msg = "Lease is not part of the NET."; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Leases::free_leases(vector<const Attribute*>& vector_leases, + string& error_msg) +{ + const VectorAttribute * single_attr_lease = 0; + map<unsigned int,Lease *>::iterator it; + + unsigned int i_ip; + string st_ip; + string mac; + + if ( vector_leases.size() > 0 ) + { + single_attr_lease = + dynamic_cast<const VectorAttribute *>(vector_leases[0]); + } + + if ( single_attr_lease == 0 ) + { + error_msg = "Empty lease description."; + return -1; + } + + st_ip = single_attr_lease->vector_value("IP"); + + if ( Leases::Lease::ip_to_number(st_ip,i_ip) != 0 ) + { + error_msg = "Wrong Lease format."; + return -1; + } + + it = leases.find(i_ip); + + if ( it == leases.end() || (it->second->used && it->second->vid != -1) ) + { + error_msg = "Lease is not on hold."; + return -1; + } + + release(st_ip); + + return 0; +} + /* ************************************************************************** */ /* Leases :: Misc */ /* ************************************************************************** */ diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 72a833d407..5fa53f2115 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -646,3 +646,29 @@ int VirtualNetwork::remove_leases(VirtualNetworkTemplate * leases_template, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +int VirtualNetwork::hold_leases(VirtualNetworkTemplate * leases_template, + string& error_msg) +{ + vector<const Attribute *> vector_leases; + + leases_template->get("LEASES", vector_leases); + + return leases->hold_leases(vector_leases, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualNetwork::free_leases(VirtualNetworkTemplate * leases_template, + string& error_msg) +{ + vector<const Attribute *> vector_leases; + + leases_template->get("LEASES", vector_leases); + + return leases->free_leases(vector_leases, error_msg); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ From 05e40b5b6f41c3691e0e0b7a8ea6d99ad80056d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Tue, 29 Nov 2011 18:09:19 +0100 Subject: [PATCH 08/15] Feature #602: Small bugfixes --- include/Leases.h | 2 +- src/vnm/RangedLeases.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Leases.h b/include/Leases.h index bb8453e53b..74a04d7928 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -42,7 +42,7 @@ public: */ Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix): ObjectSQL(), - oid(_oid), size(_size), n_used(0), db(_db){}; + oid(_oid), size(_size), n_used(0), mac_prefix(_mac_prefix), db(_db){}; virtual ~Leases() { diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index 84c1bddaf0..d992ad29c0 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -176,7 +176,7 @@ int RangedLeases::process_template(VirtualNetwork* vn, vn->remove_template_attribute("NETWORK_SIZE"); // Set the network mask - net_mask = ( 0xFFFFFFFF << host_bits ) & 0xFFFFFFFF; + net_mask = 0xFFFFFFFF << host_bits; Lease::ip_to_string(net_mask, st_mask); vn->replace_template_attribute("NETWORK_MASK", st_mask); From 8ef3c966a4ea28c265ffe74e7dc183187c809587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Tue, 29 Nov 2011 18:10:05 +0100 Subject: [PATCH 09/15] Feature #602: Fix tests --- src/vnm/test/VirtualNetworkPoolTest.cc | 36 +++++++++++++++++++------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 2d5801309c..556f6884a6 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -73,16 +73,16 @@ const string xmls[] = { "<VNET><ID>0</ID><UID>123</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", - "<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE><LEASES></LEASES></VNET>", + "<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE><LEASES></LEASES></VNET>", "<VNET><ID>0</ID><UID>133</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", }; const string xml_dump = - "<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>"; + "<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; const string xml_dump_where = - "<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>"; + "<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -411,16 +411,16 @@ public: "TYPE = RANGED\n" "BRIDGE = br0\n" "NETWORK_SIZE = B\n" - "NETWORK_ADDRESS = 192.168.1.0\n", + "NETWORK_ADDRESS = 192.168.0.0\n", - // Size "X", defaults to 128 + // Size 126 "NAME = \"Net D\"\n" "TYPE = RANGED\n" "BRIDGE = br0\n" - "NETWORK_SIZE = X\n" + "NETWORK_SIZE = 126\n" "NETWORK_ADDRESS = 192.168.1.0\n", - // Size 32 + // Size 30 "NAME = \"Net E\"\n" "TYPE = RANGED\n" "BRIDGE = br0\n" @@ -428,7 +428,7 @@ public: "NETWORK_ADDRESS = 192.168.1.0\n" }; - unsigned int sizes[7]={1,3,256,256,65536,128,32}; + unsigned int sizes[7]={1,3,254,254,65534,126,30}; int oid[7]; for (int i = 0 ; i < 7 ; i++) @@ -695,7 +695,7 @@ public: CPPUNIT_ASSERT( rc != 0 ); - // Ask for two more IPs + // Ask for the rest of IPs vn->lock(); rc = vn->get_lease(123, ip, mac, bridge); vn->unlock(); @@ -708,12 +708,28 @@ public: CPPUNIT_ASSERT( rc == 0 ); + vn->lock(); + rc = vn->get_lease(457, ip, mac, bridge); + vn->unlock(); + + CPPUNIT_ASSERT( rc == 0 ); + + vn->lock(); + rc = vn->get_lease(458, ip, mac, bridge); + vn->unlock(); + + CPPUNIT_ASSERT( rc == 0 ); + + vn->lock(); + rc = vn->get_lease(459, ip, mac, bridge); + vn->unlock(); + + CPPUNIT_ASSERT( rc == 0 ); // All IPs are now used vn->lock(); rc = vn->get_lease(789, ip, mac, bridge); vn->unlock(); - CPPUNIT_ASSERT( rc != 0 ); // Release one of the 3 IPs From ee6888567a754a57b76837042b11094c748f41bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Wed, 30 Nov 2011 11:41:41 +0100 Subject: [PATCH 10/15] Feature #602: Add tests for range definition --- src/vnm/test/VirtualNetworkPoolTest.cc | 130 +++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 556f6884a6..2a26cbef48 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -180,6 +180,8 @@ class VirtualNetworkPoolTest : public PoolTest CPPUNIT_TEST (del_lease_nonexistent_ip); CPPUNIT_TEST (del_lease_used_ip); + CPPUNIT_TEST (range_definition); + CPPUNIT_TEST_SUITE_END (); protected: @@ -1642,6 +1644,134 @@ public: CPPUNIT_ASSERT( rc != 0 ); CPPUNIT_ASSERT( error_str != "" ); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + + void range_definition() + { + VirtualNetworkPoolFriend * vnpool = + static_cast<VirtualNetworkPoolFriend*>(pool); + + int rc; + VirtualNetwork* vnet; + + int oid; + string xml_str; + string xpath; + string err; + + // All these templates should create the same range + string templ[] = { + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0\n" + "NETWORK_SIZE = C\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0\n" + "NETWORK_SIZE = 254\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0/24\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0\n" + "NETWORK_MASK = 255.255.255.0\n", + + + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0/24\n" + "IP_START = 10.10.10.17\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0/24\n" + "IP_END = 10.10.10.41\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0/24\n" + "IP_START = 10.10.10.17\n" + "IP_END = 10.10.10.41\n", + + + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "IP_START = 10.10.10.17\n" + "IP_END = 10.10.10.41\n", + + "NAME = R\n" + "TYPE = RANGED\n" + "BRIDGE = vbr0\n" + "NETWORK_ADDRESS = 10.10.10.0\n", + }; + + string ip_start[] = { + "10.10.10.1", + "10.10.10.1", + "10.10.10.1", + "10.10.10.1", + + "10.10.10.17", + "10.10.10.1", + "10.10.10.17", + + "10.10.10.17", + + "10.10.10.1", + }; + + string ip_end[] = { + "10.10.10.254", + "10.10.10.254", + "10.10.10.254", + "10.10.10.254", + + "10.10.10.254", + "10.10.10.41", + "10.10.10.41", + + "10.10.10.41", + + "10.10.10.126", + }; + + + for (int i = 0 ; i < 9 ; i++) + { + rc = vnpool->allocate(uids[0], templ[i], &oid); + + CPPUNIT_ASSERT( rc >= 0 ); + + vnet = vnpool->get(oid, false); + CPPUNIT_ASSERT( vnet != 0 ); + + vnet->to_xml_extended(xml_str); + + ObjectXML::xpath_value(xpath, xml_str.c_str(), "/VNET/RANGE/IP_START" ); + CPPUNIT_ASSERT( xpath == ip_start[i] ); + + ObjectXML::xpath_value(xpath, xml_str.c_str(), "/VNET/RANGE/IP_END" ); + CPPUNIT_ASSERT( xpath == ip_end[i] ); + + vnpool->drop(vnet, err); + } + } }; /* ************************************************************************* */ From a173e7bd754abc0b372aae76fb6267d4f5883ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Wed, 30 Nov 2011 12:43:36 +0100 Subject: [PATCH 11/15] Feature #602: onevnet release returns error if a Lease is not used, this achieves the same behaviour for fixed and ranged networks --- src/vnm/Leases.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vnm/Leases.cc b/src/vnm/Leases.cc index c159294625..98cf0e38dc 100644 --- a/src/vnm/Leases.cc +++ b/src/vnm/Leases.cc @@ -490,7 +490,7 @@ int Leases::free_leases(vector<const Attribute*>& vector_leases, it = leases.find(i_ip); - if ( it == leases.end() || (it->second->used && it->second->vid != -1) ) + if ( it == leases.end() || !it->second->used || it->second->vid != -1 ) { error_msg = "Lease is not on hold."; return -1; From f0efbf09b6b36bfc7c1b9dd57e737fc908b02878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Wed, 30 Nov 2011 13:19:15 +0100 Subject: [PATCH 12/15] Feature #602: Add VNet hold and release methods in Java OCA --- .../client/vnet/VirtualNetwork.java | 53 ++++++++++++++++++- src/oca/java/test/VirtualNetworkTest.java | 48 +++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java b/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java index ac58d7a316..9bd60df8d3 100644 --- a/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java +++ b/src/oca/java/src/org/opennebula/client/vnet/VirtualNetwork.java @@ -36,7 +36,8 @@ public class VirtualNetwork extends PoolElement{ private static final String RMLEASES = METHOD_PREFIX + "rmleases"; private static final String CHOWN = METHOD_PREFIX + "chown"; private static final String UPDATE = METHOD_PREFIX + "update"; - + private static final String HOLD = METHOD_PREFIX + "hold"; + private static final String RELEASE = METHOD_PREFIX + "release"; /** * Creates a new virtual network representation. @@ -140,6 +141,32 @@ public class VirtualNetwork extends PoolElement{ return client.call(RMLEASES, id, template); } + /** + * Holds a VirtualNetwork lease, marking it as used + * + * @param client XML-RPC Client. + * @param id The virtual network id (nid) of the target network. + * @param template IP to hold, e.g. "LEASES = [ IP = 192.168.0.5 ]" + * @return A encapsulated response. + */ + public static OneResponse hold(Client client, int id, String template) + { + return client.call(HOLD, id, template); + } + + /** + * Releases a VirtualNetwork lease on hold + * + * @param client XML-RPC Client. + * @param id The virtual network id (nid) of the target network. + * @param template IP to release, e.g. "LEASES = [ IP = 192.168.0.5 ]" + * @return A encapsulated response. + */ + public static OneResponse release(Client client, int id, String template) + { + return client.call(RELEASE, id, template); + } + /** * Changes the owner/group * @@ -271,6 +298,30 @@ public class VirtualNetwork extends PoolElement{ return rmLeases(client, id, lease_template); } + /** + * Holds a VirtualNetwork lease, marking it as used + * + * @param ip IP to hold, e.g. "192.168.0.5" + * @return A encapsulated response. + */ + public OneResponse hold(String ip) + { + String lease_template = "LEASES = [ IP = " + ip + " ]"; + return hold(client, id, lease_template); + } + + /** + * Releases a VirtualNetwork lease on hold + * + * @param ip IP to release, e.g. "192.168.0.5" + * @return A encapsulated response. + */ + public OneResponse release(String ip) + { + String lease_template = "LEASES = [ IP = " + ip + " ]"; + return release(client, id, lease_template); + } + /** * Changes the owner/group * diff --git a/src/oca/java/test/VirtualNetworkTest.java b/src/oca/java/test/VirtualNetworkTest.java index dcea0775e6..6a0c86537b 100644 --- a/src/oca/java/test/VirtualNetworkTest.java +++ b/src/oca/java/test/VirtualNetworkTest.java @@ -209,6 +209,54 @@ public class VirtualNetworkTest fixed_vnet.delete(); } + @Test + public void holdFixed() + { + res = VirtualNetwork.allocate(client, fixed_template); + assertTrue( !res.isError() ); + + VirtualNetwork fixed_vnet = + new VirtualNetwork(Integer.parseInt(res.getMessage()), client); + + res = fixed_vnet.hold("130.10.0.1"); + assertTrue( !res.isError() ); + + res = fixed_vnet.hold("130.10.0.5"); + assertTrue( res.isError() ); + + res = fixed_vnet.release("130.10.0.1"); + assertTrue( !res.isError() ); + + res = fixed_vnet.release("130.10.0.1"); + assertTrue( res.isError() ); + + res = fixed_vnet.release("130.10.0.5"); + assertTrue( res.isError() ); + + fixed_vnet.delete(); + } + + @Test + public void holdRanged() + { + res = vnet.hold("192.168.0.10"); + assertTrue( !res.isError() ); + + res = vnet.hold("192.168.100.1"); + assertTrue( res.isError() ); + + res = vnet.release("192.168.0.10"); + assertTrue( !res.isError() ); + + res = vnet.release("192.168.0.10"); + assertTrue( res.isError() ); + + res = vnet.release("192.168.100.1"); + assertTrue( res.isError() ); + + vnet.delete(); + } + @Test public void update() { From 536d69b5ab017f2a04facc865d810b5c6561e485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Thu, 1 Dec 2011 07:50:37 -0800 Subject: [PATCH 13/15] Feature #602: Change onevnet show format to separate used, free and 'on hold' leases --- src/cli/one_helper/onevnet_helper.rb | 18 ++++++++++++------ src/oca/ruby/OpenNebula/XMLUtils.rb | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 71ead0d55f..3a59dac76a 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -73,13 +73,19 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts str % ["IP_END", vn['RANGE/IP_END']] end - leases_str = vn.template_like_str('/VNET/LEASES', false) + lease_types = [ ["LEASES ON HOLD", 'LEASE[USED=1 and VID=-1]'], + ["USED LEASES", 'LEASE[USED=1 and VID>-1]'], + ["FREE LEASES", 'LEASE[USED=0]'] ] - if !leases_str.empty? - puts - CLIHelper.print_header(str_h1 % ["LEASES INFORMATION"], false) - puts leases_str - end + lease_types.each { |pair| + leases_str = vn.template_like_str('/VNET/LEASES', false, pair[1]) + + if !leases_str.empty? + puts + CLIHelper.print_header(str_h1 % [pair[0]], false) + puts leases_str + end + } end def format_pool(options) diff --git a/src/oca/ruby/OpenNebula/XMLUtils.rb b/src/oca/ruby/OpenNebula/XMLUtils.rb index 1dfa884532..3505fb9cc6 100644 --- a/src/oca/ruby/OpenNebula/XMLUtils.rb +++ b/src/oca/ruby/OpenNebula/XMLUtils.rb @@ -201,7 +201,7 @@ module OpenNebula template_like_str('TEMPLATE', indent) end - def template_like_str(root_element, indent=true) + def template_like_str(root_element, indent=true, xpath_exp=nil) if NOKOGIRI xml_template=@xml.xpath(root_element).to_s rexml=REXML::Document.new(xml_template).root @@ -217,7 +217,7 @@ module OpenNebula ind_tab=' ' end - str=rexml.collect {|n| + str=rexml.elements.collect(xpath_exp) {|n| if n.class==REXML::Element str_line="" if n.has_elements? From cdf1231f819814b3e98b5c5747dd34b78203846d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es> Date: Fri, 2 Dec 2011 12:23:21 +0100 Subject: [PATCH 14/15] Feature #602 #863: Add VLAN tag to vnets and VM NIC attribute --- include/VirtualNetwork.h | 5 +++++ src/cli/one_helper/onevnet_helper.rb | 1 + src/vnm/VirtualNetwork.cc | 29 ++++++++++++++++++++++---- src/vnm/test/VirtualNetworkPoolTest.cc | 14 ++++++------- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 6625c260b4..cca301be12 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -227,6 +227,11 @@ private: */ string vlan_id; + /** + * Whether or not to isolate this network with the vnm driver + */ + int vlan; + // ------------------------------------------------------------------------- // Virtual Network Description // ------------------------------------------------------------------------- diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index acaf71d0bb..561f49d97a 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -59,6 +59,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts str % ["PUBLIC", OpenNebulaHelper.boolean_to_str(vn['PUBLIC'])] puts str % ["TYPE", vn.type_str] puts str % ["BRIDGE", vn["BRIDGE"]] + puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])] puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if vn["PHYDEV"] puts str % ["VLAN ID", vn["VLAN_ID"]] if vn["VLAN_ID"] puts str % ["USED LEASES", vn['TOTAL_LEASES']] diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 5fa53f2115..0579f4d270 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -25,6 +25,8 @@ #include "AuthManager.h" +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + /* ************************************************************************** */ /* Virtual Network :: Constructor/Destructor */ /* ************************************************************************** */ @@ -171,6 +173,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) int rc; string pub; + string vlan_attr; string s_type; string ranged_error_str; @@ -183,7 +186,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) // ------------ TYPE ---------------------- erase_template_attribute("TYPE",s_type); - transform(s_type.begin(),s_type.end(),s_type.begin(),(int(*)(int))toupper); + TO_UPPER(s_type); if (s_type == "RANGED") { @@ -219,6 +222,14 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) erase_template_attribute("VLAN_ID",vlan_id); + // ------------ VLAN ---------------------- + + erase_template_attribute("VLAN", vlan_attr); + + TO_UPPER(vlan_attr); + + vlan = (vlan_attr == "YES"); + // ------------ BRIDGE -------------------- erase_template_attribute("BRIDGE",bridge); @@ -236,7 +247,6 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) oss << "onebr" << oid; bridge = oss.str(); - replace_template_attribute("BRIDGE",bridge); } } @@ -244,7 +254,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) erase_template_attribute("PUBLIC", pub); - transform (pub.begin(), pub.end(), pub.begin(), (int(*)(int))toupper); + TO_UPPER(pub); public_obj = (pub == "YES"); @@ -456,7 +466,8 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const "<GNAME>" << gname << "</GNAME>" << "<NAME>" << name << "</NAME>" << "<TYPE>" << type << "</TYPE>" << - "<BRIDGE>" << bridge << "</BRIDGE>"; + "<BRIDGE>" << bridge << "</BRIDGE>"<< + "<VLAN>" << vlan << "</VLAN>"; if (!phydev.empty()) { @@ -522,6 +533,7 @@ int VirtualNetwork::from_xml(const string &xml_str) rc += xpath(int_type, "/VNET/TYPE", -1); rc += xpath(bridge, "/VNET/BRIDGE", "not_found"); rc += xpath(public_obj, "/VNET/PUBLIC", 0); + rc += xpath(vlan, "/VNET/VLAN", 0); xpath(phydev, "/VNET/PHYDEV", ""); xpath(vlan_id, "/VNET/VLAN_ID",""); @@ -605,6 +617,15 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid) nic->replace("MAC" ,mac); nic->replace("IP" ,ip); + if ( vlan == 1 ) + { + nic->replace("VLAN", "YES"); + } + else + { + nic->replace("VLAN", "NO"); + } + if (!phydev.empty()) { nic->replace("PHYDEV", phydev); diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 2a26cbef48..d1744b2876 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -71,18 +71,18 @@ const string templates[] = const string xmls[] = { - "<VNET><ID>0</ID><UID>123</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", + "<VNET><ID>0</ID><UID>123</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", - "<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE><LEASES></LEASES></VNET>", + "<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE><LEASES></LEASES></VNET>", - "<VNET><ID>0</ID><UID>133</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", + "<VNET><ID>0</ID><UID>133</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", }; const string xml_dump = - "<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; + "<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; const string xml_dump_where = - "<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; + "<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><RANGE><IP_START>192.168.0.1</IP_START><IP_END>192.168.0.254</IP_END></RANGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_MASK><![CDATA[255.255.255.0]]></NETWORK_MASK></TEMPLATE></VNET></VNET_POOL>"; /* ************************************************************************* */ /* ************************************************************************* */ @@ -312,8 +312,8 @@ public: }; string phydev_xml[] = { - "<VNET><ID>0</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>BRIDGE and PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>br0</BRIDGE><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", - "<VNET><ID>1</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>No BRIDGE only PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>onebr1</BRIDGE><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><BRIDGE><![CDATA[onebr1]]></BRIDGE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>" + "<VNET><ID>0</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>BRIDGE and PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>", + "<VNET><ID>1</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>No BRIDGE only PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>onebr1</BRIDGE><VLAN>0</VLAN><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>" }; // test vm with bridge and phydev From ed564472f6f15e3151c118fc371f2144429b168b Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" <rubensm@dacya.ucm.es> Date: Sun, 4 Dec 2011 19:44:50 +0100 Subject: [PATCH 15/15] feature #602: Moved size to get the default if needed --- src/vnm/RangedLeases.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index d992ad29c0..0eea558afb 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -51,7 +51,6 @@ int RangedLeases::process_template(VirtualNetwork* vn, string st_ip_start = ""; string st_ip_end = ""; - unsigned int size = VirtualNetworkPool::default_size(); unsigned int host_bits; unsigned int network_bits; @@ -161,12 +160,18 @@ int RangedLeases::process_template(VirtualNetwork* vn, } else { + unsigned int size; + if (!st_size.empty())//Assume it's a number { istringstream iss(st_size); iss >> size; } + else + { + size = VirtualNetworkPool::default_size(); + } host_bits = (int) ceil(log(size+2)/log(2)); } @@ -178,6 +183,7 @@ int RangedLeases::process_template(VirtualNetwork* vn, // Set the network mask net_mask = 0xFFFFFFFF << host_bits; Lease::ip_to_string(net_mask, st_mask); + vn->replace_template_attribute("NETWORK_MASK", st_mask); if ( Leases::Lease::ip_to_number(st_addr,net_addr) != 0 ) @@ -190,8 +196,6 @@ int RangedLeases::process_template(VirtualNetwork* vn, goto error_not_base_addr; } - size = (1 << host_bits) - 2; - // Set IP start/end if ( ip_start == 0 ) { @@ -200,7 +204,7 @@ int RangedLeases::process_template(VirtualNetwork* vn, if ( ip_end == 0 ) { - ip_end = net_addr + size; + ip_end = net_addr + (1 << host_bits) - 2; } // Check range restrictions