1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

feature #471: Add IPv6 addresses to network leases

This commit is contained in:
Ruben S. Montero 2013-03-02 00:23:27 +01:00
parent 8f7b3ec93a
commit c96eb249d2
8 changed files with 507 additions and 190 deletions

View File

@ -36,6 +36,8 @@ public:
FixedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
vector<const Attribute*>& vector_leases);
/**
* Create a plain FixedLeases, you can populate the lease pool using
@ -43,8 +45,10 @@ public:
*/
FixedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix):
Leases(db,_oid,0,_mac_prefix),
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[]):
Leases(db,_oid,0,_mac_prefix,_global,_site),
current(leases.begin()){};
~FixedLeases(){};
@ -56,7 +60,7 @@ public:
* @param mac mac of the returned lease
* @return 0 if success
*/
int get(int vid, string& ip, string& mac);
int get(int vid, string& ip, string& mac, unsigned int eui64[]);
/**
* Ask for a specific lease in the network
@ -65,7 +69,7 @@ public:
* @param mac mac of the lease
* @return 0 if success
*/
int set(int vid, const string& ip, string& mac);
int set(int vid, const string& ip, string& mac, unsigned int eui64[]);
/**
* Release an used lease, which becomes unused
@ -110,7 +114,6 @@ public:
}
private:
/**
* Current lease pointer
*/

View File

