From 948d1d98c424bb95fcec58a3a9a05a047a5bb154 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 16 Feb 2017 16:26:46 +0100 Subject: [PATCH 1/5] F #5027: New address range types for IP6 no SLAAC. Basic lease functionality --- include/AddressRange.h | 115 ++++++++- src/cli/one_helper/onevm_helper.rb | 4 +- src/vnm/AddressRange.cc | 369 +++++++++++++++++++++-------- 3 files changed, 381 insertions(+), 107 deletions(-) diff --git a/include/AddressRange.h b/include/AddressRange.h index 33fe489ef2..3c1d117698 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -39,18 +39,30 @@ public: // ************************************************************************* // Address Range types - // ************************************************************************* + /// ************************************************************************* /** * Type of Addresses defined by this address range + * Constants are encoded as follows: + * + * option bits address family bits + * ---+----+----+ + * ...*|0000|****| + * ----+----+||||+ + * |||\___ AR with Ethernet addresses + * ||\____ AR with IPv4 addresses + * |\_____ AR with IPv6 addresses (SLAAC) + * \______ AR with IPv6 addresses (static, non-SLAAC) */ enum AddressType { - NONE = 0x00000000, /** Undefined Address Type */ - ETHER = 0x00000001, /** MAC address type */ - IP4 = 0x00000003, /** IP version 4 address */ - IP6 = 0x00000005, /** IP version 6 address */ - IP4_6 = 0x00000007 /** IP dual stack version 4 & 6 addresses */ + NONE = 0x00000000, /** Undefined Address Type */ + ETHER = 0x00000001, /** MAC address type */ + IP4 = 0x00000003, /** MAC + IP4 address */ + IP6 = 0x00000005, /** MAC + IP6 address */ + IP6_STATIC = 0x00000009, /** MAC + IP6 (no-SLAAC) address */ + IP4_6 = 0x00000007, /** MAC + IP4 + IP6 addresses */ + IP4_6_STATIC = 0x0000000B, /** MAC + IP4 + IP6 (no-SLAAC) addresses */ }; /** @@ -67,6 +79,31 @@ public: */ static AddressType str_to_type(string& str_type); + /** + * Return true if the address range includes IPv4 addresses + */ + bool is_ipv4() const + { + return (type & 0x00000002) != 0; + } + + /** + * Return true if the address range includes IPv6 addresses + */ + bool is_ipv6() const + { + return (type & 0x00000004) != 0; + } + + /** + * Return true if the address range includes static IPv6 addresses (host id + * is manually defined) + */ + bool is_ipv6_static() const + { + return (type & 0x00000008) != 0; + } + // ************************************************************************* // Address Range initialization functions // ************************************************************************* @@ -421,13 +458,13 @@ protected: /* ---------------------------------------------------------------------- */ /** * Sets the given range of addresses (by index) as used - * @param index the first address to set as used + * @param ix the first address to set as used * @param sz number of addresses to set - * @param msg describing the error if any + * @param mg describing the error if any * * @return 0 if success */ - virtual int allocate_addr(unsigned int index, unsigned int sz, string& msg) = 0; + virtual int allocate_addr(unsigned int ix, unsigned int sz, string& mg) = 0; /** * Gets a range of free addresses * @param index the first address in the range @@ -487,6 +524,13 @@ private: */ int ip_to_i(const string& _ip, unsigned int& i_ip) const; + /** + * IP version 6 to binary (32 bits) + * @param ip string form 2a00:1bc0:b001:A::3 + * @return 0 on success + */ + int ip6_to_i(const string& _ip, unsigned int i_ip[]) const; + /** * IP version 4 to dot notation * @@ -512,6 +556,14 @@ private: int ip6_to_s(const unsigned int prefix[], const unsigned int mac[], string& ip6_s) const; + /** + * IP version 6 to colon notation + * + * @param i_ip Numeric (128 bits) IP + * @return string in colon notation + */ + string ip6_to_s(const unsigned int i_ip6[]) const; + /* ---------------------------------------------------------------------- */ /* NIC setup functions */ /* ---------------------------------------------------------------------- */ @@ -537,6 +589,13 @@ private: */ void set_ip6(unsigned int addr_index, VectorAttribute * nic) const; + /** + * Writes IPv6 address (no-slaac) to the given NIC attribute + * @param addr_index internal index for the lease + * @param nic attribute of a VMTemplate + */ + void set_ip6_static(unsigned int addr_index, VectorAttribute * nic) const; + /** * Writes VNET configuration attributes to the given NIC attribute. It * includes: BRIDGE, VLAN_ID, PHYDEV and INHERIT_VNET_ATTR in oned.conf @@ -605,6 +664,39 @@ private: /* ---------------------------------------------------------------------- */ /* Restricted Attributes functions */ /* ---------------------------------------------------------------------- */ + /** + * Function to parse the IPv4 attribute ("IP") for IP4 and IP4_6 ARs + * @param error_msg if any + * @return 0 on success + */ + int init_ipv4(string& error_msg); + + /** + * Function to parse the IPv6 attributes ("GLOBAL_PREFIX" and "ULA_PREFIX") + * for IP6 and IP4_6 ARs + * @param error_msg if any + * @return 0 on success + */ + int init_ipv6(string& error_msg); + + /** + * Function to parse the IPv6 attributes no slaac ("IP6") for IP6_STATIC + * and IP4_6_STATIC ARs + * @param error_msg if any + * @return 0 on success + */ + int init_ipv6_static(string& error_msg); + + /** + * Function to parse the MAC attributes ("MAC") for all AR types + * @param error_msg if any + * @return 0 on success + */ + int init_mac(string& error_msg); + + /** + * Checks for restricted attributes, returns the first one found + */ bool check(string& rs_attr) const; /** @@ -655,6 +747,11 @@ private: */ unsigned int ula6[2]; + /** + * Binary representation of the first IPv6 address in the AR. No SLAAC ARs + */ + unsigned int ip6[4]; + /** * Security Group IDs for this Address Range */ diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index 7944fb4daf..6545e70d6c 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -169,7 +169,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper end vm_nics.each do |nic| - ["IP", "IP6_GLOBAL", "IP6_ULA", + ["IP", "IP6_GLOBAL", "IP6_ULA", "IP6", "VROUTER_IP", "VROUTER_IP6_GLOBAL", "VROUTER_IP6_ULA"].each do |attr| if nic.has_key?(attr) ips.push(nic[attr]) @@ -752,7 +752,7 @@ in the frontend machine. next if nic.has_key?("CLI_DONE") - ["IP6_LINK", "IP6_ULA", "IP6_GLOBAL"].each do |attr| + ["IP6_LINK", "IP6_ULA", "IP6_GLOBAL", "IP6"].each do |attr| if nic.has_key?(attr) shown_ips << nic[attr] diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index faf161d684..129515299e 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -32,11 +32,13 @@ string AddressRange::type_to_str(AddressType ob) { switch (ob) { - case ETHER: return "ETHER"; break; - case IP4: return "IP4" ; break; - case IP6: return "IP6" ; break; - case IP4_6: return "IP4_6"; break; - default: return ""; + case ETHER: return "ETHER" ; + case IP4: return "IP4" ; + case IP6: return "IP6" ; + case IP6_STATIC: return "IP6_STATIC" ; + case IP4_6: return "IP4_6" ; + case IP4_6_STATIC: return "IP4_6_STATIC"; + default: return ""; } }; @@ -62,6 +64,14 @@ AddressRange::AddressType AddressRange::str_to_type(string& str_type) { return IP4_6; } + else if (str_type == "IP4_6_STATIC") + { + return IP4_6_STATIC; + } + else if (str_type == "IP6_STATIC") + { + return IP6_STATIC; + } else { return NONE; @@ -71,6 +81,116 @@ AddressRange::AddressType AddressRange::str_to_type(string& str_type) /* ************************************************************************** */ /* ************************************************************************** */ +int AddressRange::init_ipv4(string& error_msg) +{ + if (!is_ipv4()) + { + attr->remove("IP"); + return 0; + } + + string value = attr->vector_value("IP"); + + if (value.empty() || ip_to_i(value, ip) == -1) + { + error_msg = "Wrong or empty IP attribute"; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +int AddressRange::init_ipv6(string& error_msg) +{ + if (!is_ipv6()) + { + attr->remove("GLOBAL_PREFIX"); + attr->remove("ULA_PREFIX"); + + return 0; + } + + string value = attr->vector_value("GLOBAL_PREFIX"); + + if (prefix6_to_i(value, global6) != 0 ) + { + error_msg = "Wrong format for IP6 global address prefix"; + return -1; + } + + value = attr->vector_value("ULA_PREFIX"); + + if (prefix6_to_i(value, ula6) != 0 ) + { + error_msg = "Wrong format for IP6 unique local address prefix"; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +int AddressRange::init_ipv6_static(string& error_msg) +{ + if (!is_ipv6_static()) + { + attr->remove("IP6"); + return 0; + } + + string value = attr->vector_value("IP6"); + + if (value.empty() || ip6_to_i(value, ip6) == -1) + { + error_msg = "Wrong or empty IP6 attribute"; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +int AddressRange::init_mac(string& error_msg) +{ + string value = attr->vector_value("MAC"); + + if (value.empty()) + { + mac[1] = VirtualNetworkPool::mac_prefix(); + + if ( is_ipv4() ) + { + mac[0] = ip; + } + else + { + srand(time(0)); + + mac[0] = rand() & 0x0000FFFF; + mac[0]+= (rand()<<16) & 0xFFFF0000; + } + + set_mac(0, attr); + } + else + { + if (mac_to_i(value, mac) == -1) + { + error_msg = "Wrong format for MAC attribute"; + return -1; + }; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg) { string value; @@ -94,78 +214,27 @@ int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg) return -1; } - /* -------------------- MAC & IPv4 start addresses ---------------------- */ + /* ---------------------- L3 & L2 start addresses ---------------------- */ - bool do_mac = false; + if ( init_ipv4(error_msg) != 0 ) + { + return -1; + } - value = vattr->vector_value("MAC"); + if ( init_ipv6(error_msg) != 0 ) + { + return -1; + } - if (value.empty()) - { - do_mac = true; - mac[1] = VirtualNetworkPool::mac_prefix(); - } - else - { - if (mac_to_i(value, mac) == -1) - { - error_msg = "Wrong format for MAC attribute"; - return -1; - }; - } + if ( init_ipv6_static(error_msg) != 0 ) + { + return -1; + } - switch(type) - { - case ETHER: - case IP6: - vattr->remove("IP"); - - if (do_mac) - { - srand(time(0)); - - mac[0] = rand() & 0x0000FFFF; - mac[0]+= (rand()<<16) & 0xFFFF0000; - } - break; - - case IP4: - case IP4_6: - value = vattr->vector_value("IP"); - - if (value.empty() || ip_to_i(value, ip) == -1) - { - error_msg = "Wrong or empty IP attribute"; - return -1; - } - - if (do_mac) - { - mac[0] = ip; - } - break; - - default: - return -1; - } - - /* -------------------------- IP6 prefixes ------------------------------ */ - - value = vattr->vector_value("GLOBAL_PREFIX"); - - if (prefix6_to_i(value, global6) != 0 ) - { - error_msg = "Wrong format for IP6 global address prefix"; - return -1; - } - - value = vattr->vector_value("ULA_PREFIX"); - - if (prefix6_to_i(value, ula6) != 0 ) - { - error_msg = "Wrong format for IP6 unique local address prefix"; - return -1; - } + if ( init_mac(error_msg) != 0 ) + { + return -1; + } /* ------------------------- Security Groups ---------------------------- */ @@ -194,11 +263,6 @@ int AddressRange::from_attr(VectorAttribute *vattr, string& error_msg) vattr->remove("PARENT_NETWORK"); - if (do_mac) //Need to add MAC to the attribute - { - set_mac(0, attr); - } - return 0; } @@ -237,7 +301,14 @@ int AddressRange::update_attributes( vup->remove("IP"); - if (type & 0x00000002) + if (is_ipv4()) + { + vup->replace("IP", attr->vector_value("IP")); + } + + vup->remove("IP6"); + + if (is_ipv6_static()) { vup->replace("IP", attr->vector_value("IP")); } @@ -266,6 +337,8 @@ int AddressRange::update_attributes( vup->remove("IP_END"); + vup->remove("IP6_END"); + vup->remove("IP6_ULA"); vup->remove("IP6_ULA_END"); @@ -367,11 +440,16 @@ int AddressRange::from_vattr_db(VectorAttribute *vattr) rc += mac_to_i(vattr->vector_value("MAC"), mac); - if (type & 0x00000002) + if (is_ipv4()) { rc += ip_to_i(vattr->vector_value("IP"), ip); } + if (is_ipv6_static()) + { + rc += ip6_to_i(vattr->vector_value("IP6"), ip6); + } + rc += prefix6_to_i(vattr->vector_value("GLOBAL_PREFIX"), global6); rc += prefix6_to_i(vattr->vector_value("ULA_PREFIX"), ula6); @@ -426,6 +504,16 @@ void AddressRange::addr_to_xml(unsigned int index, unsigned int rsize, << ""; } + if ( ip6[0] != 0 || ip6[1] != 0 || ip6[2] != 0 || ip6[3] != 0 ) + { + unsigned int ip_low[2]; + + ip_low[0] = ip6[0] + index; + ip_low[1] = ip6[1]; + + oss << "" << ip6_to_s(&(ip6[2]), ip_low, ip6_s) << ""; + } + oss << "" << rsize << "" << ""; } @@ -438,7 +526,6 @@ void AddressRange::to_xml(ostringstream &oss) const const map& ar_attrs = attr->value(); map::const_iterator it; - string aux_st; unsigned int mac_end[2]; oss << ""; @@ -460,12 +547,13 @@ void AddressRange::to_xml(ostringstream &oss) const oss << "" << one_util::escape_xml(mac_to_s(mac_end))<<""; - aux_st = attr->vector_value("IP"); - - if (aux_st != "") + if (is_ipv4()) { + string aux_st; unsigned int ip_i; + aux_st = attr->vector_value("IP"); + if (ip_to_i(aux_st, ip_i) == 0) { oss << "" << one_util::escape_xml(ip_to_s(ip_i + size - 1)) @@ -473,7 +561,7 @@ void AddressRange::to_xml(ostringstream &oss) const } } - if (type & 0x00000004) + if (is_ipv6()) { string ip6_s; @@ -499,6 +587,22 @@ void AddressRange::to_xml(ostringstream &oss) const } } + if (is_ipv6_static()) + { + string ip6_s; + + ip6_to_s(&(ip6[2]), ip6, ip6_s); + oss << "" << one_util::escape_xml(ip6_s) << ""; + + unsigned int ip_low[2]; + + ip_low[1] = ip6[1]; + ip_low[0] = ip6[0] + size - 1; + + ip6_to_s(&(ip6[2]), ip_low, ip6_s); + oss << "" << one_util::escape_xml(ip6_s) << ""; + } + oss << "" << get_used_addr() << ""; oss << ""; } @@ -539,11 +643,10 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, oss << "" << one_util::escape_xml(mac_to_s(mac_end))<<""; - aux_st = attr->vector_value("IP"); - - if (aux_st != "") + if (is_ipv4()) { unsigned int ip_i; + string aux_st = attr->vector_value("IP"); rc = ip_to_i(aux_st, ip_i); @@ -554,7 +657,7 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, } } - if (type & 0x00000004) + if (is_ipv6()) { string ip6_s; @@ -564,7 +667,8 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, oss << "" << one_util::escape_xml(ip6_s) << ""; ip6_to_s(ula6, mac_end, ip6_s); - oss << "" << one_util::escape_xml(ip6_s) << ""; + oss << "" << one_util::escape_xml(ip6_s) + << ""; } if (global6[1] != 0 || global6[0] != 0 ) /* Glocal Unicast */ @@ -573,10 +677,27 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, oss << "" << one_util::escape_xml(ip6_s) << ""; ip6_to_s(global6, mac_end, ip6_s); - oss << "" << one_util::escape_xml(ip6_s) << ""; + oss << "" << one_util::escape_xml(ip6_s) + << ""; } } + if (is_ipv6_static()) + { + string ip6_s; + + ip6_to_s(&(ip6[2]), ip6, ip6_s); + oss << "" << one_util::escape_xml(ip6_s) << ""; + + unsigned int ip_low[2]; + + ip_low[1] = ip6[1]; + ip_low[0] = ip6[0] + size - 1; + + ip6_to_s(&(ip6[2]), ip_low, ip6_s); + oss << "" << one_util::escape_xml(ip6_s) << ""; + } + oss << "" << get_used_addr() << ""; if (allocated.empty()) @@ -636,16 +757,21 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, set_mac(it->first, &lease); - if (type & 0x00000002 ) + if (is_ipv4()) { set_ip(it->first, &lease); } - if (type & 0x00000004) + if (is_ipv6()) { set_ip6(it->first, &lease); } + if (is_ipv6_static()) + { + set_ip6_static(it->first, &lease); + } + lease.to_xml(oss); } @@ -810,6 +936,34 @@ string AddressRange::ip_to_s(unsigned int i_ip) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::ip6_to_i(const string& _ip, unsigned int i_ip[]) const +{ + struct in6_addr s6; + + if (_ip.empty()) + { + return -1; + } + + int rc = inet_pton(AF_INET6, _ip.c_str(), &s6); + + if ( rc != 1 ) + { + return -1; + } + + i_ip[3] = ntohl(s6.s6_addr32[0]); + i_ip[2] = ntohl(s6.s6_addr32[1]); + i_ip[1] = ntohl(s6.s6_addr32[2]); + i_ip[0] = ntohl(s6.s6_addr32[3]); + + return 0; + +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::prefix6_to_i(const string& prefix, unsigned int ip[]) const { struct in6_addr s6; @@ -983,6 +1137,24 @@ void AddressRange::set_ip6(unsigned int addr_index, VectorAttribute * nic) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRange::set_ip6_static(unsigned int addr_index, + VectorAttribute * nic) const +{ + unsigned int low_ip[2]; + string ip6_s; + + low_ip[0] = ip6[0] + addr_index; + low_ip[1] = ip6[1]; + + if ( ip6_to_s(&(ip6[2]), low_ip, ip6_s) == 0 ) + { + nic->replace("IP6", ip6_s); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRange::set_vnet(VectorAttribute *nic, const vector &inherit) const { nic->replace("AR_ID", id); @@ -1127,16 +1299,21 @@ void AddressRange::allocate_by_index(unsigned int index, { set_mac(index, nic); - if (type & 0x00000002 ) + if (is_ipv4()) { set_ip(index, nic); } - if (type & 0x00000004) + if (is_ipv6()) { set_ip6(index, nic); } + if (is_ipv6_static()) + { + set_ip6_static(index, nic); + } + set_vnet(nic, inherit); set_allocated_addr(ot, obid, index); @@ -1263,7 +1440,7 @@ int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, { string error_msg; - if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + if (!is_ipv4()) { return -1; } From ba40cffd61df0ecfafffc99851bb4b5a2cf8e83e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 21 Feb 2017 16:50:45 +0100 Subject: [PATCH 2/5] F #5027: Operations (hold, release, reserve...) for IP6 no-slaac ARs --- include/AddressRange.h | 82 ++++---- include/AddressRangePool.h | 95 +++------ include/VirtualNetwork.h | 110 +++++----- include/VirtualNetworkPool.h | 17 +- src/cli/one_helper/onevnet_helper.rb | 8 +- src/oca/ruby/opennebula/virtual_network.rb | 47 +++-- src/rm/RequestManagerVirtualNetwork.cc | 17 +- src/vnm/AddressRange.cc | 233 ++++++++++++++++++--- src/vnm/AddressRangePool.cc | 126 +++++++++++ src/vnm/VirtualNetwork.cc | 123 +++++++++-- src/vnm/VirtualNetworkPool.cc | 44 +++- 11 files changed, 660 insertions(+), 242 deletions(-) diff --git a/include/AddressRange.h b/include/AddressRange.h index 3c1d117698..9dbd1b82a6 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -188,7 +188,7 @@ public: VectorAttribute * nic, const vector &inherit); /** - * Returns the specific address by mac if is not allocated. The NIC attr + * Returns the specific address by mac/ip if is not allocated. The NIC attr * is filled with the configuration parameters from the address range. * @param mac the mac address * @param ot the type of the object allocating the address @@ -200,48 +200,36 @@ public: int allocate_by_mac(const string& mac, PoolObjectSQL::ObjectType ot, int obid, VectorAttribute * nic, const vector &inherit); - /** - * Returns the specific address by ip if is not allocated. The NIC attr - * is filled with the configuration parameters from the address range. - * @param ot the type of the object allocating the address - * @param obid the id of the object - * @param nic the VM NIC attribute - * @param inherit attributes to be added to the NIC attribute - * @return 0 if success - */ int allocate_by_ip(const string& ip, PoolObjectSQL::ObjectType ot, int obid, VectorAttribute * nic, const vector &inherit); - /** - * Sets the given ip on hold, the address is associated to a VM of id -1. - * @param ip the ip to hold - */ - int hold_by_ip(const string& ip); + int allocate_by_ip6(const string& ip6, PoolObjectSQL::ObjectType ot, + int obid, VectorAttribute * nic, const vector &inherit); /** - * Sets the given mac on hold, the address is associated to a VM of id -1. - * @param mac the mac to hold + * Sets the given ip/mac on hold, the address is associated to a VM of + * id -1. + * @param ip/mac the ip to hold */ int hold_by_mac(const string& mac); + int hold_by_ip(const string& ip); + + int hold_by_ip6(const string& ip); + /** - * Frees a previous allocated address, referenced by its MAC address + * Frees a previous allocated address, referenced by its MAC/IP address * @param ot the object type of the owner of the address * @param obid the id of the owner of the address - * @param mac the MAC address in string form + * @param mac/ip the MAC/IP address in string form * @return 0 if the address was freed */ int free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac); - /** - * Frees a previous allocated address, referenced by its IP address - * @param ot the object type of the owner of the address - * @param obid the id of the owner of the address - * @param ip the IP address in string form - * @return 0 if the address was freed - */ int free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + int free_addr_by_ip6(PoolObjectSQL::ObjectType ot, int id,const string& ip); + /** * Frees all previous allocated address to the given object * @param ot the object type of the owner of the address @@ -287,23 +275,18 @@ public: * @param vid the id of the VNET making the reservation * @param size number of addresses to reserve * @param rar a new address range to place the reservation - * @param ip the firs ip in the Reservation - * @return 0 on success - */ - int reserve_addr_by_ip(int vid, unsigned int rsize, const string& ip, - AddressRange *rar); - - /** - * Reserve a given number of addresses from this address range - * @param vid the id of the VNET making the reservation - * @param size number of addresses to reserve - * @param rar a new address range to place the reservation - * @param mac the firs mac in the Reservation + * @param ip/mac the firs ip in the Reservation * @return 0 on success */ int reserve_addr_by_mac(int vid, unsigned int rsize, const string& mac, AddressRange *rar); + int reserve_addr_by_ip(int vid, unsigned int rsize, const string& ip, + AddressRange *rar); + + int reserve_addr_by_ip6(int vid, unsigned int rsize, const string& ip, + AddressRange *rar); + // ************************************************************************* // Helpers // ************************************************************************* @@ -417,6 +400,7 @@ protected: * * * + * * * * @param index for the address @@ -453,6 +437,20 @@ protected: */ bool is_valid_ip(unsigned int& index, const string& ip_s, bool check_free); + /** + * Check if the given IP is valid for this address range by verifying: + * - AR is of type IP6_STATIC or IP4_6_STATIC + * - Correct : notation + * - Part of the AR + * + * @param index of the IP in the AR + * @param ip6_s string representation of the IP in : notation + * @param check_free apart from previous checks + * + * @return true if the IP is valid + */ + bool is_valid_ip6(unsigned int& index, const string& ip_s, bool check_free); + /* ---------------------------------------------------------------------- */ /* Implementation specific address management interface */ /* ---------------------------------------------------------------------- */ @@ -556,13 +554,7 @@ private: int ip6_to_s(const unsigned int prefix[], const unsigned int mac[], string& ip6_s) const; - /** - * IP version 6 to colon notation - * - * @param i_ip Numeric (128 bits) IP - * @return string in colon notation - */ - string ip6_to_s(const unsigned int i_ip6[]) const; + int ip6_to_s(const unsigned int ip6_i[], string& ip6_s) const; /* ---------------------------------------------------------------------- */ /* NIC setup functions */ diff --git a/include/AddressRangePool.h b/include/AddressRangePool.h index b9335df0da..5343cd2b61 100644 --- a/include/AddressRangePool.h +++ b/include/AddressRangePool.h @@ -117,8 +117,8 @@ public: VectorAttribute * nic, const vector &inherit); /** - * Allocates an address in a suitable address range from the pool by mac - * @param mac the specific MAC address requested + * Allocates an address in a suitable address range from the pool by mac/ip + * @param mac/ip the specific MAC/IP address requested * @param ot the type of the object requesting the address (VM or NET) * @param obid the id of the object requesting the address * @param nic the NIC attribute to be filled with lease attributes @@ -128,86 +128,64 @@ public: int allocate_by_mac(const string &mac, PoolObjectSQL::ObjectType ot, int obid, VectorAttribute * nic, const vector &inherit); - /** - * Allocates an address in a suitable address range from the pool by mac - * @param ip the specific IP address requested - * @param ot the type of the object requesting the address (VM or NET) - * @param obid the id of the object requesting the address - * @param nic the NIC attribute to be filled with lease attributes - * @param inherit attributes to be added to the NIC - * @return 0 if success - */ int allocate_by_ip(const string &ip, PoolObjectSQL::ObjectType ot, int obid, VectorAttribute * nic, const vector &inherit); + int allocate_by_ip6(const string &ip, PoolObjectSQL::ObjectType ot, int obid, + VectorAttribute * nic, const vector &inherit); + /** * Holds an address from the specified address range. * @param arid of the address range - * @param ip the ip to hold - * @return 0 on success - */ - int hold_by_ip(unsigned int arid, const string& ip); - - /** - * Holds an address from the first address range containing the MAC - * @param mac the mac to hold - * @return 0 on success - */ - int hold_by_ip(const string& ip); - - /** - * Holds an address from the specified address range. - * @param arid of the address range - * @param mac the mac to hold + * @param mac/ip the mac/ip to hold * @return 0 on success */ int hold_by_mac(unsigned int arid, const string& mac); + int hold_by_ip(unsigned int arid, const string& ip); + + int hold_by_ip6(unsigned int arid, const string& ip); + /** * Holds an address from the first address range containing the MAC - * @param mac the mac to hold + * @param mac/ip the mac/ip to hold * @return 0 on success */ int hold_by_mac(const string& mac); + int hold_by_ip(const string& ip); + + int hold_by_ip6(const string& ip); + /** - * Frees the given address by MAC on the given address range + * Frees the given address by MAC/IP on the given address range * @param arid the ID of the address range * @param ot the type of the object requesting the address (VM or NET) * @param obid the id of the object requesting the address - * @param mac the specific MAC address requested + * @param mac/ip the specific MAC/IP address requested */ void free_addr(unsigned int arid, PoolObjectSQL::ObjectType ot, int obid, const string& mac); - /** - * Frees the given address by IP on the given address range - * @param arid the ID of the address range - * @param ot the type of the object requesting the address (VM or NET) - * @param obid the id of the object requesting the address - * @param ip the specific IP address requested - */ void free_addr_by_ip(unsigned int arid, PoolObjectSQL::ObjectType ot, int obid, const string& ip); + void free_addr_by_ip6(unsigned int arid, PoolObjectSQL::ObjectType ot, + int obid, const string& ip); + /** - * Frees the given address by MAC from all address ranges containing - * the MAC + * Frees the given address by MAC/IP from all address ranges containing + * the MAC/IP * @param ot the type of the object requesting the address (VM or NET) * @param obid the id of the object requesting the address - * @param mac the specific MAC address requested + * @param mac/ip the specific MAC/IP address requested */ void free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac); - /** - * Frees the given address by IP from all address ranges containing - * the IP - * @param ot the type of the object requesting the address (VM or NET) - * @param obid the id of the object requesting the address - * @param ip the specific IP address requested - */ void free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + void free_addr_by_ip6(PoolObjectSQL::ObjectType ot, int id,const string& ip); + /** * Frees all the addressed owned by the given object * @param ot the type of the object requesting the address (VM or NET) @@ -265,29 +243,24 @@ public: AddressRange *rar); /** - * Reserve a number of addresses from an address range from a given ip + * Reserve a number of addresses from an address range from a given ip/mac * @param vid the id of the VNET making the reservation * @param rsize number of addresses to reserve * @param ar_id the address range to reserve the addresses from - * @param ip the first IP in the reservation - * @param rar a new address range to place the reservation - * @return 0 on success - */ - int reserve_addr_by_ip(int vid, unsigned int rsize, unsigned int ar_id, - const string& ip, AddressRange *rar); - - /** - * Reserve a number of addresses from an address range from a given ip - * @param vid the id of the VNET making the reservation - * @param rsize number of addresses to reserve - * @param ar_id the address range to reserve the addresses from - * @param mac the first IP in the reservation + * @param mac/ip the first MAC/IP in the reservation * @param rar a new address range to place the reservation * @return 0 on success */ int reserve_addr_by_mac(int vid, unsigned int rsize, unsigned int ar_id, const string& mac, AddressRange *rar); + int reserve_addr_by_ip(int vid, unsigned int rsize, unsigned int ar_id, + const string& ip, AddressRange *rar); + + int reserve_addr_by_ip6(int vid, unsigned int rsize, unsigned int ar_id, + const string& ip, AddressRange *rar); + + // ************************************************************************* // Helpers & Formatting // ************************************************************************* diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 4145fca27a..188863cbfe 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -217,50 +217,6 @@ public: // Address allocation funtions // ************************************************************************* - /** - * Gets a new address lease for a specific VM - * @param ot the type of the object requesting the address - * @param oid the id of the object requesting the address - * @param nic the VM NIC attribute to be filled with the lease info. - * @param inherit attributes from the address range to include in the NIC - * @return 0 if success - */ - int allocate_addr(PoolObjectSQL::ObjectType ot, int oid, - VectorAttribute * nic, const vector& inherit) - { - return ar_pool.allocate_addr(ot, oid, nic, inherit); - } - - /** - * Gets a new address lease for a specific VM by MAC - * @param ot the type of the object requesting the address - * @param oid the id of the object requesting the address - * @param mac the MAC address requested - * @param nic the VM NIC attribute to be filled with the lease info. - * @param inherit attributes from the address range to include in the NIC - * @return 0 if success - */ - int allocate_by_mac(PoolObjectSQL::ObjectType ot, int oid, const string& mac, - VectorAttribute * nic, const vector& inherit) - { - return ar_pool.allocate_by_mac(mac, ot, oid, nic, inherit); - } - - /** - * Gets a new address lease for a specific VM by IP - * @param ot the type of the object requesting the address - * @param oid the id of the object requesting the address - * @param ip the IP address requested - * @param nic the VM NIC attribute to be filled with the lease info. - * @param inherit attributes from the address range to include in the NIC - * @return 0 if success - */ - int allocate_by_ip(PoolObjectSQL::ObjectType ot, int oid, const string& ip, - VectorAttribute * nic, const vector& inherit) - { - return ar_pool.allocate_by_ip(ip, ot, oid, nic, inherit); - } - /** * Release previously given address lease * @param arid of the address range where the address was leased from @@ -392,20 +348,7 @@ public: * @param rid the reservation VNET ID to store the reserved AR * @param rsize number of addresses to reserve * @param ar_id id of the address range to obtain the addresses - * @param ip the first ip in the reservations - * @param rar the address range to place the reservation - * @param err error message - * @return 0 on success - */ - int reserve_addr_by_ip(int rid, unsigned int rsize, unsigned int ar_id, - const string& ip, AddressRange *rar, string& error_str); - - /** - * Reserve an address range for this network and add it to the given vnet - * @param rid the reservation VNET ID to store the reserved AR - * @param rsize number of addresses to reserve - * @param ar_id id of the address range to obtain the addresses - * @param mac the first mac in the reservations + * @param ip/mac the first ip/mac in the reservations * @param rar the address range to place the reservation * @param err error message * @return 0 on success @@ -413,6 +356,12 @@ public: int reserve_addr_by_mac(int rid, unsigned int rsize, unsigned int ar_id, const string& mac, AddressRange *rar, string& error_str); + int reserve_addr_by_ip(int rid, unsigned int rsize, unsigned int ar_id, + const string& ip, AddressRange *rar, string& error_str); + + int reserve_addr_by_ip6(int rid, unsigned int rsize, unsigned int ar_id, + const string& ip6, AddressRange *rar, string& error_str); + /** * Returns true if this VNET is a reservation * @return true if this VNET is a reservation @@ -581,6 +530,51 @@ private: */ ObjectCollection vrouters; + // ************************************************************************* + // Address allocation funtions + // ************************************************************************* + + /** + * Gets a new address lease for a specific VM + * @param ot the type of the object requesting the address + * @param oid the id of the object requesting the address + * @param nic the VM NIC attribute to be filled with the lease info. + * @param inherit attributes from the address range to include in the NIC + * @return 0 if success + */ + int allocate_addr(PoolObjectSQL::ObjectType ot, int oid, + VectorAttribute * nic, const vector& inherit) + { + return ar_pool.allocate_addr(ot, oid, nic, inherit); + } + + /** + * Gets a new address lease for a specific VM by MAC/IP + * @param ot the type of the object requesting the address + * @param oid the id of the object requesting the address + * @param mac/ip the MAC/IP address requested + * @param nic the VM NIC attribute to be filled with the lease info. + * @param inherit attributes from the address range to include in the NIC + * @return 0 if success + */ + int allocate_by_mac(PoolObjectSQL::ObjectType ot, int oid, const string& mac, + VectorAttribute * nic, const vector& inherit) + { + return ar_pool.allocate_by_mac(mac, ot, oid, nic, inherit); + } + + int allocate_by_ip(PoolObjectSQL::ObjectType ot, int oid, const string& ip, + VectorAttribute * nic, const vector& inherit) + { + return ar_pool.allocate_by_ip(ip, ot, oid, nic, inherit); + } + + int allocate_by_ip6(PoolObjectSQL::ObjectType ot, int oid, const string& ip, + VectorAttribute * nic, const vector& inherit) + { + return ar_pool.allocate_by_ip6(ip, ot, oid, nic, inherit); + } + // ************************************************************************* // DataBase implementation (Private) // ************************************************************************* diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index 0df52fb276..76d24a9037 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -236,24 +236,19 @@ public: * @param rid the reservation VNET ID to store the reserved AR * @param rsize number of addresses to reserve * @param ar_id AR to make the reservation from - * @param ip the first ip in the reservations + * @param ip/mac the first ip/mac in the reservations * @param err error message * @return 0 on success */ int reserve_addr_by_ip(int pid, int rid, unsigned int rsize, unsigned int ar_id, const string& ip, string& err); - /** - * Reserve an address range - * @param pid the parent VNET ID to get the leases from - * @param rid the reservation VNET ID to store the reserved AR - * @param rsize number of addresses to reserve - * @param ar_id AR to make the reservation from - * @param mac the first mac in the reservations - * @param err error message - * @return 0 on success - */ + + int reserve_addr_by_ip6(int pid, int rid, unsigned int rsize, + unsigned int ar_id, const string& ip, string& err); + int reserve_addr_by_mac(int pid, int rid, unsigned int rsize, unsigned int ar_id, const string& mac, string& err); + private: /** * Holds the system-wide MAC prefix diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 3aae41382f..6f1e2f7dfc 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -274,6 +274,10 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper puts format % ["IP6_ULA", ar["IP6_ULA"], ar["IP6_ULA_END"]] end + if !ar["IP6"].nil? + puts format % ["IP6", ar["IP6"], ar["IP6_END"]] + end + puts end @@ -325,8 +329,8 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper d["IP"]||"-" end - column :IP6_GLOBAL, "", :donottruncate, :size=>26 do |d| - d["IP6_GLOBAL"]||"-" + column :IP6, "", :donottruncate, :size=>26 do |d| + d["IP6"]||d["IP6_GLOBAL"]||"-" end end.show(leases, {}) diff --git a/src/oca/ruby/opennebula/virtual_network.rb b/src/oca/ruby/opennebula/virtual_network.rb index 09a03154e4..c0a00e7d5a 100644 --- a/src/oca/ruby/opennebula/virtual_network.rb +++ b/src/oca/ruby/opennebula/virtual_network.rb @@ -16,6 +16,7 @@ require 'opennebula/pool_element' +require 'ipaddr' module OpenNebula class VirtualNetwork < PoolElement @@ -184,11 +185,9 @@ module OpenNebula def hold(ip, ar_id=-1) return Error.new('ID not defined') if !@pe_id - if ip.include?':' - addr_name = "MAC" - else - addr_name = "IP" - end + addr_name = address_type(ip) + + return addr_name if OpenNebula.is_error?(addr_name) lease_template = "LEASES = [ #{addr_name} = #{ip}" lease_template << ", AR_ID = #{ar_id}" if ar_id != -1 @@ -207,11 +206,9 @@ module OpenNebula def release(ip, ar_id=-1) return Error.new('ID not defined') if !@pe_id - if ip.include?':' - addr_name = "MAC" - else - addr_name = "IP" - end + addr_name = address_type(ip) + + return addr_name if OpenNebula.is_error?(addr_name) lease_template = "LEASES = [ #{addr_name} = #{ip}" lease_template << ", AR_ID = #{ar_id}" if ar_id != -1 @@ -243,11 +240,9 @@ module OpenNebula rtmpl << "NETWORK_ID = #{vnet}\n" if !vnet.nil? if !addr.nil? - if addr.include?':' - addr_name = "MAC" - else - addr_name = "IP" - end + addr_name = address_type(addr) + + return addr_name if OpenNebula.is_error?(addr_name) rtmpl << "#{addr_name} = #{addr}\n" end @@ -342,5 +337,27 @@ module OpenNebula chmod(-1, -1, -1, group_u, -1, -1, -1, -1, -1) end + # Returns the OpenNebula name of the address to use it in LEASE + # attributes. MAC, IP or IP6 is returned for MAC addresses in colon + # notation, ipv4 and ipv6 respectively + def address_type(addr) + begin + ipaddr = IPAddr.new addr + + if ipaddr.ipv4? + return "IP" + elsif ipaddr.ipv6? + return "IP6" + else + return Error.new('Unknown IP type') + end + rescue + if /^(\h{2}:){5}\h{2}$/ =~ addr + return "MAC" + else + return Error.new('Unknown address type') + end + end + end end end diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index b8f424254f..76a6845edc 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -301,13 +301,15 @@ void VirtualNetworkReserve::request_execute( return; } - string ip, mac; + string ip, mac, ip6; tmpl.get("IP", ip); + tmpl.get("IP6", ip6); + tmpl.get("MAC", mac); - if (!with_ar_id && (!ip.empty()||!mac.empty())) + if (!with_ar_id && (!ip.empty() || !mac.empty() || !ip6.empty())) { att.resp_msg = "AR_ID must be specified for IP/MAC based reservations"; failure_response(ACTION, att); @@ -421,11 +423,18 @@ void VirtualNetworkReserve::request_execute( { if (!ip.empty()) { - rc = vnpool->reserve_addr_by_ip(id, rid, size, ar_id, ip, att.resp_msg); + rc = vnpool->reserve_addr_by_ip(id, rid, size, ar_id, ip, + att.resp_msg); + } + if (!ip6.empty()) + { + rc = vnpool->reserve_addr_by_ip6(id, rid, size, ar_id, ip6, + att.resp_msg); } else if (!mac.empty()) { - rc = vnpool->reserve_addr_by_mac(id, rid, size, ar_id, mac, att.resp_msg); + rc = vnpool->reserve_addr_by_mac(id, rid, size, ar_id, mac, + att.resp_msg); } else { diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index 129515299e..261f06da40 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -310,7 +310,7 @@ int AddressRange::update_attributes( if (is_ipv6_static()) { - vup->replace("IP", attr->vector_value("IP")); + vup->replace("IP6", attr->vector_value("IP6")); } /* ----------------- Remove internal attributes ----------------- */ @@ -506,12 +506,14 @@ void AddressRange::addr_to_xml(unsigned int index, unsigned int rsize, if ( ip6[0] != 0 || ip6[1] != 0 || ip6[2] != 0 || ip6[3] != 0 ) { - unsigned int ip_low[2]; + unsigned int ip_low[4]; - ip_low[0] = ip6[0] + index; + ip_low[3] = ip6[3]; + ip_low[2] = ip6[2]; ip_low[1] = ip6[1]; + ip_low[0] = ip6[0] + index; - oss << "" << ip6_to_s(&(ip6[2]), ip_low, ip6_s) << ""; + oss << "" << ip6_to_s(ip_low, ip6_s) << ""; } oss << "" << rsize << "" @@ -590,16 +592,14 @@ void AddressRange::to_xml(ostringstream &oss) const if (is_ipv6_static()) { string ip6_s; + unsigned int ip_low[4]; - ip6_to_s(&(ip6[2]), ip6, ip6_s); - oss << "" << one_util::escape_xml(ip6_s) << ""; - - unsigned int ip_low[2]; - + ip_low[3] = ip6[3]; + ip_low[2] = ip6[2]; ip_low[1] = ip6[1]; ip_low[0] = ip6[0] + size - 1; - ip6_to_s(&(ip6[2]), ip_low, ip6_s); + ip6_to_s(ip_low, ip6_s); oss << "" << one_util::escape_xml(ip6_s) << ""; } @@ -674,7 +674,8 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, if (global6[1] != 0 || global6[0] != 0 ) /* Glocal Unicast */ { ip6_to_s(global6, mac, ip6_s); - oss << "" << one_util::escape_xml(ip6_s) << ""; + oss << "" << one_util::escape_xml(ip6_s) + << ""; ip6_to_s(global6, mac_end, ip6_s); oss << "" << one_util::escape_xml(ip6_s) @@ -685,16 +686,14 @@ void AddressRange::to_xml(ostringstream &oss, const vector& vms, if (is_ipv6_static()) { string ip6_s; + unsigned int ip_low[4]; - ip6_to_s(&(ip6[2]), ip6, ip6_s); - oss << "" << one_util::escape_xml(ip6_s) << ""; - - unsigned int ip_low[2]; - + ip_low[3] = ip6[3]; + ip_low[2] = ip6[2]; ip_low[1] = ip6[1]; ip_low[0] = ip6[0] + size - 1; - ip6_to_s(&(ip6[2]), ip_low, ip6_s); + ip6_to_s(ip_low, ip6_s); oss << "" << one_util::escape_xml(ip6_s) << ""; } @@ -958,7 +957,6 @@ int AddressRange::ip6_to_i(const string& _ip, unsigned int i_ip[]) const i_ip[0] = ntohl(s6.s6_addr32[3]); return 0; - } /* -------------------------------------------------------------------------- */ @@ -990,7 +988,8 @@ int AddressRange::prefix6_to_i(const string& prefix, unsigned int ip[]) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int AddressRange::ip6_to_s(const unsigned int prefix[], const unsigned int mac[], string& ip6_s) const +int AddressRange::ip6_to_s(const unsigned int prefix[], + const unsigned int mac[], string& ip6_s) const { unsigned int eui64[2]; unsigned int mlow = mac[0]; @@ -1016,6 +1015,28 @@ int AddressRange::ip6_to_s(const unsigned int prefix[], const unsigned int mac[] return -1; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRange::ip6_to_s(const unsigned int ip6_i[], string& ip6_s) const +{ + struct in6_addr ip6; + char dst[INET6_ADDRSTRLEN]; + + ip6.s6_addr32[3] = htonl(ip6_i[0]); + ip6.s6_addr32[2] = htonl(ip6_i[1]); + ip6.s6_addr32[1] = htonl(ip6_i[2]); + ip6.s6_addr32[0] = htonl(ip6_i[3]); + + if ( inet_ntop(AF_INET6, &ip6, dst, INET6_ADDRSTRLEN) != 0 ) + { + ip6_s = dst; + return 0; + } + + return -1; +} + /* ************************************************************************** */ /* ************************************************************************** */ @@ -1050,7 +1071,7 @@ bool AddressRange::is_valid_mac(unsigned int& index, const string& mac_s, bool AddressRange::is_valid_ip(unsigned int& index, const string& ip_s, bool check_free) { - if (!(type & 0x00000002))//Not of type IP4 or IP4_6 + if (!is_ipv4())//Not of type IP4 or IP4_6 { return false; } @@ -1080,6 +1101,41 @@ bool AddressRange::is_valid_ip(unsigned int& index, const string& ip_s, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +bool AddressRange::is_valid_ip6(unsigned int& index, const string& ip_s, + bool check_free) +{ + if (!is_ipv6_static())//Not of type IP6_STATIC or IP4_6_STATIC + { + return false; + } + + unsigned int ip_i[4]; + + if (ip6_to_i(ip_s, ip_i) == -1) + { + return false; + } + + //3 most significant 32bit blocks must be equal + if ( ip_i[3] != ip6[3] || ip_i[2] != ip6[2] || ip_i[1] != ip6[1] + || ip_i[0] < ip6[0] ) + { + return false; + } + + index = ip_i[0] - ip6[0]; + + if ((check_free && allocated.count(index) != 0) || (index >= size)) + { + return false; + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRange::set_mac(unsigned int addr_index, VectorAttribute * nic) const { unsigned int new_mac[2]; @@ -1140,13 +1196,15 @@ void AddressRange::set_ip6(unsigned int addr_index, VectorAttribute * nic) const void AddressRange::set_ip6_static(unsigned int addr_index, VectorAttribute * nic) const { - unsigned int low_ip[2]; + unsigned int ip_low[4]; string ip6_s; - low_ip[0] = ip6[0] + addr_index; - low_ip[1] = ip6[1]; + ip_low[3] = ip6[3]; + ip_low[2] = ip6[2]; + ip_low[1] = ip6[1]; + ip_low[0] = ip6[0] + addr_index; - if ( ip6_to_s(&(ip6[2]), low_ip, ip6_s) == 0 ) + if ( ip6_to_s(ip_low, ip6_s) == 0 ) { nic->replace("IP6", ip6_s); } @@ -1408,6 +1466,35 @@ int AddressRange::allocate_by_ip( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::allocate_by_ip6( + const string& ip6_s, + PoolObjectSQL::ObjectType ot, + int obid, + VectorAttribute* nic, + const vector& inherit) +{ + string error_msg; + unsigned int index; + + if (!is_valid_ip6(index, ip6_s, true)) + { + return -1; + } + + if (allocate_addr(index, 1, error_msg) != 0) + { + NebulaLog::log("IPM", Log::ERROR, error_msg); + return -1; + } + + allocate_by_index(index, ot, obid, nic, inherit); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac_s) { @@ -1470,6 +1557,45 @@ int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::free_addr_by_ip6(PoolObjectSQL::ObjectType ot, int obid, + const string& ip_s) +{ + string error_msg; + + if (!is_ipv6()) + { + return -1; + } + + unsigned int ip_i[4]; + + if (ip6_to_i(ip_s, ip_i) == -1) + { + return -1; + } + + unsigned int index = ip_i[0] - ip6[0]; + + if (index < 0 || index >= size || ip6[3] != ip_i[3] || ip6[2] != ip_i[2] + || ip6[1] != ip_i[1]) + { + return -1; + } + + if (free_addr(index, error_msg) != 0) + { + return -1; + } + + return free_allocated_addr(ot, obid, index); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid) { map::iterator it = allocated.begin(); @@ -1559,9 +1685,10 @@ const char * AddressRange::SG_RULE_ATTRIBUTES[] = { "TYPE", "SIZE", "MAC", - "IP"}; + "IP", + "IP6"}; -const int AddressRange::NUM_SG_RULE_ATTRIBUTES = 5; +const int AddressRange::NUM_SG_RULE_ATTRIBUTES = 6; void AddressRange::process_security_rule(VectorAttribute * rule) { @@ -1595,6 +1722,30 @@ void AddressRange::process_security_rule(VectorAttribute * rule) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::hold_by_ip6(const string& ip_s) +{ + string error_msg; + unsigned int index; + + if (!is_valid_ip6(index, ip_s, true)) + { + return -1; + } + + if (allocate_addr(index, 1, error_msg) != 0) + { + NebulaLog::log("IPM", Log::ERROR, error_msg); + return -1; + } + + set_allocated_addr(PoolObjectSQL::VM, -1, index); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::hold_by_ip(const string& ip_s) { string error_msg; @@ -1669,11 +1820,16 @@ int AddressRange::reserve_addr(int vid, unsigned int rsize, AddressRange *rar) set_mac(first_index, new_ar); - if (type & 0x00000002 ) + if ( is_ipv4() ) { set_ip(first_index, new_ar); } + if ( is_ipv6_static() ) + { + set_ip6_static(first_index, new_ar); + } + new_ar->replace("SIZE",rsize); new_ar->remove("IPAM_MAD"); @@ -1721,11 +1877,16 @@ int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize, set_mac(sindex, new_ar); - if (type & 0x00000002 ) + if ( is_ipv4() ) { set_ip(sindex, new_ar); } + if ( is_ipv6_static() ) + { + set_ip6_static(sindex, new_ar); + } + new_ar->replace("SIZE",rsize); new_ar->remove("IPAM_MAD"); @@ -1740,6 +1901,22 @@ int AddressRange::reserve_addr_by_index(int vid, unsigned int rsize, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::reserve_addr_by_ip6(int vid, unsigned int rsize, + const string& ip_s, AddressRange *rar) +{ + unsigned int sindex; + + if (!is_valid_ip6(sindex, ip_s, false)) + { + return -1; + } + + return reserve_addr_by_index(vid, rsize, sindex, rar); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::reserve_addr_by_ip(int vid, unsigned int rsize, const string& ip_s, AddressRange *rar) { diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index b0801196ec..5149807382 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -320,6 +320,27 @@ int AddressRangePool::allocate_by_ip(const string &ip, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRangePool::allocate_by_ip6(const string &ip, + PoolObjectSQL::ObjectType ot, int obid, VectorAttribute * nic, + const vector &inherit) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if (it->second->allocate_by_ip6(ip, ot, obid, nic, inherit) == 0) + { + used_addr++; + return 0; + } + } + + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::free_addr(unsigned int arid, PoolObjectSQL::ObjectType ot, int obid, const string& mac) { @@ -358,6 +379,25 @@ void AddressRangePool::free_addr_by_ip(unsigned int arid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRangePool::free_addr_by_ip6(unsigned int arid, + PoolObjectSQL::ObjectType ot, int obid, const string& ip) +{ + map::iterator it; + + it = ar_pool.find(arid); + + if (it!=ar_pool.end()) + { + if ( it->second->free_addr_by_ip6(ot, obid, ip) == 0 ) + { + used_addr--; + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::free_addr(PoolObjectSQL::ObjectType ot, int obid, const string& mac_s) { @@ -392,6 +432,23 @@ void AddressRangePool::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRangePool::free_addr_by_ip6(PoolObjectSQL::ObjectType ot, int obid, + const string& ip_s) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if (it->second->free_addr_by_ip6(ot, obid, ip_s) == 0) + { + used_addr--; + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRangePool::free_addr_by_owner(PoolObjectSQL::ObjectType ot, int oid) { map::iterator it; @@ -509,6 +566,7 @@ unsigned int AddressRangePool::get_size() const return total; } + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -556,6 +614,50 @@ int AddressRangePool::hold_by_ip(const string& ip_s) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRangePool::hold_by_ip6(unsigned int ar_id, const string& ip_s) +{ + map::const_iterator it; + + it = ar_pool.find(ar_id); + + if (it == ar_pool.end()) + { + return -1; + } + + int rc = it->second->hold_by_ip6(ip_s); + + if (rc == 0) + { + used_addr++; + } + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRangePool::hold_by_ip6(const string& ip_s) +{ + map::iterator it; + int rc = -1; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if (it->second->hold_by_ip6(ip_s) == 0) //At least one AR hold the IP + { + used_addr++; + rc = 0; + } + } + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRangePool::hold_by_mac(unsigned int ar_id, const string& mac_s) { map::iterator it; @@ -694,6 +796,30 @@ int AddressRangePool::reserve_addr_by_mac(int vid, unsigned int rsize, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRangePool::reserve_addr_by_ip6(int vid, unsigned int rsize, + unsigned int ar_id, const string& ip, AddressRange *rar) +{ + map::iterator it; + + it = ar_pool.find(ar_id); + + if (it == ar_pool.end()) + { + return -1; + } + + if (it->second->reserve_addr_by_ip6(vid, rsize, ip, rar) == 0) + { + used_addr += rsize; + return 0; + } + + return -1; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::process_security_rule( VectorAttribute * rule, vector &new_rules) diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index bf88d69c42..1b5582f983 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -652,15 +652,30 @@ int VirtualNetwork::nic_attribute( //-------------------------------------------------------------------------- int rc; + string ip6 = nic->vector_value("IP6"); string ip = nic->vector_value("IP"); string mac = nic->vector_value("MAC"); - if (!ip.empty()) + int ip_ne = ip.empty() ? 0 : 1; + int ip6_ne = ip6.empty() ? 0 : 1; + int mac_ne = mac.empty() ? 0 : 1; + + if ( ip_ne + ip6_ne + mac_ne > 1 ) + { + return -1; + } + + if (ip_ne == 1) { rc = allocate_by_ip(PoolObjectSQL::VM, vid, ip, nic->vector_attribute(), inherit_attrs); } - else if (!mac.empty()) + else if (ip6_ne == 1) + { + rc = allocate_by_ip6(PoolObjectSQL::VM, vid, ip6, nic->vector_attribute(), + inherit_attrs); + } + else if (mac_ne == 1) { rc = allocate_by_mac(PoolObjectSQL::VM, vid,mac,nic->vector_attribute(), inherit_attrs); @@ -718,15 +733,30 @@ int VirtualNetwork::vrouter_nic_attribute( if (floating) { + string ip6 = nic->vector_value("IP6"); string ip = nic->vector_value("IP"); string mac = nic->vector_value("MAC"); - if (!ip.empty()) + int ip_ne = ip.empty() ? 0 : 1; + int ip6_ne = ip6.empty() ? 0 : 1; + int mac_ne = mac.empty() ? 0 : 1; + + if ( ip_ne + ip6_ne + mac_ne > 1 ) + { + return -1; + } + + if (ip_ne == 1) { rc = allocate_by_ip(PoolObjectSQL::VROUTER, vrid, ip, nic->vector_attribute(), inherit_attrs); } - else if (!mac.empty()) + else if (ip6_ne == 1) + { + rc = allocate_by_ip6(PoolObjectSQL::VROUTER, vrid, ip6, + nic->vector_attribute(), inherit_attrs); + } + else if (mac_ne == 1) { rc = allocate_by_mac(PoolObjectSQL::VROUTER, vrid, mac, nic->vector_attribute(), inherit_attrs); @@ -846,35 +876,55 @@ int VirtualNetwork::hold_leases(VirtualNetworkTemplate * leases_template, unsigned int ar_id; string ip = lease->vector_value("IP"); + string ip6 = lease->vector_value("IP6"); string mac = lease->vector_value("MAC"); - if (ip.empty() && mac.empty()) + int ip_ne = ip.empty() ? 0 : 1; + int ip6_ne = ip6.empty() ? 0 : 1; + int mac_ne = mac.empty() ? 0 : 1; + + int attr_ne = ip_ne + ip6_ne + mac_ne; + + if ( attr_ne == 0 ) { - error_msg = "Missing MAC or IP."; + error_msg = "Missing MAC, IP or IP6."; + return -1; + } + else if ( attr_ne > 1 ) + { + error_msg = "Only one attribute MAC, IP or IP6 can be set."; return -1; } if (lease->vector_value("AR_ID", ar_id) != 0) //No AR_ID hold all addresses { - if (!mac.empty()) + if (mac_ne == 1) { rc = ar_pool.hold_by_mac(mac); } - else if (!ip.empty()) + else if (ip_ne == 1) { rc = ar_pool.hold_by_ip(ip); } + else if (ip6_ne == 1) + { + rc = ar_pool.hold_by_ip6(ip6); + } } else { - if (!mac.empty()) + if (mac_ne == 1) { rc = ar_pool.hold_by_mac(ar_id, mac); } - else if (!ip.empty()) + else if (ip_ne == 1) { rc = ar_pool.hold_by_ip(ar_id, ip); } + else if (ip6_ne == 1) + { + rc = ar_pool.hold_by_ip6(ar_id, ip6); + } } if (rc!=0) @@ -902,35 +952,55 @@ int VirtualNetwork::free_leases(VirtualNetworkTemplate * leases_template, unsigned int ar_id; string ip = lease->vector_value("IP"); + string ip6 = lease->vector_value("IP6"); string mac = lease->vector_value("MAC"); - if (ip.empty() && mac.empty()) + int ip_ne = ip.empty() ? 0 : 1; + int ip6_ne = ip6.empty() ? 0 : 1; + int mac_ne = mac.empty() ? 0 : 1; + + int attr_ne = ip_ne + ip6_ne + mac_ne; + + if ( attr_ne == 0 ) { - error_msg = "Missing MAC or IP."; + error_msg = "Missing MAC, IP or IP6."; + return -1; + } + else if ( attr_ne > 1 ) + { + error_msg = "Only one attribute MAC, IP or IP6 can be set."; return -1; } if (lease->vector_value("AR_ID", ar_id) != 0) //No AR_ID free all addresses { - if (!mac.empty()) + if ( mac_ne == 1 ) { ar_pool.free_addr(PoolObjectSQL::VM, -1, mac); } - else if (!ip.empty()) + else if ( ip_ne == 1 ) { ar_pool.free_addr_by_ip(PoolObjectSQL::VM, -1, ip); } + else if ( ip6_ne == 1 ) + { + ar_pool.free_addr_by_ip6(PoolObjectSQL::VM, -1, ip6); + } } else { - if (!mac.empty()) + if ( mac_ne == 1 ) { ar_pool.free_addr(ar_id, PoolObjectSQL::VM, -1, mac); } - else if (!ip.empty()) + else if ( ip_ne == 1 ) { ar_pool.free_addr_by_ip(ar_id, PoolObjectSQL::VM, -1, ip); } + else if ( ip6_ne == 1 ) + { + ar_pool.free_addr_by_ip6(ar_id, PoolObjectSQL::VM, -1, ip6); + } } return 0; @@ -1030,6 +1100,27 @@ int VirtualNetwork::reserve_addr_by_ip(int rid, unsigned int rsize, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualNetwork::reserve_addr_by_ip6(int rid, unsigned int rsize, + unsigned int ar_id, const string& ip, AddressRange *rar, string& error_str) +{ + if (ar_pool.reserve_addr_by_ip6(rid, rsize, ar_id, ip, rar)!=0) + { + ostringstream oss; + + oss << "Not enough free addresses in address range " << ar_id + << ", or it does not exist"; + + error_str = oss.str(); + + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VirtualNetwork::reserve_addr_by_mac(int rid, unsigned int rsize, unsigned int ar_id, const string& mac, AddressRange *rar, string& error_str) { diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 7dfce15970..77d6f58aa1 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -586,8 +586,48 @@ int VirtualNetworkPool::reserve_addr(int pid, int rid, unsigned int rsize, unsig /* -------------------------------------------------------------------------- */ -int VirtualNetworkPool::reserve_addr_by_ip(int pid, int rid, unsigned int rsize, unsigned int ar_id, - const string& ip, string& err) +int VirtualNetworkPool::reserve_addr_by_ip6(int pid, int rid, unsigned int rsize, + unsigned int ar_id, const string& ip, string& err) +{ + AddressRange * rar = allocate_ar(rid, err); + + if ( rar == 0 ) + { + return -1; + } + + VirtualNetwork * pvn = get(pid, true); + + if ( pvn == 0 ) + { + delete rar; + + ostringstream oss; + oss << "Virtual network " << pid << " does not exist"; + + err = oss.str(); + return -1; + } + + int rc = pvn->reserve_addr_by_ip6(rid, rsize, ar_id, ip, rar, err); + + update(pvn); + + pvn->unlock(); + + if ( rc != 0) + { + delete rar; + return -1; + } + + return add_ar(rid, rar, err); +} + +/* -------------------------------------------------------------------------- */ + +int VirtualNetworkPool::reserve_addr_by_ip(int pid, int rid, unsigned int rsize, + unsigned int ar_id, const string& ip, string& err) { AddressRange * rar = allocate_ar(rid, err); From 27956d9891ec7a0e777357a3049b4e9de6e73277 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 21 Feb 2017 16:57:24 +0100 Subject: [PATCH 3/5] Fix server_cipher client for Ruby 2.4 (crypt token must be 32bytes) --- src/authm_mad/remotes/server_cipher/server_cipher_auth.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/authm_mad/remotes/server_cipher/server_cipher_auth.rb b/src/authm_mad/remotes/server_cipher/server_cipher_auth.rb index eb99d706ca..51001698a6 100644 --- a/src/authm_mad/remotes/server_cipher/server_cipher_auth.rb +++ b/src/authm_mad/remotes/server_cipher/server_cipher_auth.rb @@ -39,12 +39,13 @@ class OpenNebula::ServerCipherAuth @srv_passwd = srv_passwd if !srv_passwd.empty? - @key = Digest::SHA1.hexdigest(@srv_passwd) + # truncate token to 32-bytes for Ruby >= 2.4 + @key = Digest::SHA1.hexdigest(@srv_passwd)[0..31] else @key = "" end - @cipher = OpenSSL::Cipher::Cipher.new(CIPHER) + @cipher = OpenSSL::Cipher.new(CIPHER) end ########################################################################### @@ -109,7 +110,8 @@ class OpenNebula::ServerCipherAuth # auth method for auth_mad def authenticate(srv_user,srv_pass, signed_text) begin - @key = srv_pass + # truncate token to 32-bytes for Ruby >= 2.4 + @key = srv_pass[0..31] s_user, t_user, expires = decrypt(signed_text).split(':') From faf2c6f3b84c49651b374bb9fb4e68ee92cf8ffb Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 21 Feb 2017 17:24:05 +0100 Subject: [PATCH 4/5] F #5027: Update security group driver to work with the IP6 static AR --- src/vnm_mad/remotes/lib/security_groups.rb | 5 ++ .../remotes/lib/security_groups_iptables.rb | 51 +++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/vnm_mad/remotes/lib/security_groups.rb b/src/vnm_mad/remotes/lib/security_groups.rb index aac7552afc..18a976ad6d 100644 --- a/src/vnm_mad/remotes/lib/security_groups.rb +++ b/src/vnm_mad/remotes/lib/security_groups.rb @@ -70,6 +70,7 @@ module VNMNetwork @range = @rule[:range] @ip = @rule[:ip] + @ip6 = @rule[:ip6] @ip6_global = @rule[:ip6_global] @ip6_ula = @rule[:ip6_ula] @size = @rule[:size] @@ -124,6 +125,10 @@ module VNMNetwork nets += VNMNetwork::to_nets(@ip6_ula, @size.to_i) end + if @ip6 && @size + nets += VNMNetwork::to_nets(@ip6, @size.to_i) + end + return nets end diff --git a/src/vnm_mad/remotes/lib/security_groups_iptables.rb b/src/vnm_mad/remotes/lib/security_groups_iptables.rb index c8540750f9..bca6bdad77 100644 --- a/src/vnm_mad/remotes/lib/security_groups_iptables.rb +++ b/src/vnm_mad/remotes/lib/security_groups_iptables.rb @@ -84,7 +84,7 @@ module SGIPTables sets = [] the_nets.each do |n| - if IPAddr.new(the_nets[0]).ipv6? + if IPAddr.new(the_nets[n]).ipv6? command = :ip6tables family = "inet6" else @@ -124,32 +124,39 @@ module SGIPTables return if the_nets.empty? - if IPAddr.new(the_nets[0]).ipv6? - command = :ip6tables - family = "inet6" - else - command = :iptables - family = "inet" - end - - if @rule_type == :inbound - chain = vars[:chain_in] - set = "#{vars[:set_sg_in]}-nr-#{family}" - dir = "src,dst" - else - chain = vars[:chain_out] - set = "#{vars[:set_sg_out]}-nr-#{family}" - dir = "dst,dst" - end - - cmds.add :ipset, "create #{set} hash:net,port family #{family}" - cmds.add command, "-A #{chain} -m set --match-set" \ - " #{set} #{dir} -j RETURN" + sets = [] the_nets.each do |n| + if IPAddr.new(the_nets[n]).ipv6? + command = :ip6tables + family = "inet6" + else + command = :iptables + family = "inet" + end + + if @rule_type == :inbound + chain = vars[:chain_in] + set = "#{vars[:set_sg_in]}-nr-#{family}" + dir = "src,dst" + else + chain = vars[:chain_out] + set = "#{vars[:set_sg_out]}-nr-#{family}" + dir = "dst,dst" + end + + if !sets.include?(set) + cmds.add :ipset, "create #{set} hash:net,port family #{family}" + cmds.add command, "-A #{chain} -m set --match-set" \ + " #{set} #{dir} -j RETURN" + + sets << set + end + @range.split(",").each do |r| r.gsub!(":","-") net_range = "#{n},#{@protocol}:#{r}" + cmds.add :ipset, "add -exist #{set} #{net_range}" end end From a78630ded347de9fd8b9e6753eb2f34595e35487 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 22 Feb 2017 15:30:22 +0100 Subject: [PATCH 5/5] F #5027: Adds support for ipv6 addresses in several commands of onevnet. Fix bugs --- src/cli/one_helper/onevnet_helper.rb | 11 ++++++++++- src/cli/onevnet | 17 +++++++++++------ src/rm/RequestManagerVirtualNetwork.cc | 2 +- src/vnm/AddressRange.cc | 2 +- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index 6f1e2f7dfc..be1fb35d6e 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -48,6 +48,14 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper :description => "First IP address in . notation" } + IP6 = { + :name => "ip6", + :short => "-6 ip6", + :large => "--ip6 ip6", + :format => String, + :description => "First IPv6 address in : notation" + } + SIZE = { :name => "size", :short => "-s size", @@ -117,7 +125,8 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper ] ADDAR_OPTIONS = [ - SIZE, MAC, IP, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VN_MAD, VLAN_ID ] + SIZE, MAC, IP, IP6, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VN_MAD, + VLAN_ID ] def self.rname "VNET" diff --git a/src/cli/onevnet b/src/cli/onevnet index dbb238273e..562d5ef752 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -123,15 +123,17 @@ cmd=CommandParser::CmdParser.new(ARGV) do if options[:ip] if options[:ip6_global] || options[:ip6_ula] ar << "TYPE=\"IP4_6\"" + elsif options[:ip6] + ar << "TYPE=\"IP4_6_STATIC\"" else ar << "TYPE=\"IP4\"" end + elsif options[:ip6] + ar << "TYPE=\"IP6_STATIC\"" + elsif options[:ip6_global] || options[:ip6_ula] + ar << "TYPE=\"IP6\"" else - if options[:ip6_global] || options[:ip6_ula] - ar << "TYPE=\"IP6\"" - else - ar << "TYPE=\"ETHER\"" - end + ar << "TYPE=\"ETHER\"" end if options[:size] @@ -142,6 +144,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do end ar << ", IP = " << options[:ip] if options[:ip] + ar << ", IP6 = " << options[:ip6] if options[:ip6] ar << ", MAC = " << options[:mac] if options[:mac] ar << ", GLOBAL_PREFIX = " << options[:ip6_global] if options[:ip6_global] @@ -234,7 +237,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do command :reserve, reserve_desc, :vnetid, [:vnetid, nil], :options=>STD_OPTIONS + [OneVNetHelper::AR, OneVNetHelper::NAME, - OneVNetHelper::SIZE, OneVNetHelper::MAC, OneVNetHelper::IP] do + OneVNetHelper::SIZE, OneVNetHelper::MAC, OneVNetHelper::IP, + OneVNetHelper::IP6 ] do helper.perform_action(args[0],options,"reservation made") do |vn| size = options[:size] || -1 name = options[:name] || -1 @@ -242,6 +246,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do addr = nil addr = options[:mac] if options[:mac] addr = options[:ip] if options[:ip] + addr = options[:ip6] if options[:ip6] if size == -1 STDERR.puts "Specify a size (-s size) for the reservation" diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index 76a6845edc..4c8dabaa53 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -426,7 +426,7 @@ void VirtualNetworkReserve::request_execute( rc = vnpool->reserve_addr_by_ip(id, rid, size, ar_id, ip, att.resp_msg); } - if (!ip6.empty()) + else if (!ip6.empty()) { rc = vnpool->reserve_addr_by_ip6(id, rid, size, ar_id, ip6, att.resp_msg); diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index 261f06da40..1364fe53a4 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -1562,7 +1562,7 @@ int AddressRange::free_addr_by_ip6(PoolObjectSQL::ObjectType ot, int obid, { string error_msg; - if (!is_ipv6()) + if (!is_ipv6_static()) { return -1; }