Index: trunk/exodus/forms.py
===================================================================
--- trunk/exodus/forms.py	(revision 6467)
+++ trunk/exodus/forms.py	(revision 6469)
@@ -4,4 +4,5 @@
         link_is_wireless, new_ssid
 from exodus.wllogic import MASTER, MANAGED
+from exodus.settings import AP_SUBNET
 from exodus.wlipcalc import IPCalc
 
@@ -34,4 +35,22 @@
         model = Interface
 
+    def clean_polar(self):
+        polar = self.cleaned_data.get('polar')
+        self.type = self.cleaned_data.get('type')
+        
+        if polar and not link_is_wireless(self):
+            raise forms.ValidationError( 
+                    "An ethernet interface can't have a polarization.")
+        else:
+            return polar
+
+    def clean_antenna(self):
+        self.type = self.cleaned_data.get('type')
+        antenna = self.cleaned_data.get('antenna')
+        if antenna and not link_is_wireless(self):
+            raise forms.ValidationError(
+                    "An ethernet interface can't have an antenna.")
+        return antenna
+
     def clean_link(self):
         link = self.cleaned_data.get('link')
@@ -41,10 +60,7 @@
         # self.instance raises DoesNotExist, 
         # but self.instance.[pk, ssid, polar, etc] doesn't
-        # Primary Keys's always start at 1.
-        if self.instance.pk:
-            edit = True 
-        else:
-            edit = False
-            
+
+        edit = bool(self.instance.pk)
+
         if link:
             # if link is to self we don't need to check anything else
@@ -73,6 +89,13 @@
 
             # if link is ethernet, don't worry about master and managed.
+            # but we do want every link to link to one 'master' in the
+            # subnet.
+            # We assume that the link of a link is always the master.
+            # if link is to self, link.link_id == link.id
             elif not link_is_wireless(link):
-                return link
+                if link.id == link.link_id:
+                    return link
+                else:
+                    return link.link
 
             # if this elif is True, it means that 'link' is in managed 
@@ -103,5 +126,5 @@
                 # calc the new ipaddresses
                 ip = IPCalc(new_master.node, 30)  
-                new_master.ip , new_slave.ip = ip.ips
+                new_master.ip, new_slave.ip = ip.ips
                 new_master.netmask = new_slave.netmask = 30
                     
@@ -130,3 +153,43 @@
             return link
 
+    def clean_ip(self):
+        """Cleans the ip.
+
+        We calculate the ipaddresses of this link and the ones linked to it.
+        We also define the netmask in this routine.
+        """
+        #XXX: check if there is a free ip in the subnet
+        #XXX: if not generate a new ip
+        #XXX: Do we get here eventhough a validation error is raised
+        node = self.cleaned_data.get('node')
+        ip = self.cleaned_data.get('ip')
+        link = self.cleaned_data.get('link')   
+        ap = self.cleaned_data.get('accesspoint')
+        edit = bool(self.instance.pk)
+        # if we have an error, we don't calculate new ip addresses.
+        import pdb; pdb.set_trace() ;
+        if self._errors:
+            return ip
+        
+        if ap:
+            try:
+                new_ip = IPCalc(node, AP_SUBNET, link)
+            except Exception:
+                return ip    
+            ip = new_ip.ips[0]
+            if edit:
+                pass        
+            self.data['netmask'] = AP_SUBNET
+            #XXX: distribute ipaddresses
+            #XXX: add ips for links to.
+            
+        # if link is not defined, the link can have it's own ip.
+        #XXX: and not accespoint
+        if not link and not ap:
+            ip = IPCalc(node, 32) 
+            self.data['netmask'] = 32
+            return ip
+
+        return ip
+        
     #XXX: change SSID when iface.name changes    
Index: trunk/exodus/models.py
===================================================================
--- trunk/exodus/models.py	(revision 6467)
+++ trunk/exodus/models.py	(revision 6469)
@@ -86,18 +86,4 @@
         return self.name
 
-   # def save(self, force_insert=False, force_update=False):
-   #     #XXX: could there be racing conditions?
-   #     #XXX: Maybe move this to a model form, 
-   #     from wllogic import free_master_ip
-   #     # check if there is a masterip, if not generate one.
-   #     # check if there is a network change, if so, generate a new masterip.
-   #     if self.masterip:
-   #         old = Node.objects.get(pk=self.pk)
-   #         if old.network != self.network:
-   #             self.masterip = free_master_ip(self.network)
-   #     else:
-   #         self.masterip = free_master_ip(self.network)
-   #     super(Node, self).save(force_insert, force_update)
-
 class Interface(models.Model):
     node = models.ForeignKey(Node)
@@ -106,16 +92,16 @@
     iface = models.CharField(max_length=10, verbose_name="interface", 
             default='eth0')