@ -40,9 +40,17 @@ public:
* @param _oid the virtual network unique identifier
* @param _size the max number of leases
*/
Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix):
ObjectSQL(),
oid(_oid), size(_size), n_used(0), mac_prefix(_mac_prefix), db(_db){};
Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix,
unsigned int _global[], unsigned int _site[]):
ObjectSQL(), oid(_oid), size(_size), n_used(0), mac_prefix(_mac_prefix)
, db(_db)
{
global[1] = _global[1];
global[0] = _global[0];
site[1] = _site[1];
site[0] = _site[0];
};
virtual ~Leases()
{
@ -61,18 +69,20 @@ public:
* @param vid identifier of the VM getting this lease
* @param ip ip of the returned lease
* @param mac mac of the returned lease
* @param eui64 extended unique identifier
* @return 0 if success
*/
virtual int get(int vid, string& ip,string& mac) = 0;
virtual int get(int vid, string& ip, string& mac, unsigned int *eui64) = 0;
/**
* Ask for a specific lease in the network
* @param vid identifier of the VM getting this lease
* @param ip ip of lease requested
* @param mac mac of the lease
* @param eui64 extended unique identifier
* @return 0 if success
*/
virtual int set(int vid, const string& ip, string& mac) = 0;
virtual int set(int vid, const string& ip, string& mac, unsigned int *eui64) = 0;
/**
* Release an used lease, which becomes unused
@ -122,9 +132,6 @@ public:
*/
int free_leases(vector<const Attribute*>& vector_leases, string& error_msg);
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
protected:
/**
* The Lease class, it represents a pair of IP and MAC assigned to
@ -133,16 +140,6 @@ protected:
class Lease : public ObjectXML
{
public:
/**
* Creates a new lease, string form. This constructor throws a runtime
* exception if the IP or MAC format is wrong.
* @param _ip, the Lease IP in string format
* @param _mac, the Lease MAC in string format
* @param _vid, the ID of the VM owning the lease
* @param _used, the lease is in use
*/
//Lease(const string& _ip, const string& _mac,int _vid, bool _used=true);
/**
* Creates a new lease, numeric form.
* @param _ip, the Lease IP in numeric format
@ -150,12 +147,16 @@ protected:
* @param _vid, the ID of the VM owning the lease
* @param _used, the lease is in use
*/
Lease(unsigned int _ip, unsigned int _mac[], int _vid, bool _used=true)
:ObjectXML(),ip(_ip), vid(_vid), used(_used)
Lease(unsigned int _ip,
unsigned int _mac[],
int _vid,
bool _used)
:ObjectXML(),ip(_ip), vid(_vid), used(_used)
{
// TODO check size
mac[PREFIX]=_mac[PREFIX];
mac[SUFFIX]=_mac[SUFFIX];
mac[1]=_mac[1];
mac[0]=_mac[0];
mac_to_eui64(mac, eui64);
};
/**
@ -166,13 +167,6 @@ 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
@ -184,21 +178,35 @@ protected:
*/
static void ip_to_string(const unsigned int i_ip, string& ip);
/**
* Generates IPv6 strings based on the modified EUI64 and global and
* site network prefixes.
*/
static void ip6_to_string(const unsigned int eui64[],
const unsigned int prefix[],
string& ip6s);
/**
* Conversion from string MAC to unsigned int[] MAC
* @return 0 if success
*/
static int mac_to_number(const string& mac, unsigned int i_mac[]);
/**
* Generates the modified extended unique identifier based on MAC
* @param i_mac the MAC address
* @param i_meui64 the modified EUI64
*/
static void mac_to_eui64(const unsigned int mac[], unsigned int eui64[]);
/**
* Conversion from string IP to unsigned int IP
*/
static void mac_to_string(const unsigned int i_mac[], string& mac);
/**
* Prints a Lease in a single line
* Conversion from string IP to unsigned int IP
*/
friend ostream& operator<<(ostream& os, Lease& _lease);
static int prefix6_to_number(const string& prefix, unsigned int ip[]);
/**
* Function to print the Lease object into a string in
@ -206,8 +214,9 @@ protected:
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
string& to_xml(string& xml,
const unsigned int global[],
const unsigned int site[]) const;
/**
* Function to print the Lease object into a string in
* XML format. The output contains all the internal attributes,
@ -225,22 +234,15 @@ protected:
*/
int from_xml(const string &xml_str);
/**
* Constants to access the array storing the MAC address
*/
enum MACIndex
{
SUFFIX = 0,/**< Lower significant 4 bytes */
PREFIX = 1 /**< Higher significant 2 bytes */
};
unsigned int ip;
unsigned int ip;
unsigned int mac[2];
unsigned int mac [2];
unsigned int eui64[2];
int vid;
int vid;
bool used;
bool used;
};
friend class VirtualNetwork;
@ -252,12 +254,12 @@ protected:
/**
* Leases identifier. Connects it to a Virtual Network
*/
int oid;
int oid;
/**
* Number of possible leases (free + assigned)
*/
unsigned int size;
unsigned int size;
/**
* Hash of leases, indexed by lease.ip
@ -274,6 +276,16 @@ protected:
*/
unsigned int mac_prefix;
/**
* Global prefix for IPv6 addresses (64 upper bits)
*/
unsigned int global[2];
/**
* Global prefix for IPv6 addresses (64 upper bits)
*/
unsigned int site[2];
// -------------------------------------------------------------------------
// DataBase implementation variables
// -------------------------------------------------------------------------
@ -307,7 +319,7 @@ protected:
bool check(unsigned int ip);
/**
* Check if a VM is the owner of the ip
* Check if a VM is the owner of the ip
* @param ip of the lease to be checked
* @param vid the ID of the VM
* @return true if the ip was already assigned

View File

@ -32,6 +32,8 @@ public:
RangedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
unsigned int _ip_start,
unsigned int _ip_end);
@ -55,7 +57,7 @@ public:
* @param mac mac of the returned lease
* @return 0 if success
*/
int get(int vid, string& ip, string& mac);
int get(int vid, string& ip, string& mac, unsigned int eui64[]);
/**
* Ask for a specific lease in the network
@ -64,7 +66,7 @@ public:
* @param mac mac of the lease
* @return 0 if success
*/
int set(int vid, const string& ip, string& mac);
int set(int vid, const string& ip, string& mac, unsigned int eui64[]);
/**
* Release an used lease, which becomes unused

View File

@ -117,8 +117,10 @@ public:
*/
int get_lease(int vid, string& _ip, string& _mac, string& _bridge)
{
unsigned int eui64[2];
_bridge = bridge;
return leases->get(vid,_ip,_mac);
return leases->get(vid, _ip, _mac, eui64);
};
/**
@ -131,8 +133,10 @@ public:
*/
int set_lease(int vid, const string& _ip, string& _mac, string& _bridge)
{
unsigned int eui64[2];
_bridge = bridge;
return leases->set(vid,_ip,_mac);
return leases->set(vid, _ip, _mac, eui64);
};
/**
@ -227,6 +231,16 @@ private:
*/
int vlan;
/**
* IPv6 address global unicast prefix
*/
string global;
/**
* IPv6 address site unicast prefix
*/
string site;
// -------------------------------------------------------------------------
// Virtual Network Description
// -------------------------------------------------------------------------

