blob: 208a9106cc7edf81834b5f436e55f8277722e96c [file] [log] [blame]
"""
Copyright (c) 2017 SONATA-NFV and Paderborn University
ALL RIGHTS RESERVED.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Neither the name of the SONATA-NFV, Paderborn University
nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
This work has been performed in the framework of the SONATA project,
funded by the European Commission under Grant number 671517 through
the Horizon 2020 and 5G-PPP programmes. The authors would like to
acknowledge the contributions of their colleagues of the SONATA
partner consortium (www.sonata-nfv.eu).
"""
from resources.net import Net
import threading
lock = threading.Lock()
__issued_ips = dict()
__default_subnet_size = 256
__default_subnet_bitmask = 24
__first_ip = Net.ip_2_int('10.0.0.0')
__last_ip = Net.ip_2_int('10.255.255.255')
__current_ip = __first_ip
def get_new_cidr(uuid):
"""
Calculates a unused cidr for a subnet.
:param uuid: The UUID of the subnet - Thus it can store which subnet gets which CIDR
:type uuid: ``str``
:return: Returns None if all available CIDR are used. Otherwise returns a valid CIDR.
:rtype: ``str``
"""
global lock
lock.acquire()
global __current_ip
while __first_ip <= __current_ip < __last_ip and __current_ip in __issued_ips:
__current_ip += __default_subnet_size
if __current_ip >= __last_ip or __current_ip < __first_ip or __current_ip in __issued_ips:
return None
__issued_ips[__current_ip] = uuid
lock.release()
return Net.int_2_ip(__current_ip) + '/' + str(__default_subnet_bitmask)
def free_cidr(cidr, uuid):
"""
Frees a issued CIDR thus it can be reused.
:param cidr: The currently used CIDR.
:type cidr: ``str``
:param uuid: The UUID of the Subnet, which uses this CIDR.
:type uuid: ``str``
:return: Returns False if the CIDR is None or the UUID did not correspond tho the used CIDR. Else it returns True.
:rtype: ``bool``
"""
if cidr is None:
return False
global __current_ip
int_ip = Net.cidr_2_int(cidr)
global lock
lock.acquire()
if int_ip in __issued_ips and __issued_ips[int_ip] == uuid:
del __issued_ips[int_ip]
if int_ip < __current_ip:
__current_ip = int_ip
lock.release()
return True
lock.release()
return False
def is_cidr_issued(cidr):
"""
Returns True if the CIDR is used.
:param cidr: The requested CIDR.
:type cidr: ``str``
:return: Returns True if the CIDR is used, else False.
:rtype: ``bool``
"""
if cidr is None:
return False
int_ip = Net.cidr_2_int(cidr)
if int_ip in __issued_ips:
return True
return False
def is_my_cidr(cidr, uuid):
"""
Checks if the UUID and the used CIDR are related.
:param cidr: The issued CIDR.
:type cidr: ``str``
:param uuid: The Subnet UUID.
:type uuid: ``str``
:return: Returns False if the CIDR is None or if the CIDR is not issued. Else returns True.
:rtype: ``bool``
"""
if cidr is None:
return False
int_ip = Net.cidr_2_int(cidr)
if not int_ip in __issued_ips:
return False
if __issued_ips[int_ip] == uuid:
return True
return False
def assign_cidr(cidr, uuid):
"""
Allows a subnet to request a specific CIDR.
:param cidr: The requested CIDR.
:type cidr: ``str``
:param uuid: The Subnet UUID.
:type uuid: ``str``
:return: Returns False if the CIDR is None or if the CIDR is already issued. Returns True if the CIDR could be
assigned to the UUID.
"""
if cidr is None:
return False
int_ip = Net.cidr_2_int(cidr)
if int_ip in __issued_ips:
return False
global lock
lock.acquire()
__issued_ips[int_ip] = uuid
lock.release()
return True