+    accesspoint = models.BooleanField()
+    polar = models.CharField(blank=True, max_length=10, choices=POLAR_CHOICES)
+    antenna = models.ForeignKey(Antenna, blank=True, null=True)
+    link = models.ForeignKey('self', blank=True, null=True)
     ip = models.IPAddressField(unique=True, blank=True)
     netmask = models.IntegerField(default=30)
-    polar = models.CharField(blank=True, max_length=10, choices=POLAR_CHOICES)
     ssid = models.CharField(max_length=50, blank=True, null=True)
     mode = models.CharField(max_length=10, choices=WIFI_MODE_CHOICES,
             blank=True)
     channel = models.IntegerField(blank=True, null=True)
-    antenna = models.ForeignKey(Antenna, blank=True, null=True)
     shortdesc = models.CharField(blank=True, max_length=10)
     desc = models.CharField(blank=True, max_length=100)
-    accesspoint = models.BooleanField()
-    link = models.ForeignKey('self', blank=True, null=True)
    
     class Meta:
Index: trunk/exodus/settings.py
===================================================================
--- trunk/exodus/settings.py	(revision 6467)
+++ trunk/exodus/settings.py	(revision 6469)
@@ -19,4 +19,6 @@
 # Theses types are compatibale
 COMPAT = ('11b', '11g')
+# AP subnet size
+AP_SUBNET = 26
 
 
Index: trunk/exodus/tests.py
===================================================================
--- trunk/exodus/tests.py	(revision 6467)
+++ trunk/exodus/tests.py	(revision 6469)
@@ -49,14 +49,14 @@
 
     def test_ipcalc_get_used_ips(self):
+        list = set(['172.16.0.1', '172.16.0.2', '172.16.0.4', '172.16.0.5', 
+                '172.16.0.6', '172.16.0.7'])
+        used_list = self.ipcalc(30)._get_used_ips()
+        self.failUnlessEqual( list, used_list)
+
+    def test_ipcalc_get_free_network_addr(self):
+        from exodus.wllogic import show_addr
         list = ['172.16.0.1', '172.16.0.2', '172.16.0.4', '172.16.0.5', 
                 '172.16.0.6', '172.16.0.7']
-        used_list = self.ipcalc(30)._get_used_ips()
-        used_list.sort()
-        self.failUnlessEqual( list, used_list)
-
-    def test_ipcalc_get_free_network_addr(self):
-        list = ['172.16.0.1', '172.16.0.2', '172.16.0.4', '172.16.0.5', 
-                '172.16.0.6', '172.16.0.7']
-        network_addr = self.ipcalc(30)._get_free_network_addr(list)
+        network_addr = show_addr(self.ipcalc(30)._get_free_network_addr(list))
         self.failUnlessEqual(network_addr, '172.16.0.8')
 
Index: trunk/exodus/wlipcalc.py
===================================================================
--- trunk/exodus/wlipcalc.py	(revision 6467)
+++ trunk/exodus/wlipcalc.py	(revision 6469)
@@ -9,5 +9,5 @@
     """
 
-    def __init__(self, node, free_netmask):
+    def __init__(self, node, free_netmask, link = None):
         if free_netmask <= MASTERIP_NETMASK or free_netmask > 32:
             raise ValueError, 'Netmask out of bounds.'
@@ -17,4 +17,5 @@
         master_netmask = MASTERIP_NETMASK
         self.master_network = wl.get_network(self.master_ip, master_netmask)
+        self.link = link
 
         # calculate the number of ipaddresses in the subnetmask
@@ -56,19 +57,22 @@
         for i in self.node.interface_set.all():
             #XXX: rewrite to if i.ip in masterip??
-            if i.id == i.link_id:
+            # not i.id == self.link.id, don't populate used_list
+            # with ips from it's own netmask
+            if i.id == i.link_id and not i.id == self.link.id:
                 ip_size = self._ip_size(i.netmask)
                 network_addr = wl.network(i.ip, i.netmask)
-                for j in range(ip_size):
+                for j in xrange(ip_size):
                     used_list.append(wl.show_addr(network_addr + j))
-        return used_list
+        return set(used_list)
 
     def _get_free_network_addr(self, used_list):
         """Calculate a new network address with a used_list and given netmask.
         """
-        for i in range(self.master_ip_size/self.new_ip_size):
+        #XXX: network_addr in for loop(generator expression)/list comprehension
+        for i in xrange(self.master_ip_size/self.new_ip_size):
             network_addr = wl.parse_addr(self.master_network) + \
                     (self.new_ip_size * i)
             k = 0
-            for j in range(self.new_ip_size):
+            for j in xrange(self.new_ip_size):
                 new_ip = wl.show_addr(network_addr + j) 
                 if new_ip not in used_list:
Index: trunk/exodus/wllogic.py
===================================================================
--- trunk/exodus/wllogic.py	(revision 6467)
+++ trunk/exodus/wllogic.py	(revision 6469)
@@ -175,5 +175,2 @@
 		return 32	
 	return int(32) - int(ceil(log(number_ifaces+2,2)))
-
-
-
