mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-25 02:50:08 +03:00
feature #206: Moved the Virtual Network to new DB classes
This commit is contained in:
parent
4f74172044
commit
aeb27c1004
@ -22,31 +22,31 @@
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* The FixedLeases class represents a pool of fixed IP-MAC leases. A lease can
|
||||
* The FixedLeases class represents a pool of fixed IP-MAC leases. A lease can
|
||||
* be either a IP (the MAC is then PREFIX:IP) or the IP and MAC addresses. The
|
||||
* pool is read from a template file, each lease is in the form:
|
||||
* LEASE = [ IP = "<the ip>", MAC = "<the mac>"]
|
||||
*/
|
||||
*/
|
||||
class FixedLeases : public Leases
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a FixedLeases from template
|
||||
*/
|
||||
FixedLeases(SqliteDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix,
|
||||
vector<const Attribute*>& vector_leases);
|
||||
/**
|
||||
* Create a plain FixedLeases, you can populate the lease pool using
|
||||
* select()
|
||||
*/
|
||||
FixedLeases(SqliteDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix):
|
||||
Leases(db,_oid,0),
|
||||
mac_prefix(_mac_prefix),
|
||||
current(leases.begin()){};
|
||||
/**
|
||||
* Create a FixedLeases from template
|
||||
*/
|
||||
FixedLeases(SqlDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix,
|
||||
vector<const Attribute*>& vector_leases);
|
||||
/**
|
||||
* Create a plain FixedLeases, you can populate the lease pool using
|
||||
* select()
|
||||
*/
|
||||
FixedLeases(SqlDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix):
|
||||
Leases(db,_oid,0),
|
||||
mac_prefix(_mac_prefix),
|
||||
current(leases.begin()){};
|
||||
|
||||
~FixedLeases(){};
|
||||
|
||||
@ -58,7 +58,7 @@ public:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int get(int vid, string& ip, string& mac);
|
||||
|
||||
|
||||
/**
|
||||
* Ask for a specific lease in the network
|
||||
* @param vid identifier of the VM getting this lease
|
||||
@ -76,32 +76,32 @@ public:
|
||||
{
|
||||
del(ip);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the leases from the DB.
|
||||
*/
|
||||
int select(SqliteDB * db)
|
||||
int select(SqlDB * db)
|
||||
{
|
||||
//Read the leases from the DB
|
||||
int rc = Leases::select(db);
|
||||
//Update the size
|
||||
size = leases.size();
|
||||
|
||||
return rc;
|
||||
//Read the leases from the DB
|
||||
int rc = Leases::select(db);
|
||||
//Update the size
|
||||
size = leases.size();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The default MAC prefix for the OpenNebula cluster
|
||||
*/
|
||||
unsigned int mac_prefix;
|
||||
|
||||
/**
|
||||
* Current lease pointer
|
||||
*/
|
||||
map<unsigned int, Lease *>::iterator current;
|
||||
|
||||
|
||||
/**
|
||||
* The default MAC prefix for the OpenNebula cluster
|
||||
*/
|
||||
unsigned int mac_prefix;
|
||||
|
||||
/**
|
||||
* Current lease pointer
|
||||
*/
|
||||
map<unsigned int, Lease *>::iterator current;
|
||||
|
||||
/**
|
||||
* Add a lease, from the Lease interface
|
||||
* @param ip ip of the lease
|
||||
@ -110,7 +110,7 @@ private:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int add(const string& ip, const string& mac, int vid, bool used=true);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a lease, from the Lease interface
|
||||
* @param db pointer to DB
|
||||
|
@ -17,7 +17,6 @@
|
||||
#ifndef LEASES_H_
|
||||
#define LEASES_H_
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include "ObjectSQL.h"
|
||||
#include "Attribute.h"
|
||||
|
||||
@ -27,12 +26,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int leases_select_cb (
|
||||
void * _lease,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
/**
|
||||
* The Leases class represents all the IP and MAC addresses (lease) that can
|
||||
* be asigned (or are asigned) in a Virtual Network
|
||||
@ -46,13 +39,13 @@ public:
|
||||
* @param _oid the virtual network unique identifier
|
||||
* @param _size the max number of leases
|
||||
*/
|
||||
Leases(SqliteDB * _db, int _oid, unsigned long _size):
|
||||
Leases(SqlDB * _db, int _oid, unsigned long _size):
|
||||
oid(_oid), size(_size), db(_db){};
|
||||
|
||||
|
||||
virtual ~Leases()
|
||||
{
|
||||
map<unsigned int, Lease *>::iterator it;
|
||||
|
||||
|
||||
for(it=leases.begin();it!=leases.end();it++)
|
||||
{
|
||||
delete it->second;
|
||||
@ -78,7 +71,7 @@ public:
|
||||
* @return 0 if success
|
||||
*/
|
||||
virtual int set(int vid, const string& ip, string& mac) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Release an used lease, which becomes unused
|
||||
* @param ip of the lease in use
|
||||
@ -122,31 +115,31 @@ protected:
|
||||
};
|
||||
|
||||
~Lease(){};
|
||||
|
||||
|
||||
/**
|
||||
* Converts this lease's IP and MAC to string
|
||||
* @param ip ip of the lease in string
|
||||
* @param mac mac of the lease in string
|
||||
*/
|
||||
void to_string(string& _ip, string& _mac) const;
|
||||
|
||||
|
||||
/**
|
||||
* Conversion from string IP to unsigned int IP
|
||||
* @return 0 if success
|
||||
*/
|
||||
static int ip_to_number(const string& ip, unsigned int& i_ip);
|
||||
|
||||
|
||||
/**
|
||||
* Conversion from unsigned int IP to string IP
|
||||
*/
|
||||
static void ip_to_string(const unsigned int i_ip, string& ip);
|
||||
|
||||
|
||||
/**
|
||||
* Conversion from string MAC to unsigned int[] MAC
|
||||
* @return 0 if success
|
||||
*/
|
||||
static int mac_to_number(const string& mac, unsigned int i_mac[]);
|
||||
|
||||
|
||||
/**
|
||||
* Conversion from string IP to unsigned int IP
|
||||
*/
|
||||
@ -161,7 +154,7 @@ protected:
|
||||
* Function to print the Lease object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
@ -169,10 +162,10 @@ protected:
|
||||
* Function to print the Lease object into a string in
|
||||
* XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
|
||||
/**
|
||||
* Constants to access the array storing the MAC address
|
||||
*/
|
||||
@ -181,19 +174,19 @@ protected:
|
||||
SUFFIX = 0,/**< Lower significant 4 bytes */
|
||||
PREFIX = 1 /**< Higher significant 2 bytes */
|
||||
};
|
||||
|
||||
|
||||
unsigned int ip;
|
||||
|
||||
|
||||
unsigned int mac [2];
|
||||
|
||||
|
||||
int vid;
|
||||
|
||||
|
||||
bool used;
|
||||
};
|
||||
|
||||
friend class VirtualNetwork;
|
||||
friend class VirtualNetworkPool;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Leases fields
|
||||
// -------------------------------------------------------------------------
|
||||
@ -201,12 +194,12 @@ protected:
|
||||
* Leases indentifier. Connects it to a Virtual Network
|
||||
*/
|
||||
int oid;
|
||||
|
||||
|
||||
/**
|
||||
* Number of possible leases (free + asigned)
|
||||
*/
|
||||
unsigned int size;
|
||||
|
||||
|
||||
/**
|
||||
* Hash of leases, indexed by lease.ip
|
||||
*/
|
||||
@ -218,7 +211,7 @@ protected:
|
||||
/**
|
||||
* Pointer to the DataBase
|
||||
*/
|
||||
SqliteDB * db;
|
||||
SqlDB * db;
|
||||
|
||||
enum ColNames
|
||||
{
|
||||
@ -240,29 +233,30 @@ protected:
|
||||
// -------------------------------------------------------------------------
|
||||
// Leases methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if the passed ip corresponds with a given lease
|
||||
* @param ip of the lease to be checked
|
||||
* @return true if the ip was already assigned
|
||||
*/
|
||||
bool check(const string& ip);
|
||||
|
||||
bool check(unsigned int ip);
|
||||
bool check(const string& ip);
|
||||
|
||||
bool check(unsigned int ip);
|
||||
|
||||
/**
|
||||
* Reads the leases from the DB, and updates the lease hash table
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
virtual int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Reads the leases from the DB, and updates the lease hash table
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
virtual int select(SqliteDB * db);
|
||||
|
||||
friend ostream& operator<<(ostream& os, Lease& _lease);
|
||||
|
||||
/**
|
||||
* Function to print the Leases object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
@ -270,34 +264,27 @@ protected:
|
||||
* 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
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
private:
|
||||
|
||||
friend int leases_select_cb (
|
||||
void * _leases,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a leases object
|
||||
* Callback function to unmarshall a Lease object (Lease::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @para names the column names
|
||||
* @para vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int unmarshall(int num, char **names, char ** values);
|
||||
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* This method should not be called, leases are added/removed/updated
|
||||
* through add/del interface
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int insert(SqliteDB * db);
|
||||
int insert(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Leases are added/removed/updated through add/del interface
|
||||
@ -305,7 +292,7 @@ private:
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int drop(SqliteDB * db);
|
||||
int drop(SqlDB * db);
|
||||
|
||||
/**
|
||||
* This method should not be called, leases are added/removed/updated
|
||||
@ -313,7 +300,7 @@ private:
|
||||
* @param db pointer to the database.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int update(SqliteDB * db);
|
||||
int update(SqlDB * db);
|
||||
};
|
||||
|
||||
#endif /*LEASES_H_*/
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
RangedLeases(SqliteDB * db,
|
||||
RangedLeases(SqlDB * db,
|
||||
int _oid,
|
||||
unsigned long _size,
|
||||
unsigned int _mac_prefix,
|
||||
@ -53,40 +53,40 @@ public:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int set(int vid, const string& ip, string& mac);
|
||||
|
||||
|
||||
/**
|
||||
* Release an used lease, which becomes unused
|
||||
* @param ip of the lease in use
|
||||
*/
|
||||
void release(const string& ip)
|
||||
{
|
||||
del(ip);
|
||||
del(ip);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the leases from the DB.
|
||||
*/
|
||||
int select(SqliteDB * db)
|
||||
int select(SqlDB * db)
|
||||
{
|
||||
//Read the leases from the DB
|
||||
int rc = Leases::select(db);
|
||||
|
||||
return rc;
|
||||
//Read the leases from the DB
|
||||
int rc = Leases::select(db);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* The default MAC prefix for the OpenNebula cluster
|
||||
*/
|
||||
unsigned int mac_prefix;
|
||||
|
||||
/**
|
||||
* The Network address to generate leases
|
||||
*/
|
||||
unsigned int network_address;
|
||||
|
||||
unsigned int current;
|
||||
|
||||
/**
|
||||
* The default MAC prefix for the OpenNebula cluster
|
||||
*/
|
||||
unsigned int mac_prefix;
|
||||
|
||||
/**
|
||||
* The Network address to generate leases
|
||||
*/
|
||||
unsigned int network_address;
|
||||
|
||||
unsigned int current;
|
||||
|
||||
/**
|
||||
* Add a lease, from the Lease interface
|
||||
* @param ip ip of the lease
|
||||
@ -95,7 +95,7 @@ private:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int add(unsigned int ip, unsigned int mac[], int vid, bool used=true);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a lease, from the Lease interface
|
||||
* @param db pointer to DB
|
||||
@ -103,7 +103,7 @@ private:
|
||||
* @return 0 if success
|
||||
*/
|
||||
int del(const string& ip);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /*RANGED_LEASES_H_*/
|
||||
#endif /*RANGED_LEASES_H_*/
|
@ -31,10 +31,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" int vn_select_cb (void * _vn, int num,char ** values, char ** names);
|
||||
|
||||
extern "C" int vn_dump_cb (void * _oss, int num, char ** values, char ** names);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -61,7 +57,6 @@ public:
|
||||
// *************************************************************************
|
||||
// Virtual Network Public Methods
|
||||
// *************************************************************************
|
||||
|
||||
|
||||
/**
|
||||
* Gets the uid of the owner of the Virtual Network
|
||||
@ -128,7 +123,7 @@ public:
|
||||
* Function to print the VirtualNetwork object into a string in
|
||||
* plain text
|
||||
* @param str the resulting string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_str(string& str) const;
|
||||
|
||||
@ -136,10 +131,10 @@ public:
|
||||
* Function to print the VirtualNetwork object into a string in
|
||||
* XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -147,18 +142,6 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
friend class VirtualNetworkPool;
|
||||
|
||||
friend int vn_select_cb (
|
||||
void * _vm,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
friend int vn_dump_cb (
|
||||
void * _oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names);
|
||||
|
||||
// *************************************************************************
|
||||
// Virtual Network Private Attributes
|
||||
// *************************************************************************
|
||||
@ -169,12 +152,12 @@ private:
|
||||
/**
|
||||
* Name of the Virtual Network
|
||||
*/
|
||||
string name;
|
||||
string name;
|
||||
|
||||
/**
|
||||
* Owner of the Virtual Network
|
||||
*/
|
||||
int uid;
|
||||
int uid;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Binded physical attributes
|
||||
@ -183,7 +166,7 @@ private:
|
||||
/**
|
||||
* Name of the bridge this VNW binds to
|
||||
*/
|
||||
string bridge;
|
||||
string bridge;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Virtual Network Description
|
||||
@ -191,13 +174,13 @@ private:
|
||||
/**
|
||||
* Holds the type of this network
|
||||
*/
|
||||
NetworkType type;
|
||||
NetworkType type;
|
||||
|
||||
/**
|
||||
* Pointer to leases class, can be fixed or ranged.
|
||||
* Holds information on given (and, optionally, possible) leases
|
||||
*/
|
||||
Leases * leases;
|
||||
Leases * leases;
|
||||
|
||||
/**
|
||||
* The Virtual Network template, holds the VNW attributes.
|
||||
@ -211,12 +194,12 @@ private:
|
||||
/**
|
||||
* MAC prefix for this OpenNebula site
|
||||
*/
|
||||
unsigned int mac_prefix;
|
||||
unsigned int mac_prefix;
|
||||
|
||||
/**
|
||||
* Default size for virtual networks
|
||||
*/
|
||||
int default_size;
|
||||
int default_size;
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
@ -225,41 +208,31 @@ private:
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the Virtual Network
|
||||
*/
|
||||
static void bootstrap(SqliteDB * db)
|
||||
static void bootstrap(SqlDB * db)
|
||||
{
|
||||
db->exec(VirtualNetwork::db_bootstrap);
|
||||
ostringstream oss_vnet(VirtualNetwork::db_bootstrap);
|
||||
ostringstream oss_templ(VirtualNetworkTemplate::db_bootstrap);
|
||||
ostringstream oss_lease(Leases::db_bootstrap);
|
||||
|
||||
db->exec(VirtualNetworkTemplate::db_bootstrap);
|
||||
|
||||
db->exec(Leases::db_bootstrap);
|
||||
db->exec(oss_vnet);
|
||||
db->exec(oss_templ);
|
||||
db->exec(oss_lease);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to unmarshall a VNW object, and associated classes.
|
||||
* Callback function to unmarshall a VNW object (VirtualNetwork::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @para names the column names
|
||||
* @para vaues the column values
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int unmarshall(int num, char **names, char ** values);
|
||||
int select_cb(void * nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Function to unmarshall a VNW object into an stream in XML format.
|
||||
* @param oss the output stream
|
||||
* @param num the number of columns read from the DB
|
||||
* @para names the column names
|
||||
* @para vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values);
|
||||
/**
|
||||
* Function to drop VN entry in vn_pool
|
||||
* @return 0 on success
|
||||
*/
|
||||
int vn_drop(SqliteDB * db);
|
||||
int vn_drop(SqlDB * db);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
@ -321,15 +294,15 @@ private:
|
||||
/**
|
||||
* Updates the template of a VNW, adding a new attribute (replacing it if
|
||||
* already defined), the VN's mutex SHOULD be locked
|
||||
* @param vm pointer to the virtual network object
|
||||
* @param db pointer to the DB
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
SqliteDB * db,
|
||||
string& name,
|
||||
string& value)
|
||||
SqlDB * db,
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
int rc;
|
||||
@ -380,21 +353,21 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select(SqliteDB * db);
|
||||
int select(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes the Virtual Network and its associated template and leases in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(SqliteDB * db);
|
||||
int insert(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Writes/updates the Virtual Network data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqliteDB * db);
|
||||
int update(SqlDB * db);
|
||||
|
||||
/**
|
||||
* Deletes a VNW from the database and all its associated information:
|
||||
@ -403,28 +376,29 @@ protected:
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int drop(SqliteDB * db)
|
||||
int drop(SqlDB * db)
|
||||
{
|
||||
int rc;
|
||||
int rc;
|
||||
|
||||
rc = vn_template.drop(db);
|
||||
rc = vn_template.drop(db);
|
||||
|
||||
rc += leases->drop(db);
|
||||
|
||||
rc += vn_drop(db);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the contect of a set of Host objects in the given stream
|
||||
* using XML format
|
||||
* @param db pointer to the db
|
||||
* Dumps the contect of a VirtualNetwork object in the given stream using
|
||||
* XML format
|
||||
* @param oss the output stream
|
||||
* @param where string to filter the VirtualMachine objects
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int dump(SqliteDB * db, ostringstream& oss, const string& where);
|
||||
static int dump(ostringstream& oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_NETWORK_H_*/
|
||||
#endif /*VIRTUAL_NETWORK_H_*/
|
@ -32,9 +32,9 @@ class VirtualNetworkPool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
|
||||
VirtualNetworkPool(SqliteDB * db,
|
||||
const string& str_mac_prefix,
|
||||
int default_size);
|
||||
VirtualNetworkPool(SqlDB * db,
|
||||
const string& str_mac_prefix,
|
||||
int default_size);
|
||||
|
||||
~VirtualNetworkPool(){};
|
||||
|
||||
@ -74,7 +74,7 @@ public:
|
||||
*/
|
||||
VirtualNetwork * get(
|
||||
const string& name,
|
||||
bool lock);
|
||||
bool lock);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Virtual Network DB access functions
|
||||
@ -89,41 +89,30 @@ public:
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update_template_attribute(
|
||||
VirtualNetwork * vn,
|
||||
string& name,
|
||||
string& value)
|
||||
VirtualNetwork * vn,
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
return vn->update_template_attribute(db,name,value);
|
||||
return vn->update_template_attribute(db,name,value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VirtualNetwork pool
|
||||
*/
|
||||
static void bootstrap(SqliteDB * _db)
|
||||
static void bootstrap(SqlDB * _db)
|
||||
{
|
||||
VirtualNetwork::bootstrap(_db);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dumps the HOST pool in XML format. A filter can be also added to the
|
||||
* query
|
||||
* Dumps the Virtual Network pool in XML format. A filter can be also added
|
||||
* to the query
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* @param where filter for the objects, defaults to all
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
|
||||
oss << "<VNET_POOL>";
|
||||
|
||||
rc = VirtualNetwork::dump(db,oss,where);
|
||||
|
||||
oss << "</VNET_POOL>";
|
||||
|
||||
return rc;
|
||||
}
|
||||
int dump(ostringstream& oss, const string& where);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -145,6 +134,25 @@ private:
|
||||
return new VirtualNetwork(mac_prefix, default_size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function to get output the virtual network pool in XML format
|
||||
* (VirtualNetworkPool::dump)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump_cb(void * _oss, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Callback function to get the ID of a given virtual network
|
||||
* (VirtualNetworkPool::get)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int get_cb(void * _oss, int num, char **values, char **names);
|
||||
};
|
||||
|
||||
#endif /*VIRTUAL_NETWORK_POOL_H_*/
|
||||
#endif /*VIRTUAL_NETWORK_POOL_H_*/
|
@ -19,30 +19,30 @@
|
||||
#include "Nebula.h"
|
||||
|
||||
FixedLeases::FixedLeases(
|
||||
SqliteDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix,
|
||||
vector<const Attribute*>& vector_leases):
|
||||
Leases(db,_oid,0),mac_prefix(_mac_prefix),current(leases.begin())
|
||||
{
|
||||
SqlDB * db,
|
||||
int _oid,
|
||||
unsigned int _mac_prefix,
|
||||
vector<const Attribute*>& vector_leases):
|
||||
Leases(db,_oid,0),mac_prefix(_mac_prefix),current(leases.begin())
|
||||
{
|
||||
const VectorAttribute * single_attr_lease;
|
||||
string _mac;
|
||||
string _ip;
|
||||
|
||||
|
||||
size = vector_leases.size();
|
||||
|
||||
|
||||
for (unsigned long i=0; i < size ;i++)
|
||||
{
|
||||
single_attr_lease = dynamic_cast<const VectorAttribute *>
|
||||
(vector_leases[i]);
|
||||
|
||||
single_attr_lease = dynamic_cast<const VectorAttribute *>
|
||||
(vector_leases[i]);
|
||||
|
||||
if( single_attr_lease )
|
||||
{
|
||||
_ip = single_attr_lease->vector_value("IP");
|
||||
_mac = single_attr_lease->vector_value("MAC");
|
||||
|
||||
add(_ip,_mac,-1,false);
|
||||
}
|
||||
|
||||
add(_ip,_mac,-1,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,24 +54,24 @@ int FixedLeases::add(const string& ip, const string& mac, int vid, bool used)
|
||||
ostringstream oss;
|
||||
unsigned int _ip;
|
||||
unsigned int _mac [2];
|
||||
|
||||
|
||||
int rc;
|
||||
|
||||
|
||||
if ( Leases::Lease::ip_to_number(ip,_ip) )
|
||||
{
|
||||
goto error_ip;
|
||||
goto error_ip;
|
||||
}
|
||||
|
||||
|
||||
if (mac.empty())
|
||||
{
|
||||
_mac[Lease::PREFIX] = mac_prefix;
|
||||
_mac[Lease::SUFFIX] = _ip;
|
||||
_mac[Lease::PREFIX] = mac_prefix;
|
||||
_mac[Lease::SUFFIX] = _ip;
|
||||
}
|
||||
else if (Leases::Lease::mac_to_number(mac,_mac))
|
||||
{
|
||||
goto error_mac;
|
||||
goto error_mac;
|
||||
}
|
||||
|
||||
|
||||
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES (" <<
|
||||
oid << "," <<
|
||||
_ip << "," <<
|
||||
@ -81,19 +81,19 @@ int FixedLeases::add(const string& ip, const string& mac, int vid, bool used)
|
||||
used << ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
leases.insert(make_pair(_ip,new Lease(_ip,_mac,vid,used)));
|
||||
leases.insert(make_pair(_ip,new Lease(_ip,_mac,vid,used)));
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
|
||||
error_mac:
|
||||
oss.str("");
|
||||
oss << "Error inserting lease, MAC = " << mac;
|
||||
goto error_common;
|
||||
|
||||
|
||||
error_ip:
|
||||
oss.str("");
|
||||
oss << "Error inserting lease, IP = " << ip;
|
||||
@ -108,33 +108,33 @@ error_common:
|
||||
|
||||
int FixedLeases::del(const string& ip)
|
||||
{
|
||||
unsigned int _ip;
|
||||
unsigned int _ip;
|
||||
ostringstream oss;
|
||||
|
||||
|
||||
map<unsigned int, Lease *>::iterator it_ip;
|
||||
|
||||
|
||||
// Remove lease from leases map
|
||||
|
||||
|
||||
if ( Leases::Lease::ip_to_number(ip,_ip) )
|
||||
{
|
||||
return 0; //Wrong format, not leased
|
||||
return 0; //Wrong format, not leased
|
||||
}
|
||||
|
||||
|
||||
it_ip = leases.find(_ip);
|
||||
|
||||
|
||||
if (it_ip == leases.end())
|
||||
{
|
||||
return 0; //Not in the map, not leased
|
||||
return 0; //Not in the map, not leased
|
||||
}
|
||||
|
||||
// Flip used flag to false
|
||||
|
||||
|
||||
it_ip->second->used = false;
|
||||
it_ip->second->vid = -1;
|
||||
|
||||
oss << "UPDATE " << table << " SET used='0', vid='-1' "
|
||||
<< " WHERE ip='" << _ip <<"'";
|
||||
|
||||
|
||||
oss << "UPDATE " << table << " SET used='0', vid='-1' "
|
||||
<< " WHERE ip='" << _ip <<"'";
|
||||
|
||||
return db->exec(oss);
|
||||
}
|
||||
|
||||
@ -142,45 +142,45 @@ int FixedLeases::del(const string& ip)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int FixedLeases::get(int vid, string& ip, string& mac)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
if (leases.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(unsigned int i=0 ;i<size; i++,current++)
|
||||
{
|
||||
if (current == leases.end())
|
||||
{
|
||||
current = leases.begin();
|
||||
}
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
if (current->second->used == false)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "UPDATE " << table << " SET used='1', vid='" << vid
|
||||
<< "' WHERE ip='" << current->second->ip <<"'";
|
||||
if (leases.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
current->second->used = true;
|
||||
current->second->vid = vid;
|
||||
|
||||
current->second->to_string(ip,mac);
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
for(unsigned int i=0 ;i<size; i++,current++)
|
||||
{
|
||||
if (current == leases.end())
|
||||
{
|
||||
current = leases.begin();
|
||||
}
|
||||
|
||||
if (current->second->used == false)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "UPDATE " << table << " SET used='1', vid='" << vid
|
||||
<< "' WHERE ip='" << current->second->ip <<"'";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
current->second->used = true;
|
||||
current->second->vid = vid;
|
||||
|
||||
current->second->to_string(ip,mac);
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -188,45 +188,45 @@ int FixedLeases::get(int vid, string& ip, string& mac)
|
||||
|
||||
int FixedLeases::set(int vid, const string& ip, string& mac)
|
||||
{
|
||||
map<unsigned int,Lease *>::iterator it;
|
||||
|
||||
ostringstream oss;
|
||||
unsigned int num_ip;
|
||||
int rc;
|
||||
|
||||
rc = Leases::Lease::ip_to_number(ip,num_ip);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
map<unsigned int,Lease *>::iterator it;
|
||||
|
||||
ostringstream oss;
|
||||
unsigned int num_ip;
|
||||
int rc;
|
||||
|
||||
rc = Leases::Lease::ip_to_number(ip,num_ip);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
it=leases.find(num_ip);
|
||||
|
||||
if (it == leases.end()) //it does not exists in the net
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
else if (it->second->used) //it is in use
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
oss << "UPDATE " << table << " SET used='1', vid='" << vid
|
||||
<< "' WHERE ip='" << it->second->ip <<"'";
|
||||
|
||||
oss << "UPDATE " << table << " SET used='1', vid='" << vid
|
||||
<< "' WHERE ip='" << it->second->ip <<"'";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
it->second->used = true;
|
||||
it->second->vid = vid;
|
||||
|
||||
|
||||
Leases::Lease::mac_to_string(it->second->mac,mac);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -187,31 +187,31 @@ ostream& operator<<(ostream& os, Leases::Lease& _lease)
|
||||
string xml;
|
||||
|
||||
os << _lease.to_xml(xml);
|
||||
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
string& Leases::Lease::to_str(string& str) const
|
||||
{
|
||||
string ip;
|
||||
string mac;
|
||||
|
||||
string ip;
|
||||
string mac;
|
||||
|
||||
ostringstream os;
|
||||
|
||||
to_string(ip,mac);
|
||||
|
||||
|
||||
ip = "IP = " + ip;
|
||||
mac = "MAC = " + mac;
|
||||
|
||||
|
||||
os.width(20);
|
||||
os << left << ip;
|
||||
|
||||
|
||||
os.width(24);
|
||||
os << left << mac;
|
||||
|
||||
os << left << " USED = " << used;
|
||||
|
||||
os << left << " USED = " << used;
|
||||
os << left << " VID = " << vid;
|
||||
|
||||
|
||||
str = os.str();
|
||||
|
||||
return str;
|
||||
@ -220,14 +220,14 @@ string& Leases::Lease::to_str(string& str) const
|
||||
|
||||
string& Leases::Lease::to_xml(string& str) const
|
||||
{
|
||||
string ip;
|
||||
string mac;
|
||||
|
||||
string ip;
|
||||
string mac;
|
||||
|
||||
ostringstream os;
|
||||
|
||||
to_string(ip,mac);
|
||||
|
||||
os <<
|
||||
|
||||
os <<
|
||||
"<LEASE>" <<
|
||||
"<IP>"<< ip << "</IP>" <<
|
||||
"<MAC>" << mac << "</MAC>" <<
|
||||
@ -251,13 +251,13 @@ const char * Leases::table = "leases";
|
||||
const char * Leases::db_names = "(oid,ip,mac_prefix,mac_suffix,vid,used)";
|
||||
|
||||
const char * Leases::db_bootstrap = "CREATE TABLE leases ("
|
||||
"oid INTEGER,ip INTEGER, mac_prefix INTEGER,mac_suffix INTEGER,"
|
||||
"oid INTEGER,ip INTEGER, mac_prefix INTEGER,mac_suffix INTEGER,"
|
||||
"vid INTEGER, used INTEGER, PRIMARY KEY(oid,ip))";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Leases::unmarshall(int num, char **names, char ** values)
|
||||
int Leases::select_cb(void *nil, int num, char **values, char **names)
|
||||
{
|
||||
if ( (values[OID] == 0) ||
|
||||
(values[IP] == 0) ||
|
||||
@ -274,65 +274,45 @@ int Leases::unmarshall(int num, char **names, char ** values)
|
||||
unsigned int ip;
|
||||
int vid;
|
||||
bool used;
|
||||
|
||||
|
||||
istringstream iss;
|
||||
|
||||
|
||||
iss.str(values[IP]);
|
||||
iss >> ip;
|
||||
|
||||
|
||||
iss.clear();
|
||||
iss.str(values[MAC_PREFIX]);
|
||||
iss >> mac[Lease::PREFIX];
|
||||
|
||||
|
||||
iss.clear();
|
||||
iss.str(values[MAC_SUFFIX]);
|
||||
iss >> mac[Lease::SUFFIX];
|
||||
|
||||
|
||||
iss.clear();
|
||||
iss.str(values[VID]);
|
||||
iss >> vid;
|
||||
|
||||
|
||||
iss.clear();
|
||||
iss.str(values[USED]);
|
||||
iss >> used;
|
||||
|
||||
leases.insert(make_pair(ip,new Lease(ip,mac,vid,used)));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int leases_select_cb (
|
||||
void * _leases,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
Leases * leases;
|
||||
|
||||
leases = static_cast<Leases *>(_leases);
|
||||
|
||||
if (leases == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return leases->unmarshall(num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Leases::select(SqliteDB * db)
|
||||
int Leases::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
set_callback(static_cast<Callbackable::Callback>(&Leases::select_cb));
|
||||
|
||||
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
rc = db->exec(oss,leases_select_cb,(void *) this);
|
||||
rc = db->exec(oss,this);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
@ -342,9 +322,9 @@ int Leases::select(SqliteDB * db)
|
||||
return 0;
|
||||
|
||||
error_id:
|
||||
oss.str("");
|
||||
oss.str("");
|
||||
oss << "Error getting leases for network nid: " << oid;
|
||||
|
||||
|
||||
Nebula::log("VNM", Log::ERROR, oss);
|
||||
return -1;
|
||||
}
|
||||
@ -352,11 +332,11 @@ error_id:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Leases::drop(SqliteDB * db)
|
||||
int Leases::drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
// Drop all the leases
|
||||
|
||||
// Drop all the leases
|
||||
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
|
||||
|
||||
return db->exec(oss);
|
||||
@ -365,7 +345,7 @@ int Leases::drop(SqliteDB * db)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Leases::insert(SqliteDB * db)
|
||||
int Leases::insert(SqlDB * db)
|
||||
{
|
||||
Nebula::log("VNM", Log::ERROR, "Should not access to Leases.insert()");
|
||||
return -1;
|
||||
@ -374,7 +354,7 @@ int Leases::insert(SqliteDB * db)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Leases::update(SqliteDB * db)
|
||||
int Leases::update(SqlDB * db)
|
||||
{
|
||||
Nebula::log("VNM", Log::ERROR, "Should not access to Leases.update()");
|
||||
return -1;
|
||||
@ -461,7 +441,7 @@ string& Leases::to_str(string& str) const
|
||||
{
|
||||
os << it->second->to_str(lease_str) << endl;
|
||||
}
|
||||
|
||||
|
||||
str = os.str();
|
||||
|
||||
return str;
|
||||
|
@ -24,7 +24,7 @@
|
||||
/* Virtual Network :: Constructor/Destructor */
|
||||
/* ************************************************************************** */
|
||||
|
||||
VirtualNetwork::VirtualNetwork(unsigned int mp, int ds):
|
||||
VirtualNetwork::VirtualNetwork(unsigned int mp, int ds):
|
||||
PoolObjectSQL(-1),
|
||||
name(""),
|
||||
uid(-1),
|
||||
@ -32,19 +32,17 @@ VirtualNetwork::VirtualNetwork(unsigned int mp, int ds):
|
||||
type(UNINITIALIZED),
|
||||
leases(0),
|
||||
mac_prefix(mp),
|
||||
default_size(ds)
|
||||
{
|
||||
}
|
||||
default_size(ds){};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
VirtualNetwork::~VirtualNetwork()
|
||||
{
|
||||
{
|
||||
if (leases != 0)
|
||||
{
|
||||
delete leases;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
@ -61,13 +59,13 @@ const char * VirtualNetwork::db_bootstrap = "CREATE TABLE network_pool ("
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::unmarshall(int num, char **names, char ** values)
|
||||
int VirtualNetwork::select_cb(void * nil, int num, char **values, char **names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[UID]) ||
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[BRIDGE]) ||
|
||||
(!values[BRIDGE]) ||
|
||||
(num != LIMIT ))
|
||||
{
|
||||
return -1;
|
||||
@ -75,14 +73,14 @@ int VirtualNetwork::unmarshall(int num, char **names, char ** values)
|
||||
|
||||
oid = atoi(values[OID]);
|
||||
uid = atoi(values[UID]);
|
||||
|
||||
|
||||
name = values[NAME];
|
||||
|
||||
|
||||
type = (NetworkType)atoi(values[TYPE]);
|
||||
|
||||
|
||||
bridge = values[BRIDGE];
|
||||
|
||||
// Virtual Network template ID is the Network ID
|
||||
|
||||
// Virtual Network template ID is the Network ID
|
||||
vn_template.id = oid;
|
||||
|
||||
return 0;
|
||||
@ -91,48 +89,31 @@ int VirtualNetwork::unmarshall(int num, char **names, char ** values)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int vn_select_cb (
|
||||
void * _vn,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
VirtualNetwork * vn;
|
||||
|
||||
vn = static_cast<VirtualNetwork *>(_vn);
|
||||
|
||||
if (vn == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return vn->unmarshall(num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::select(SqliteDB * db)
|
||||
int VirtualNetwork::select(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
ostringstream ose;
|
||||
|
||||
|
||||
int rc;
|
||||
int boid;
|
||||
|
||||
string network_address;
|
||||
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualNetwork::select_cb));
|
||||
|
||||
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
|
||||
|
||||
boid = oid;
|
||||
oid = -1;
|
||||
|
||||
rc = db->exec(oss,vn_select_cb,(void *) this);
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
if ((rc != 0) || (oid != boid ))
|
||||
{
|
||||
goto error_id;
|
||||
}
|
||||
|
||||
|
||||
//Get the template
|
||||
rc = vn_template.select(db);
|
||||
|
||||
@ -144,38 +125,38 @@ int VirtualNetwork::select(SqliteDB * db)
|
||||
//Get the leases
|
||||
if (type == RANGED)
|
||||
{
|
||||
string nclass = "";
|
||||
int size = 0;
|
||||
|
||||
string nclass = "";
|
||||
int size = 0;
|
||||
|
||||
// retrieve specific information from template
|
||||
get_template_attribute("NETWORK_ADDRESS",network_address);
|
||||
|
||||
|
||||
if (network_address.empty())
|
||||
{
|
||||
goto error_addr;
|
||||
goto error_addr;
|
||||
}
|
||||
|
||||
|
||||
get_template_attribute("NETWORK_SIZE",nclass);
|
||||
|
||||
|
||||
if ( nclass == "B" )
|
||||
{
|
||||
size = 65534;
|
||||
size = 65534;
|
||||
}
|
||||
else if ( nclass == "C" )
|
||||
{
|
||||
size = 254;
|
||||
size = 254;
|
||||
}
|
||||
else if (!nclass.empty()) //Assume its a number
|
||||
{
|
||||
istringstream iss(nclass);
|
||||
iss >> size;
|
||||
istringstream iss(nclass);
|
||||
iss >> size;
|
||||
}
|
||||
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
size = default_size;
|
||||
size = default_size;
|
||||
}
|
||||
|
||||
|
||||
leases = new RangedLeases::RangedLeases(db,
|
||||
oid,
|
||||
size,
|
||||
@ -184,59 +165,59 @@ int VirtualNetwork::select(SqliteDB * db)
|
||||
}
|
||||
else if(type == FIXED)
|
||||
{
|
||||
leases = new FixedLeases(db,
|
||||
leases = new FixedLeases(db,
|
||||
oid,
|
||||
mac_prefix);
|
||||
mac_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_type;
|
||||
goto error_type;
|
||||
}
|
||||
|
||||
|
||||
if (leases == 0)
|
||||
{
|
||||
goto error_leases;
|
||||
}
|
||||
|
||||
|
||||
return leases->select(db);
|
||||
|
||||
error_id:
|
||||
ose << "Error getting Virtual Network nid: " << oid;
|
||||
goto error_common;
|
||||
goto error_common;
|
||||
|
||||
error_template:
|
||||
ose << "Can not get template for Virtual Network nid: " << oid;
|
||||
goto error_common;
|
||||
|
||||
goto error_common;
|
||||
|
||||
error_leases:
|
||||
ose << "Error getting Virtual Network leases nid: " << oid;
|
||||
goto error_common;
|
||||
goto error_common;
|
||||
|
||||
error_type:
|
||||
ose << "Wrong type of Virtual Network: " << type;
|
||||
ose << "Wrong type of Virtual Network: " << type;
|
||||
goto error_common;
|
||||
|
||||
|
||||
error_addr:
|
||||
ose << "Network address is not defined nid: " << oid;
|
||||
|
||||
ose << "Network address is not defined nid: " << oid;
|
||||
|
||||
error_common:
|
||||
Nebula::log("VNM", Log::ERROR, ose);
|
||||
return -1;
|
||||
Nebula::log("VNM", Log::ERROR, ose);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::unmarshall(ostringstream& oss,
|
||||
int num,
|
||||
char ** names,
|
||||
char ** values)
|
||||
int VirtualNetwork::dump(ostringstream& oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
if ((!values[OID]) ||
|
||||
(!values[UID]) ||
|
||||
(!values[NAME]) ||
|
||||
(!values[TYPE]) ||
|
||||
(!values[BRIDGE])||
|
||||
(!values[BRIDGE])||
|
||||
(!values[LIMIT]) ||
|
||||
(num != LIMIT + 2 ))
|
||||
{
|
||||
@ -258,62 +239,13 @@ int VirtualNetwork::unmarshall(ostringstream& oss,
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" int vn_dump_cb (
|
||||
void * _oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
if (oss == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return VirtualNetwork::unmarshall(*oss,num,names,values);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::dump(SqliteDB * db, ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
cmd << "SELECT " << VirtualNetwork::table << ".*,COUNT("
|
||||
<< Leases::table << ".used), user_pool.user_name FROM "
|
||||
<< VirtualNetwork::table
|
||||
<< " LEFT OUTER JOIN " << Leases::table << " ON "
|
||||
<< VirtualNetwork::table << ".oid = " << Leases::table << ".oid"
|
||||
<< " AND " << Leases::table << ".used = 1"
|
||||
<< " LEFT OUTER JOIN (SELECT oid,user_name FROM user_pool) "
|
||||
<< " AS user_pool ON "<< VirtualNetwork::table << ".uid = user_pool.oid";
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
cmd << " GROUP BY " << VirtualNetwork::table << ".oid";
|
||||
|
||||
rc = db->exec(cmd,vn_dump_cb,(void *) &oss);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::insert(SqliteDB * db)
|
||||
int VirtualNetwork::insert(SqlDB * db)
|
||||
{
|
||||
ostringstream ose;
|
||||
int rc;
|
||||
|
||||
|
||||
if ( vn_template.id == -1 )
|
||||
{
|
||||
vn_template.id = oid;
|
||||
@ -332,90 +264,90 @@ int VirtualNetwork::insert(SqliteDB * db)
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_update;
|
||||
goto error_update;
|
||||
}
|
||||
|
||||
//Get the leases
|
||||
if (type == VirtualNetwork::RANGED)
|
||||
{
|
||||
string nclass = "";
|
||||
string naddr = "";
|
||||
int size = 0;
|
||||
|
||||
// retrieve specific information from template
|
||||
get_template_attribute("NETWORK_ADDRESS",naddr);
|
||||
|
||||
if (naddr.empty())
|
||||
{
|
||||
goto error_addr;
|
||||
}
|
||||
|
||||
get_template_attribute("NETWORK_SIZE",nclass);
|
||||
|
||||
if ( nclass == "B" )
|
||||
{
|
||||
size = 65534;
|
||||
}
|
||||
else if ( nclass == "C" )
|
||||
{
|
||||
size = 254;
|
||||
}
|
||||
else if (!nclass.empty())//Assume its a number
|
||||
{
|
||||
istringstream iss(nclass);
|
||||
|
||||
iss >> size;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
size = default_size;
|
||||
}
|
||||
|
||||
leases = new RangedLeases::RangedLeases(db,
|
||||
oid,
|
||||
size,
|
||||
mac_prefix,
|
||||
naddr);
|
||||
}
|
||||
else if(type == VirtualNetwork::FIXED)
|
||||
{
|
||||
vector<const Attribute *> vector_leases;
|
||||
|
||||
get_template_attribute("LEASES",vector_leases);
|
||||
//Get the leases
|
||||
if (type == VirtualNetwork::RANGED)
|
||||
{
|
||||
string nclass = "";
|
||||
string naddr = "";
|
||||
int size = 0;
|
||||
|
||||
leases = new FixedLeases::FixedLeases(db,
|
||||
oid,
|
||||
mac_prefix,
|
||||
vector_leases);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_type;
|
||||
}
|
||||
|
||||
if (leases == 0)
|
||||
{
|
||||
goto error_null_leases;
|
||||
}
|
||||
|
||||
return 0;
|
||||
// retrieve specific information from template
|
||||
get_template_attribute("NETWORK_ADDRESS",naddr);
|
||||
|
||||
if (naddr.empty())
|
||||
{
|
||||
goto error_addr;
|
||||
}
|
||||
|
||||
get_template_attribute("NETWORK_SIZE",nclass);
|
||||
|
||||
if ( nclass == "B" )
|
||||
{
|
||||
size = 65534;
|
||||
}
|
||||
else if ( nclass == "C" )
|
||||
{
|
||||
size = 254;
|
||||
}
|
||||
else if (!nclass.empty())//Assume its a number
|
||||
{
|
||||
istringstream iss(nclass);
|
||||
|
||||
iss >> size;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
size = default_size;
|
||||
}
|
||||
|
||||
leases = new RangedLeases::RangedLeases(db,
|
||||
oid,
|
||||
size,
|
||||
mac_prefix,
|
||||
naddr);
|
||||
}
|
||||
else if(type == VirtualNetwork::FIXED)
|
||||
{
|
||||
vector<const Attribute *> vector_leases;
|
||||
|
||||
get_template_attribute("LEASES",vector_leases);
|
||||
|
||||
leases = new FixedLeases::FixedLeases(db,
|
||||
oid,
|
||||
mac_prefix,
|
||||
vector_leases);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_type;
|
||||
}
|
||||
|
||||
if (leases == 0)
|
||||
{
|
||||
goto error_null_leases;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_template:
|
||||
ose << "Can not insert in DB template for Virtual Network id " << oid;
|
||||
ose << "Can not insert in DB template for Virtual Network id " << oid;
|
||||
goto error_common;
|
||||
|
||||
error_update:
|
||||
ose << "Can not update Virtual Network id " << oid;
|
||||
vn_template.drop(db);
|
||||
goto error_common;
|
||||
ose << "Can not update Virtual Network id " << oid;
|
||||
vn_template.drop(db);
|
||||
goto error_common;
|
||||
|
||||
error_type:
|
||||
ose << "Wrong type of Virtual Network: " << type;
|
||||
ose << "Wrong type of Virtual Network: " << type;
|
||||
goto error_leases;
|
||||
|
||||
error_addr:
|
||||
ose << "Network address is not defined nid: " << oid;
|
||||
ose << "Network address is not defined nid: " << oid;
|
||||
goto error_leases;
|
||||
|
||||
error_null_leases:
|
||||
@ -425,30 +357,30 @@ error_leases:
|
||||
vn_drop(db);
|
||||
|
||||
error_common:
|
||||
Nebula::log("VNM", Log::ERROR, ose);
|
||||
Nebula::log("VNM", Log::ERROR, ose);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::update(SqliteDB * db)
|
||||
int VirtualNetwork::update(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
char * sql_name = sqlite3_mprintf("%q",name.c_str());
|
||||
|
||||
char * sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char * sql_bridge = sqlite3_mprintf("%q",bridge.c_str());
|
||||
char * sql_bridge = db->escape_str(bridge.c_str());
|
||||
|
||||
if ( sql_bridge == 0 )
|
||||
{
|
||||
sqlite3_free(sql_name);
|
||||
db->free_str(sql_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -458,29 +390,29 @@ int VirtualNetwork::update(SqliteDB * db)
|
||||
"'" << sql_name << "'," <<
|
||||
type << "," <<
|
||||
"'" << sql_bridge << "')";
|
||||
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
sqlite3_free(sql_name);
|
||||
sqlite3_free(sql_bridge);
|
||||
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_bridge);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetwork::vn_drop(SqliteDB * db)
|
||||
int VirtualNetwork::vn_drop(SqlDB * db)
|
||||
{
|
||||
ostringstream oss;
|
||||
int rc;
|
||||
|
||||
vn_template.drop(db);
|
||||
vn_template.drop(db);
|
||||
|
||||
leases->drop(db);
|
||||
|
||||
oss << "DELETE FROM " << table << " WHERE OID=" << oid;
|
||||
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
if ( rc == 0 )
|
||||
@ -488,7 +420,7 @@ int VirtualNetwork::vn_drop(SqliteDB * db)
|
||||
set_valid(false);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -501,8 +433,8 @@ ostream& operator<<(ostream& os, VirtualNetwork& vn)
|
||||
{
|
||||
string vnet_xml;
|
||||
|
||||
os << vn.to_xml(vnet_xml);
|
||||
|
||||
os << vn.to_xml(vnet_xml);
|
||||
|
||||
return os;
|
||||
};
|
||||
|
||||
@ -516,7 +448,7 @@ string& VirtualNetwork::to_xml(string& xml) const
|
||||
string template_xml;
|
||||
string leases_xml;
|
||||
|
||||
os <<
|
||||
os <<
|
||||
"<VNET>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
@ -527,7 +459,7 @@ string& VirtualNetwork::to_xml(string& xml) const
|
||||
if (leases)
|
||||
os << leases->to_xml(leases_xml);
|
||||
os << "</VNET>";
|
||||
|
||||
|
||||
xml = os.str();
|
||||
|
||||
return xml;
|
||||
@ -542,7 +474,7 @@ string& VirtualNetwork::to_str(string& str) const
|
||||
|
||||
string template_str;
|
||||
string leases_str;
|
||||
|
||||
|
||||
os << "ID : " << oid << endl;
|
||||
os << "UID : " << uid << endl;
|
||||
os << "NAME : " << name << endl;
|
||||
@ -555,21 +487,20 @@ string& VirtualNetwork::to_str(string& str) const
|
||||
{
|
||||
os << "Fixed" << endl;
|
||||
}
|
||||
|
||||
|
||||
os << "Bridge : " << bridge << endl << endl;
|
||||
|
||||
os << "....: Template :...." << vn_template.to_str(template_str) << endl << endl;
|
||||
|
||||
|
||||
if (leases)
|
||||
{
|
||||
os << "....: Leases :...." << endl << leases->to_str(leases_str) << endl;
|
||||
}
|
||||
|
||||
|
||||
str = os.str();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
@ -18,12 +18,12 @@
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include <sstream>
|
||||
|
||||
VirtualNetworkPool::VirtualNetworkPool(SqliteDB * db,
|
||||
const string& prefix,
|
||||
int _default_size):
|
||||
PoolSQL(db,VirtualNetwork::table),
|
||||
mac_prefix(0),
|
||||
default_size(_default_size)
|
||||
VirtualNetworkPool::VirtualNetworkPool(SqlDB * db,
|
||||
const string& prefix,
|
||||
int _default_size):
|
||||
PoolSQL(db,VirtualNetwork::table),
|
||||
mac_prefix(0),
|
||||
default_size(_default_size)
|
||||
{
|
||||
istringstream iss;
|
||||
size_t pos = 0;
|
||||
@ -34,16 +34,16 @@ VirtualNetworkPool::VirtualNetworkPool(SqliteDB * db,
|
||||
|
||||
while ( (pos = mac.find(':')) != string::npos )
|
||||
{
|
||||
mac.replace(pos,1," ");
|
||||
count++;
|
||||
mac.replace(pos,1," ");
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
Nebula::log("VNM",Log::ERROR,"Wrong MAC prefix format, using default");
|
||||
mac_prefix = 1; //"00:01"
|
||||
|
||||
return;
|
||||
Nebula::log("VNM",Log::ERROR,"Wrong MAC prefix format, using default");
|
||||
mac_prefix = 1; //"00:01"
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iss.str(mac);
|
||||
@ -55,41 +55,41 @@ VirtualNetworkPool::VirtualNetworkPool(SqliteDB * db,
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
int VirtualNetworkPool::allocate (
|
||||
int uid,
|
||||
const string& stemplate,
|
||||
int * oid)
|
||||
{
|
||||
VirtualNetwork * vn;
|
||||
char * error_msg;
|
||||
VirtualNetwork * vn;
|
||||
char * error_msg;
|
||||
int rc;
|
||||
ostringstream oss;
|
||||
ostringstream oss;
|
||||
|
||||
string name;
|
||||
string bridge;
|
||||
|
||||
|
||||
string str_type;
|
||||
|
||||
|
||||
// Build a new Virtual Network object
|
||||
vn = new VirtualNetwork(mac_prefix, default_size);
|
||||
|
||||
|
||||
vn->uid = uid;
|
||||
|
||||
|
||||
rc = vn->vn_template.parse(stemplate,&error_msg);
|
||||
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
oss << error_msg;
|
||||
oss << error_msg;
|
||||
Nebula::log("VNM", Log::ERROR, oss);
|
||||
free(error_msg);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Information about the VN needs to be extracted from the template
|
||||
vn->get_template_attribute("TYPE",str_type);
|
||||
|
||||
|
||||
if ( str_type == "RANGED")
|
||||
{
|
||||
vn->type = VirtualNetwork::RANGED;
|
||||
@ -101,46 +101,39 @@ int VirtualNetworkPool::allocate (
|
||||
|
||||
vn->get_template_attribute("NAME",name);
|
||||
vn->name = name;
|
||||
|
||||
|
||||
vn->get_template_attribute("BRIDGE",bridge);
|
||||
vn->bridge = bridge;
|
||||
|
||||
|
||||
// Insert the VN in the pool so we have a valid OID
|
||||
|
||||
*oid = PoolSQL::allocate(vn);
|
||||
|
||||
|
||||
if ( *oid == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C"
|
||||
int VirtualNetworkPool::get_cb(void * _oid, int num, char **values,char **names)
|
||||
{
|
||||
static int select_name_cb(
|
||||
void * _value,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
int * oid;
|
||||
|
||||
oid = static_cast<int *>(_value);
|
||||
|
||||
int * oid;
|
||||
|
||||
oid = static_cast<int *>(_oid);
|
||||
|
||||
if ( oid == 0 || values == 0 || values[0] == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
*oid = atoi(values[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -149,23 +142,27 @@ static int select_name_cb(
|
||||
VirtualNetwork * VirtualNetworkPool::get(const string& name, bool lock)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
int oid;
|
||||
int rc;
|
||||
|
||||
char * sql_name = sqlite3_mprintf("%q",name.c_str());
|
||||
int oid;
|
||||
int rc;
|
||||
|
||||
char * sql_name = db->escape_str(name.c_str());
|
||||
|
||||
if ( sql_name == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
oss << "SELECT oid FROM " << VirtualNetwork::table << " WHERE name = '"
|
||||
<< sql_name << "'";
|
||||
|
||||
rc = db->exec(oss, select_name_cb, (void *) (&oid));
|
||||
|
||||
sqlite3_free(sql_name);
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualNetworkPool::get_cb),
|
||||
static_cast<void *>(&oid));
|
||||
|
||||
oss << "SELECT oid FROM " << VirtualNetwork::table << " WHERE name = '"
|
||||
<< sql_name << "'";
|
||||
|
||||
rc = db->exec(oss, this);
|
||||
|
||||
db->free_str(sql_name);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
@ -178,4 +175,51 @@ VirtualNetwork * VirtualNetworkPool::get(const string& name, bool lock)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetworkPool::dump_cb(void * _oss,
|
||||
int num,
|
||||
char ** values,
|
||||
char ** names)
|
||||
{
|
||||
ostringstream * oss;
|
||||
|
||||
oss = static_cast<ostringstream *>(_oss);
|
||||
|
||||
return VirtualNetwork::dump(*oss, num, values, names);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualNetworkPool::dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
int rc;
|
||||
ostringstream cmd;
|
||||
|
||||
oss << "<VNET_POOL>";
|
||||
|
||||
set_callback(
|
||||
static_cast<Callbackable::Callback>(&VirtualNetworkPool::dump_cb),
|
||||
static_cast<void *>(&oss));
|
||||
|
||||
cmd << "SELECT " << VirtualNetwork::table << ".*,COUNT("
|
||||
<< Leases::table << ".used), user_pool.user_name FROM "
|
||||
<< VirtualNetwork::table
|
||||
<< " LEFT OUTER JOIN " << Leases::table << " ON "
|
||||
<< VirtualNetwork::table << ".oid = " << Leases::table << ".oid"
|
||||
<< " AND " << Leases::table << ".used = 1"
|
||||
<< " LEFT OUTER JOIN (SELECT oid,user_name FROM user_pool) "
|
||||
<< " AS user_pool ON "<< VirtualNetwork::table
|
||||
<< ".uid = user_pool.oid";
|
||||
|
||||
if ( !where.empty() )
|
||||
{
|
||||
cmd << " WHERE " << where;
|
||||
}
|
||||
|
||||
cmd << " GROUP BY " << VirtualNetwork::table << ".oid";
|
||||
|
||||
rc = db->exec(cmd,this);
|
||||
|
||||
oss << "</VNET_POOL>";
|
||||
|
||||
return rc;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user