diff options
-rw-r--r-- | netmodel/model/type.py | 22 | ||||
-rw-r--r-- | vicn/resource/ip_assignment.py | 35 |
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) |