View File

@ -24,8 +24,10 @@ FixedLeases::FixedLeases(
SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
vector<const Attribute*>& vector_leases):
Leases(db,_oid,0,_mac_prefix),current(leases.begin())
Leases(db,_oid,0,_mac_prefix, _global, _site), current(leases.begin())
{
const VectorAttribute * single_attr_lease;
string _mac;
@ -68,24 +70,44 @@ int FixedLeases::add(const string& ip, const string& mac, int vid,
int rc;
if ( Leases::Lease::ip_to_number(ip,_ip) )
if (ip.empty() && mac.empty())
{
goto error_ip;
goto error_no_ip_mac;
}
if ( leases.count(_ip) > 0 )
//Set IP & MAC addresses if provided
if (!ip.empty())
{
goto error_duplicate;
if ( Leases::Lease::ip_to_number(ip,_ip) )
{
goto error_ip;
}
}
if (!mac.empty())
{
if (Leases::Lease::mac_to_number(mac,_mac))
{
goto error_mac;
}
}
//Generate IP from MAC (or viceversa)
if (ip.empty())
{
_ip = _mac[0];
}
if (mac.empty())
{
_mac[Lease::PREFIX] = mac_prefix;
_mac[Lease::SUFFIX] = _ip;
_mac[1] = mac_prefix;
_mac[0] = _ip;
}
else if (Leases::Lease::mac_to_number(mac,_mac))
//Check for duplicates
if ( leases.count(_ip) > 0 )
{
goto error_mac;
goto error_duplicate;
}
lease = new Lease(_ip,_mac,vid,used);
@ -120,29 +142,28 @@ int FixedLeases::add(const string& ip, const string& mac, int vid,
return rc;
error_no_ip_mac:
oss << "Both IP and MAC cannot be empty";
goto error_common;
error_ip:
oss.str("");
oss << "Error inserting lease, malformed IP = " << ip;
goto error_common;
error_mac:
oss.str("");
oss << "Error inserting lease, malformed MAC = " << mac;
goto error_common;
error_duplicate:
oss.str("");
oss << "Error inserting lease, IP " << ip << " already exists";
goto error_common;
error_body:
oss.str("");
oss << "Error inserting lease, marshall error";
delete lease;
goto error_common;
error_db:
oss.str("");
oss << "Error inserting lease in database.";
delete lease;
@ -192,7 +213,7 @@ int FixedLeases::remove(const string& ip, string& error_msg)
}
delete it->second;
leases.erase(it);
return rc;
@ -255,7 +276,7 @@ int FixedLeases::unset(const string& ip)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int FixedLeases::get(int vid, string& ip, string& mac)
int FixedLeases::get(int vid, string& ip, string& mac, unsigned int eui64[])
{
int rc = -1;
@ -280,7 +301,11 @@ int FixedLeases::get(int vid, string& ip, string& mac)
rc = update_lease(current->second);
current->second->to_string(ip,mac);
Leases::Lease::mac_to_string(current->second->mac, mac);
Leases::Lease::ip_to_string(current->second->ip, ip);
eui64[0] = current->second->eui64[0];
eui64[1] = current->second->eui64[1];
current++;
break;
@ -293,7 +318,7 @@ int FixedLeases::get(int vid, string& ip, string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int FixedLeases::set(int vid, const string& ip, string& mac)
int FixedLeases::set(int vid, const string& ip, string& mac, unsigned int eui64[])
{
map<unsigned int,Lease *>::iterator it;
@ -323,6 +348,9 @@ int FixedLeases::set(int vid, const string& ip, string& mac)
Leases::Lease::mac_to_string(it->second->mac,mac);
eui64[0] = it->second->eui64[0];
eui64[1] = it->second->eui64[1];
return update_lease(it->second);
}
@ -394,7 +422,6 @@ int FixedLeases::add_leases(vector<const Attribute*>& vector_leases,
error_msg = "Empty lease description.";
}
return rc;
}

View File

@ -14,10 +14,11 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "Leases.h"
#include "NebulaLog.h"
#include <arpa/inet.h>
/* ************************************************************************** */
/* ************************************************************************** */
/* Lease class */
@ -27,17 +28,6 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::to_string(string &_ip,
string &_mac) const
{
mac_to_string(mac, _mac);
ip_to_string(ip, _ip);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::ip_to_number(const string& _ip, unsigned int& i_ip)
{
istringstream iss;
@ -108,6 +98,38 @@ void Leases::Lease::ip_to_string(const unsigned int i_ip, string& ip)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::ip6_to_string(const unsigned int eui64[],
const unsigned int prefix[],
string& ip6s)
{
struct in6_addr ip6;
char dst[INET6_ADDRSTRLEN];
ip6.s6_addr32[2] = htonl(eui64[1]);
ip6.s6_addr32[3] = htonl(eui64[0]);
// global or site unicast address
if (prefix[1] != 0 && prefix[0] != 0 )
{
ip6.s6_addr32[0] = htonl(prefix[1]);
ip6.s6_addr32[1] = htonl(prefix[0]);
}
else // link local address
{
ip6.s6_addr32[0] = htonl(0xfe800000);
ip6.s6_addr32[1] = 0;
}
if ( inet_ntop(AF_INET6, &ip6, dst, INET6_ADDRSTRLEN) != 0 )
{
ip6s = dst;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::mac_to_number(const string& _mac, unsigned int i_mac[])
{
istringstream iss;
@ -130,22 +152,61 @@ int Leases::Lease::mac_to_number(const string& _mac, unsigned int i_mac[])
iss.str(mac);
i_mac[PREFIX] = 0;
i_mac[SUFFIX] = 0;
i_mac[1] = 0;
i_mac[0] = 0;
iss >> hex >> i_mac[PREFIX] >> ws >> hex >> tmp >> ws;
i_mac[PREFIX] <<= 8;
i_mac[PREFIX] += tmp;
iss >> hex >> i_mac[1] >> ws >> hex >> tmp >> ws;
i_mac[1] <<= 8;
i_mac[1] += tmp;
for (int i=0;i<4;i++)
{
iss >> hex >> tmp >> ws;
i_mac[SUFFIX] <<= 8;
i_mac[SUFFIX] += tmp;
i_mac[0] <<= 8;
i_mac[0] += tmp;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::prefix6_to_number(const string& prefix, unsigned int ip[])
{
struct in6_addr s6;
ostringstream oss(prefix);
if (prefix.empty())
{
ip[1] = ip[0] = 0;
return 0;
}
oss << ":0:0:0:1";
int rc = inet_pton(AF_INET6, oss.str().c_str(), &s6);
if ( rc != 1 )
{
return -1;
}
ip[1] = s6.s6_addr32[0];
ip[0] = s6.s6_addr32[1];
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::mac_to_eui64(const unsigned int i_mac[], unsigned int eui64[])
{
eui64[1] = ((i_mac[1]+512)<<16) + ((i_mac[0] & 0xFF000000)>>16) + 0x000000FF;
eui64[0] = 4261412864 + (i_mac[0] & 0x00FFFFFF);
}
/* -------------------------------------------------------------------------- */
@ -162,12 +223,12 @@ void Leases::Lease::mac_to_string(const unsigned int i_mac[], string& mac)
{
if ( i < 4 )
{
temp_byte = i_mac[SUFFIX];
temp_byte = i_mac[0];
temp_byte >>= i*8;
}
else
{
temp_byte = i_mac[PREFIX];
temp_byte = i_mac[1];
temp_byte >>= (i%4)*8;
}
@ -189,34 +250,45 @@ void Leases::Lease::mac_to_string(const unsigned int i_mac[], string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ostream& operator<<(ostream& os, Leases::Lease& _lease)
string& Leases::Lease::to_xml(string& str,
const unsigned int global[],
const unsigned int site[]) const
{
string xml;
string ip_s;
string ipl_s, ips_s, ipg_s;
string mac_s;
os << _lease.to_xml(xml);
return os;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Leases::Lease::to_xml(string& str) const
{
string ip;
string mac;
unsigned int tmp_prefix[2] = {0, 0};
ostringstream os;
to_string(ip,mac);
mac_to_string(mac, mac_s);
ip_to_string(ip, ip_s);
ip6_to_string(eui64, tmp_prefix, ipl_s);
os <<
"<LEASE>" <<
"<IP>" << ip << "</IP>" <<
"<MAC>" << mac << "</MAC>" <<
"<USED>"<< used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"</LEASE>";
"<IP>" << ip_s << "</IP>" <<
"<MAC>" << mac_s << "</MAC>" <<
"<USED>"<< used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"<IP6_LINK>" << ipl_s << "</IP6_LINK>";
if (site[1] != 0 || site[0] != 0 )
{
ip6_to_string(eui64, site, ips_s);
os << "<IP6_SITE>" << ips_s << "</IP6_SITE>";
}
if (global[1] != 0 || global[0] != 0 )
{
ip6_to_string(eui64, global, ipg_s);
os << "<IP6_GLOBAL>" << ipg_s << "</IP6_GLOBAL>";
}
os << "</LEASE>";
str = os.str();
@ -232,11 +304,11 @@ string& Leases::Lease::to_xml_db(string& str) const
os <<
"<LEASE>" <<
"<IP>" << ip << "</IP>" <<
"<MAC_PREFIX>" << mac[Lease::PREFIX] << "</MAC_PREFIX>" <<
"<MAC_SUFFIX>" << mac[Lease::SUFFIX] << "</MAC_SUFFIX>" <<
"<USED>" << used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"<IP>" << ip << "</IP>" <<
"<MAC_PREFIX>" << mac[1] << "</MAC_PREFIX>" <<
"<MAC_SUFFIX>" << mac[0] << "</MAC_SUFFIX>" <<
"<USED>" << used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"</LEASE>";
str = os.str();
@ -255,11 +327,13 @@ int Leases::Lease::from_xml(const string &xml_str)
// Initialize the internal XML object
update_from_str(xml_str);
rc += xpath(ip , "/LEASE/IP" , 0);
rc += xpath(mac[Lease::PREFIX], "/LEASE/MAC_PREFIX" , 0);
rc += xpath(mac[Lease::SUFFIX], "/LEASE/MAC_SUFFIX" , 0);
rc += xpath(int_used , "/LEASE/USED" , 0);
rc += xpath(vid , "/LEASE/VID" , 0);
rc += xpath(ip, "/LEASE/IP", 0);
rc += xpath(mac[1], "/LEASE/MAC_PREFIX", 0);
rc += xpath(mac[0], "/LEASE/MAC_SUFFIX", 0);
rc += xpath(int_used, "/LEASE/USED", 0);
rc += xpath(vid, "/LEASE/VID", 0);
used = static_cast<bool>(int_used);
@ -268,6 +342,8 @@ int Leases::Lease::from_xml(const string &xml_str)
return -1;
}
mac_to_eui64(mac, eui64);
return 0;
}
@ -446,6 +522,8 @@ int Leases::hold_leases(vector<const Attribute*>& vector_leases,
string ip;
string mac;
unsigned int tmp[2];
if ( vector_leases.size() > 0 )
{
single_attr_lease =
@ -466,7 +544,7 @@ int Leases::hold_leases(vector<const Attribute*>& vector_leases,
return -1;
}
rc = set(-1, ip, mac);
rc = set(-1, ip, mac, tmp);
if ( rc != 0 )
{
@ -535,7 +613,7 @@ string& Leases::to_xml(string& xml) const
for(it=leases.begin();it!=leases.end();it++)
{
os << it->second->to_xml(lease_xml);
os << it->second->to_xml(lease_xml, global, site);
}
xml = os.str();

View File

@ -28,9 +28,11 @@ RangedLeases::RangedLeases(
SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
unsigned int _ip_start,
unsigned int _ip_end):
Leases(db,_oid,0,_mac_prefix),
Leases(db, _oid, 0, _mac_prefix, _global, _site),
ip_start(_ip_start),ip_end(_ip_end),current(0)
{
size = ip_end - ip_start + 1;
@ -39,31 +41,123 @@ RangedLeases::RangedLeases(
/* ************************************************************************** */
/* Ranged Leases :: Methods */
/* ************************************************************************** */
static int get_template_size(VirtualNetwork* vn,
unsigned int& host_bits,
unsigned int& size)
{
string st_size = "";
vn->erase_template_attribute("NETWORK_SIZE", st_size);
if ( st_size == "C" || st_size == "c" )
{
host_bits = 8;
size = 256;
}
else if ( st_size == "B" || st_size == "b" )
{
host_bits = 16;
size = 65536;
}
else if ( st_size == "A" || st_size == "a" )
{
host_bits = 24;
size = 16777216;
}
else
{
if (!st_size.empty())//Assume it's a number
{
istringstream iss(st_size);
iss >> size;
if (iss.fail())
{
return -1;
}
}
else
{
size = VirtualNetworkPool::default_size();
}
host_bits = (int) ceil(log(size+2)/log(2));
}
return 0;
}
/* -------------------------------------------------------------------------- */
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 = "";
string st_ip_start = "";
string st_ip_end = "";
string st_mac_start = "";
unsigned int host_bits;
unsigned int host_bits = 0;
unsigned int network_bits;
unsigned int size;
unsigned int net_addr;
unsigned int net_mask;
size_t pos;
unsigned int mac[2];
// -------------------------------------------------------------------------
// Pure IPv6 network definition based on MAC_START and NETWORK_SIZE
// -------------------------------------------------------------------------
vn->erase_template_attribute("MAC_START", st_mac_start);
if (!st_mac_start.empty())
{
if ( Leases::Lease::mac_to_number(st_mac_start, mac) != 0 )
{
goto error_mac_start;
}
ip_start = mac[0];
if (get_template_size(vn, host_bits, size) != 0)
{
goto error_size;
}
ip_end = ip_start + size;
if ( ip_end < ip_start )
{
goto error_greater_mac;
}
vn->remove_template_attribute("IP_START");
vn->remove_template_attribute("IP_END");
vn->remove_template_attribute("NETWORK_ADDRESS");
vn->remove_template_attribute("NETWORK_MASK");
vn->remove_template_attribute("NETWORK_SIZE");
return 0;
}
// -------------------------------------------------------------------------
// Initialize IP_START and IP_END to limit the IP range
// -------------------------------------------------------------------------
ip_start = 0;
ip_end = 0;
// retrieve specific information from template
vn->erase_template_attribute("IP_START", st_ip_start);
vn->erase_template_attribute("IP_END", st_ip_end);
vn->erase_template_attribute("IP_END", st_ip_end);
if ( !st_ip_start.empty() )
{
@ -81,11 +175,15 @@ int RangedLeases::process_template(VirtualNetwork* vn,
}
}
// -------------------------------------------------------------------------
// Check for NETWORK_ADDRESS
// -------------------------------------------------------------------------
vn->erase_template_attribute("NETWORK_ADDRESS", st_addr);
if (st_addr.empty())
{
if ( ip_start != 0 && ip_end != 0 )
if ( ip_start != 0 && ip_end != 0 ) //Manually range, exit
{
if ( ip_end < ip_start )
{
@ -100,10 +198,13 @@ int RangedLeases::process_template(VirtualNetwork* vn,
}
}
// Check if the IP has a network prefix
// -------------------------------------------------------------------------
// Check for NETWORK_SIZE or NETWORK_ADDRESS
// -------------------------------------------------------------------------
pos = st_addr.find("/");
if ( pos != string::npos )
if ( pos != string::npos ) // Check for CIDR network address
{
string st_network_bits;
@ -120,7 +221,7 @@ int RangedLeases::process_template(VirtualNetwork* vn,
host_bits = 32 - network_bits;
}
else
else // Check for network mask in decimal-dot notation
{
vn->erase_template_attribute("NETWORK_MASK", st_mask);
@ -142,50 +243,29 @@ int RangedLeases::process_template(VirtualNetwork* vn,
host_bits++;
}
}
else
else //No network mask, get NETWORK_SIZE
{
vn->erase_template_attribute("NETWORK_SIZE",st_size);
if ( st_size == "C" || st_size == "c" )
if (get_template_size(vn, host_bits, size) != 0)
{
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
{
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));
goto error_size;
}
}
}
vn->remove_template_attribute("NETWORK_SIZE");
// Set the network mask
// -------------------------------------------------------------------------
// Generate NETWORK_MASK
// -------------------------------------------------------------------------
net_mask = 0xFFFFFFFF << host_bits;
Lease::ip_to_string(net_mask, st_mask);
vn->replace_template_attribute("NETWORK_MASK", st_mask);
// -------------------------------------------------------------------------
// Consistency Checks based on the network address, and range
// -------------------------------------------------------------------------
if ( Leases::Lease::ip_to_number(st_addr,net_addr) != 0 )
{
goto error_net_addr;
@ -225,6 +305,9 @@ int RangedLeases::process_template(VirtualNetwork* vn,
return 0;
error_mac_start:
oss << "MAC_START " << st_mac_start << " is not a valid MAC.";
goto error_common;
error_ip_start:
oss << "IP_START " << st_ip_start << " is not a valid IP.";
@ -260,6 +343,10 @@ error_range_ip_start:
<< st_addr << "/" << 32-host_bits << ".";
goto error_common;
error_size:
oss << "NETWORK_SIZE is not an integer number.";
goto error_common;
error_range_ip_end:
oss << "IP_END " << st_ip_end << " is not part of the network "
<< st_addr << "/" << 32-host_bits << ".";
@ -273,6 +360,9 @@ error_greater:
<< st_ip_end << ".";
goto error_common;
error_greater_mac:
oss << "Size too big, it will overflow MAC address space.";
goto error_common;
error_common:
error_str = oss.str();
@ -282,7 +372,7 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RangedLeases::get(int vid, string& ip, string& mac)
int RangedLeases::get(int vid, string& ip, string& mac, unsigned int eui64[])
{
unsigned int num_ip;
int rc = -1;
@ -295,8 +385,10 @@ int RangedLeases::get(int vid, string& ip, string& mac)
{
unsigned int num_mac[2];
num_mac[Lease::PREFIX] = mac_prefix;
num_mac[Lease::SUFFIX] = num_ip;
num_mac[1] = mac_prefix;
num_mac[0] = num_ip;
Leases::Lease::mac_to_eui64(num_mac, eui64);
rc = add(num_ip,num_mac,vid);
@ -316,7 +408,7 @@ int RangedLeases::get(int vid, string& ip, string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RangedLeases::set(int vid, const string& ip, string& mac)
int RangedLeases::set(int vid, const string& ip, string& mac, unsigned int eui64[])
{
unsigned int num_ip;
unsigned int num_mac[2];
@ -339,8 +431,10 @@ int RangedLeases::set(int vid, const string& ip, string& mac)
return -1;
}
num_mac[Lease::PREFIX] = mac_prefix;
num_mac[Lease::SUFFIX] = num_ip;
num_mac[1] = mac_prefix;
num_mac[0] = num_ip;
Leases::Lease::mac_to_eui64(num_mac, eui64);
rc = add(num_ip,num_mac,vid);

View File

@ -131,7 +131,13 @@ int VirtualNetwork::select_leases(SqlDB * db)
string network_address;
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int site_i[2];
unsigned int global_i[2];
Leases::Lease::prefix6_to_number(site, site_i);
Leases::Lease::prefix6_to_number(global, global_i);
//Get the leases
if (type == RANGED)
@ -139,6 +145,8 @@ int VirtualNetwork::select_leases(SqlDB * db)
leases = new RangedLeases(db,
oid,
mac_prefix,
global_i,
site_i,
ip_start,
ip_end);
}
@ -146,7 +154,9 @@ int VirtualNetwork::select_leases(SqlDB * db)
{
leases = new FixedLeases(db,
oid,
mac_prefix);
mac_prefix,
global_i,
site_i);
}
else
{
@ -182,11 +192,14 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
ostringstream ose;
int rc;
string vlan_attr;
string s_type;
string ranged_error_str;
string vlan_attr;
string s_type;
string ranged_error_str;
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int global_i[2];
unsigned int site_i[2];
//--------------------------------------------------------------------------
// VirtualNetwork Attributes from the template
@ -254,11 +267,27 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
ostringstream oss;
oss << "onebr" << oid;
bridge = oss.str();
}
}
// ------------ IP6 PREFIX ---------------
erase_template_attribute("GLOBAL_PREFIX", global);
if (Leases::Lease::prefix6_to_number(global, global_i) != 0)
{
goto error_global;
}
erase_template_attribute("SITE_PREFIX", site);
if (Leases::Lease::prefix6_to_number(site, site_i) != 0)
{
goto error_site;
}
//--------------------------------------------------------------------------
// Get the leases
//--------------------------------------------------------------------------
@ -278,6 +307,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
leases = new RangedLeases(db,
oid,
mac_prefix,
global_i,
site_i,
ip_start,
ip_end);
}
@ -290,6 +321,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
leases = new FixedLeases(db,
oid,
mac_prefix,
global_i,
site_i,
vector_leases);
remove_template_attribute("LEASES");
@ -336,6 +369,16 @@ error_ranged:
ose << ranged_error_str;
goto error_common;
error_global:
ose << global
<< " does not contain a character string representing a valid prefix";
goto error_common;
error_site:
ose << site
<< " does not contain a character string representing a valid prefix";
goto error_common;
error_null_leases:
ose << "Error getting Virtual Network leases.";
@ -514,6 +557,24 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
os << "<VLAN_ID/>";
}
if (!global.empty())
{
os << "<GLOBAL_PREFIX>" << global << "</GLOBAL_PREFIX>";
}
else
{
os << "<GLOBAL_PREFIX/>";
}
if (!site.empty())
{
os << "<SITE_PREFIX>" << site << "</SITE_PREFIX>";
}
else
{
os << "<SITE_PREFIX/>";
}
if ( type == RANGED )
{
string st_ip_start;
@ -586,6 +647,9 @@ int VirtualNetwork::from_xml(const string &xml_str)
xpath(phydev, "/VNET/PHYDEV", "");
xpath(vlan_id, "/VNET/VLAN_ID","");
xpath(global, "/VNET/GLOBAL_PREFIX", "");
xpath(site, "/VNET/SITE_PREFIX","");
type = static_cast<NetworkType>(int_type);
// Get associated classes
@ -632,6 +696,9 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
string ip;
string mac;
unsigned int eui64[2];
unsigned int prefix[2] = {0, 0};
ostringstream oss;
ip = nic->vector_value("IP");
@ -643,11 +710,11 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
if (ip.empty())
{
rc = leases->get(vid,ip,mac);
rc = leases->get(vid, ip, mac, eui64);
}
else
{
rc = leases->set(vid,ip,mac);
rc = leases->set(vid,ip,mac, eui64);
}
if ( rc != 0 )
@ -659,11 +726,31 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
// NEW NIC ATTRIBUTES
//--------------------------------------------------------------------------
nic->replace("NETWORK" ,name);
nic->replace("NETWORK", name);
nic->replace("NETWORK_ID",oss.str());
nic->replace("BRIDGE" ,bridge);
nic->replace("MAC" ,mac);
nic->replace("IP" ,ip);
nic->replace("BRIDGE", bridge);
nic->replace("MAC", mac);
nic->replace("IP", ip);
Leases::Lease::ip6_to_string(eui64, prefix, ip);
nic->replace("IP6_LINK", ip);
if (!global.empty())
{
Leases::Lease::prefix6_to_number(global, prefix);
Leases::Lease::ip6_to_string(eui64, prefix, ip);
nic->replace("IP6_GLOBAL", ip);
}
if (!site.empty())
{
Leases::Lease::prefix6_to_number(site, prefix);
Leases::Lease::ip6_to_string(eui64, prefix, ip);
nic->replace("IP6_SITE", ip);
}
if ( vlan == 1 )
{