aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--netmodel/model/type.py22
-rw-r--r--vicn/resource/ip_assignment.py35
2 files changed, 17 insertions, 40 deletions
diff --git a/netmodel/model/type.py b/netmodel/model/type.py
index 9a7b8740..19be3105 100644
--- a/netmodel/model/type.py
+++ b/netmodel/model/type.py
@@ -149,12 +149,16 @@ class Prefix(BaseType, metaclass=ABCMeta):
return self.get_iterator()
#Iterates by steps of prefix_len, e.g., on all available /31 in a /24
- def get_iterator(self, prefix_len=None):
+ def get_iterator(self, prefix_len=None, skip_internet_address=False):
if prefix_len is None:
prefix_len=self.MAX_PREFIX_SIZE
assert (prefix_len >= self.prefix_len and prefix_len<=self.MAX_PREFIX_SIZE)
step = 2**(self.MAX_PREFIX_SIZE - prefix_len)
- for ip in range(self.first_prefix_address(), self.last_prefix_address()+1, step):
+
+ start = self.first_prefix_address()
+ if skip_internet_address:
+ start = start+1
+ for ip in range(start, self.last_prefix_address()+1, step):
yield type(self)(ip, prefix_len)
class Inet4Prefix(Prefix):
@@ -190,20 +194,6 @@ class Inet6Prefix(Prefix):
def ntoa (cls, address):
return inet_ntop(AF_INET6, pack(">QQ", address >> 64, address & ((1 << 64) -1)))
- #skip_internet_address: skip a:b::0, as v6 often use default /64 prefixes
- def get_iterator(self, prefix_len=None, skip_internet_address=None):
- if skip_internet_address is None:
- #We skip the internet address if we iterate over Addresses
- if prefix_len is None:
- skip_internet_address = True
- #But not if we iterate over prefixes
- else:
- skip_internet_address = False
- it = super().get_iterator(prefix_len)
- if skip_internet_address:
- next(it)
- return it
-
class InetAddress(Prefix):
def get_tuple(self):
diff --git a/vicn/resource/ip_assignment.py b/vicn/resource/ip_assignment.py
index 3bb16ff9..16624aa5 100644
--- a/vicn/resource/ip_assignment.py
+++ b/vicn/resource/ip_assignment.py
@@ -93,13 +93,14 @@ class IpAssignment(Resource):
if not interfaces:
continue
- if self.PrefixClass is Inet6Prefix:
- # 0 is forbidden
- num_required_ip = len(interfaces) + 1
- elif channel.has_type("emulatedchannel"): #EmulatedChannel + IPv4
- num_required_ip = len(interfaces) + 2 + channel.nb_base_stations #Internet address + bcast
- else:
- num_required_ip = len(interfaces)
+ num_required_ip = len(interfaces)
+ if num_required_ip > 2:
+ # We must reserve the first IP (the internet address) and the last one (the broadcast address)
+ # It does not apply in the case of 2 addresses as you do not need broadcast on the point2point link
+ num_required_ip = num_required_ip + 2
+ if channel.has_type("emulatedchannel"):
+ num_required_ip = num_required_ip + channel.nb_base_stations
+
min_prefix_len = math.ceil(math.log(num_required_ip, 2))
prefix_len = min(self.max_prefix_len,
@@ -121,26 +122,12 @@ class IpAssignment(Resource):
# Use an iterator to assign IPs from the prefix to the
# interfaces
- it = prefix.get_iterator(it_prefix_len)
- # XXX MACCHA it is a prefix
-
- if channel.has_type("emulatedchannel"):
- #Internet address
- next(it)
+ # Skip internet address if necessary, i.e., if prefix contains more than 2 addresses
+ skip_internet_address = (prefix_len < self.PrefixClass.MAX_PREFIX_SIZE -1)
+ it = prefix.get_iterator(it_prefix_len, skip_internet_address = skip_internet_address)
for interface in interfaces:
if_prefix = next(it)
- #XXX We cannot assign prefix::0 as a valid address to an interface.
- #XXX For each interface with an ip6 address belonging to prefix,
- #XXX linux add prefix::0 to the local routing table. Therefore prefix::0 cannot be
- #XXX the address of a non local interface
- ip = if_prefix.ip_address
- if ip == prefix.first_prefix_address() and self.PrefixClass is Inet6Prefix:
- if if_prefix.prefix_len < if_prefix.MAX_PREFIX_SIZE:
- if_prefix.ip_address = ip+1
- else:
- if_prefix = next(it)
-
if_prefix.prefix_len = prefix_len
if self.PrefixClass is Inet6Prefix:
address = Inet6Address(if_prefix.ip_address, prefix_len)