Skip internet address for multicast channels 82/8282/1
authorMarcel Enguehard <[email protected]>
Fri, 1 Sep 2017 09:22:33 +0000 (11:22 +0200)
committerMarcel Enguehard <[email protected]>
Fri, 1 Sep 2017 09:22:33 +0000 (11:22 +0200)
Change-Id: Id91e3646a9b9fe60923d6f738fe627427968b8ad
Signed-off-by: Marcel Enguehard <[email protected]>
netmodel/model/type.py
vicn/resource/ip_assignment.py

index 9a7b874..19be310 100644 (file)
@@ -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):
index 3bb16ff..16624aa 100644 (file)
@@ -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)