Change the default for aaa to socket based because of eap tls.
Separate the radius port subnet. (though it doesn't work with EAP tls)
Dynamically add users on radius start that maps to the source mac.
This could be used with eap-md5/pap and sample customizer.
Disable voltha teardown for subscriber and tls tests.

Change-Id: Id4f1e1242456579d44dfbcfff2f9d1ee417dfff1
diff --git a/src/test/utils/CordContainer.py b/src/test/utils/CordContainer.py
index eb20294..97a3c87 100644
--- a/src/test/utils/CordContainer.py
+++ b/src/test/utils/CordContainer.py
@@ -47,6 +47,8 @@
 import shutil
 from OnosCtrl import OnosCtrl
 from OnosLog import OnosLog
+from OltConfig import OltConfig
+from EapolAAA import radius_add_users, radius_restore_users
 from onosclidriver import OnosCliDriver
 from threadPool import ThreadPool
 from threading import Lock
@@ -1086,28 +1088,38 @@
     IMAGE = 'cordtest/radius'
     NAME = 'cord-radius'
     NETWORK = 'cord-radius-test'
-    SUBNET = '11.0.0.0/24'
-    SUBNET_PREFIX = '11.0.0'
-    GATEWAY = '11.0.0.1'
+    SOCKET_SUBNET = '11.0.0.0/24'
+    SOCKET_SUBNET_PREFIX = '11.0.0'
+    SOCKET_GATEWAY = '11.0.0.1'
 
     @classmethod
     def create_network(cls, name = NETWORK):
         try:
-            Container.create_network(name, subnet = cls.SUBNET, gateway = cls.GATEWAY)
+            Container.create_network(name, subnet = cls.SOCKET_SUBNET, gateway = cls.SOCKET_GATEWAY)
         except:
             pass
 
     def __init__(self, name = NAME, image = IMAGE, prefix = '', tag = 'candidate',
-                 boot_delay = 10, restart = False, update = False, network = None, network_disabled = False):
+                 boot_delay = 10, restart = False, update = False, network = None,
+                 network_disabled = False, olt_config = ''):
         super(Radius, self).__init__(name, image, prefix = prefix, tag = tag, command = self.start_command)
         if update is True or not self.img_exists():
             self.build_image(self.image_name)
         if restart is True and self.exists():
             self.kill()
+        else:
+            subscribers = 10
+            if olt_config:
+                port_map, _ = OltConfig(olt_config).olt_port_map()
+                if port_map:
+                    subscribers = port_map['num_ports'] * len(port_map['switch_port_list'])
+            radius_restore_users()
+            radius_add_users(subscribers)
         if not self.exists():
             self.remove_container(name, force=True)
             host_config = self.create_host_config(port_list = self.ports,
-                                                  host_guest_map = self.host_guest_map)
+                                                  host_guest_map = self.host_guest_map,
+                                                  privileged = True)
             volumes = []
             for _,g in self.host_guest_map:
                 volumes.append(g)
diff --git a/src/test/utils/CordTestConfig.py b/src/test/utils/CordTestConfig.py
index 0910a31..8234cf0 100644
--- a/src/test/utils/CordTestConfig.py
+++ b/src/test/utils/CordTestConfig.py
@@ -18,6 +18,7 @@
 import unittest
 import json
 import os
+import time
 from nose.tools import assert_not_equal
 from nose.plugins import Plugin
 from CordTestUtils import log_test as log
@@ -141,6 +142,12 @@
     #load the sadis and aaa config
     OnosCtrl.sadis_load_config(olt_switch_map = olt_switch_map)
     OnosCtrl.aaa_load_config()
+    #OnosCtrl('org.opencord.aaa').deactivate()
+    #time.sleep(3)
+    #OnosCtrl('org.opencord.aaa').activate()
+    #time.sleep(3)
+    if voltha_enabled is False:
+        OnosCtrl.config_olt_access(VolthaCtrl.UPLINK_VLAN_START)
 
 def teardown_module(module):
     class_test = get_test_class(module)
diff --git a/src/test/utils/CordTestServer.py b/src/test/utils/CordTestServer.py
index 6bbcaf6..e495afb 100644
--- a/src/test/utils/CordTestServer.py
+++ b/src/test/utils/CordTestServer.py
@@ -31,7 +31,7 @@
 #
 from CordContainer import Container, Onos, OnosStopWrapper, OnosCord, OnosCordStopWrapper, Quagga, QuaggaStopWrapper, Radius, reinitContainerClients
 from OltConfig import OltConfig
-from EapolAAA import get_radius_macs
+from EapolAAA import get_radius_macs, get_radius_networks
 from nose.tools import nottest
 from SimpleXMLRPCServer import SimpleXMLRPCServer
 from resource import getrlimit, RLIMIT_NOFILE
@@ -144,14 +144,18 @@
         port_map, _ = olt.olt_port_map()
         Radius(prefix = Container.IMAGE_PREFIX, restart = True)
         radius_macs = get_radius_macs(len(port_map['radius_ports']))
+        radius_networks = get_radius_networks(len(port_map['switch_radius_port_list']))
         radius_intf_index = 0
-        radius_intf_subnet = Radius.SUBNET_PREFIX
+        index = 0
         for host_intf, ports in port_map['switch_radius_port_list']:
+            prefix, subnet, _ = radius_networks[index]
+            mask = subnet.split('/')[-1]
+            index += 1
             for port in ports:
                 guest_if = 'eth{}'.format(radius_intf_index + 2)
                 port_index = port_map[port]
                 local_if = 'r{}'.format(port_index)
-                guest_ip = '{}.{}/24'.format(radius_intf_subnet, port_index)
+                guest_ip = '{}.{}/{}'.format(prefix, port_index, mask)
                 mac = radius_macs[radius_intf_index]
                 radius_intf_index += 1
                 pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4} {5}'.format(host_intf, guest_if,
diff --git a/src/test/utils/EapolAAA.py b/src/test/utils/EapolAAA.py
index 8219e27..e9094c8 100644
--- a/src/test/utils/EapolAAA.py
+++ b/src/test/utils/EapolAAA.py
@@ -34,8 +34,10 @@
 from scapy_ssl_tls.ssl_tls import *
 from socket import *
 from struct import *
+import os
 import sys
 import binascii
+import shutil
 from nose.tools import assert_equal, assert_not_equal, assert_raises, assert_true
 from CordTestUtils import log_test
 
@@ -65,6 +67,8 @@
 cCertMsg = '\x0b\x00\x00\x03\x00\x00\x00'
 TLS_LENGTH_INCLUDED = 0x80
 TLS_MORE_FRAGMENTS = 0x40
+RADIUS_USER_MAC_START = (0x02 << 40) | (0x03 << 32) | (0x04 << 24) | 1
+RADIUS_USER_MAC_END =  (0x02 << 40) | (0x03 << 32) | (0x04 << 24) | (0xff << 16) | ( 0xff << 8 ) | 0xff
 
 class EapolPacket(object):
 
@@ -288,11 +292,15 @@
            EAP_RESPONSE = 2
            log_test.info( 'Changing invalid field values in tls auth packets====== version changing' )
 
-def get_radius_macs(num):
+def get_radius_macs(num, start = 0, end = 0):
     """Generate radius server mac addresses"""
     """Scope to generate 256*256*256 mac addresses"""
-    s = (0x00 << 40) | (0x02 << 32) | ( 0x03 << 24) | (1)
-    e = (0x00 << 40) | (0x02 << 32) | ( 0x03 << 24) | (0xff << 16) | (0xff << 8) | (0xff)
+    if start == 0 or end == 0:
+        s = (0x00 << 40) | (0x02 << 32) | ( 0x03 << 24) | (1)
+        e = (0x00 << 40) | (0x02 << 32) | ( 0x03 << 24) | (0xff << 16) | (0xff << 8) | (0xff)
+    else:
+        s = start
+        e = end
     n_macs = []
     for v in xrange(s, e):
         mask = (v & 0xff0000) == 0xff0000 or \
@@ -316,3 +324,64 @@
 
     #convert the number to macs
     return map(n_to_mac, n_macs)
+
+def get_radius_networks(num):
+    PORT_SUBNET_START = '12.0.0.0'
+    PORT_SUBNET_MASK = '/24'
+    PORT_SUBNET_END = '220.0.0.0'
+    port_start_list = map(lambda ip: int(ip), PORT_SUBNET_START.split('.'))
+    port_end_list = map(lambda ip: int(ip), PORT_SUBNET_END.split('.'))
+    port_subnet_start = (port_start_list[0] << 24) | ( port_start_list[1] << 16 ) | ( port_start_list[2] << 8 ) | 0
+    port_subnet_end = (port_end_list[0] << 24) | ( port_end_list[1] << 16 ) | ( port_end_list[2] << 8 ) | 0
+    mask = int(PORT_SUBNET_MASK[1:])
+    net_list = []
+    for n in xrange(port_subnet_start, port_subnet_end, 256):
+        subnet = ((n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, 0, mask)
+        prefix = subnet[:3]
+        gw = prefix + (1,)
+        subnet_s = '{}.{}.{}.{}/{}'.format(*subnet)
+        prefix_s = '{}.{}.{}'.format(*prefix)
+        gw_s = '{}.{}.{}.{}'.format(*gw)
+        net_list.append((prefix_s, subnet_s, gw_s))
+        if len(net_list) >= num:
+            break
+
+    return net_list
+
+def get_radius_user_file():
+    cur_dir = os.path.dirname(os.path.realpath(__file__))
+    radius_authorize = 'setup/radius-config/freeradius/mods-config/files/authorize'
+    radius_user_file = os.path.join(cur_dir, '..', *radius_authorize.split('/'))
+    return radius_user_file
+
+def radius_add_users(num):
+    global RADIUS_USER_MAC_START, RADIUS_USER_MAC_END
+    template = '''
+%s Cleartext-Password := "radpass"
+\tReply-Message := "Hello, %%{User-Name}"
+'''
+    radius_user_file = get_radius_user_file()
+    if not os.access(radius_user_file, os.F_OK):
+        return False
+    mac_start = RADIUS_USER_MAC_START
+    mac_end =   RADIUS_USER_MAC_END
+    macs = get_radius_macs(num, start = mac_start, end = mac_end)
+    save_file = '{}.save'.format(radius_user_file)
+    new_file = '{}.new'.format(radius_user_file)
+    shutil.copy(radius_user_file, save_file)
+    with open(radius_user_file, 'r') as f:
+        lines = f.readlines()
+    for m in macs:
+        lines.append(template %(m))
+    with open(new_file, 'w') as f:
+        f.writelines(lines)
+    os.rename(new_file, radius_user_file)
+    return True
+
+def radius_restore_users():
+    radius_user_file = get_radius_user_file()
+    save_file = '{}.save'.format(radius_user_file)
+    if not os.access(save_file, os.F_OK):
+        return False
+    os.rename(save_file, radius_user_file)
+    return True
diff --git a/src/test/utils/OnosCtrl.py b/src/test/utils/OnosCtrl.py
index a2daf20..64a2ea6 100644
--- a/src/test/utils/OnosCtrl.py
+++ b/src/test/utils/OnosCtrl.py
@@ -34,7 +34,7 @@
 import os,sys,time
 from OltConfig import OltConfig
 from CordTestUtils import get_mac, get_controller, log_test
-from EapolAAA import get_radius_macs
+from EapolAAA import get_radius_macs, get_radius_networks
 
 class OnosCtrl:
 
@@ -304,7 +304,7 @@
         return device_mac
 
     @classmethod
-    def aaa_load_config(cls, controller = None, olt_conf_file = ''):
+    def aaa_load_config(cls, controller = None, olt_conf_file = '', conn_type = 'socket'):
         ovs_devices = cls.get_devices(controller = controller, mfr = 'Nicira')
         if not ovs_devices:
             log_test.info('No OVS devices found to configure AAA connect points')
@@ -313,21 +313,29 @@
         port_map, _ = olt.olt_port_map()
         app = 'org.opencord.aaa'
         cfg = { 'apps' : { app : { 'AAA' : {} } } }
-        aaa_cfg = dict(radiusConnectionType = 'port',
+        if conn_type == 'socket':
+            customizer = 'default'
+        else:
+            customizer = 'sample'
+        aaa_cfg = dict(radiusConnectionType = conn_type,
                        radiusSecret = 'radius_password',
                        radiusServerPort = '1812',
-                       packetCustomizer = 'sample',
+                       packetCustomizer = customizer,
                        vlanId = -1)
-        radius_ip = os.getenv('ONOS_AAA_IP') or '11.0.0.3'
-        radius_subnet = '.'.join(radius_ip.split('.')[:-1])
+        radius_networks = get_radius_networks(len(port_map['switch_radius_port_list']))
+        index = 0
         for switch, ports in port_map['switch_radius_port_list']:
             radius_macs = get_radius_macs(len(ports))
+            prefix, _, _ = radius_networks[index]
+            index += 1
             aaa_cfg['nasIp'] = controller or cls.controller
             aaa_cfg['nasMac'] = radius_macs[0]
             aaa_cfg['radiusMac'] = radius_macs[0]
             connect_points = []
             radius_port = port_map[ ports[0] ]
-            radius_ip = '{}.{}'.format(radius_subnet, radius_port)
+            radius_ip = '{}.{}'.format(prefix, radius_port)
+            if conn_type == 'socket':
+                radius_ip = os.getenv('ONOS_AAA_IP')
             aaa_cfg['radiusIp'] = radius_ip
             for dev in ovs_devices:
                 device_id = dev['id']
@@ -382,7 +390,7 @@
                             'cache' : {
                                 'enabled' : False,
                                 'maxsize' : 50,
-                                'ttl' : 'PT10m',
+                                'ttl' : 'PT0m',
                             },
                         },
                         'entries' : [],
@@ -427,12 +435,19 @@
         #log_test.info('Sadis cfg: %s' %json.dumps(sadis_cfg, indent=4))
         cls.config(sadis_cfg, controller = controller)
 
-        # cls(sadis_app, controller = controller).deactivate()
-        # time.sleep(2)
-        # cls(sadis_app, controller = controller).activate()
-        # time.sleep(2)
+    @classmethod
+    def config_olt_access(cls, uplink_vlan, controller = None, defaultVlan = '0', olt_conf_file = ''):
+        olt = OltConfig(olt_conf_file = olt_conf_file)
+        port_map, _ = olt.olt_port_map()
+        uplink = str(port_map['uplink'])
+        device_config = { 'devices' : {} }
+        ovs_devices = cls.get_devices(controller = controller, mfr = 'Nicira')
+        for dev in ovs_devices:
+            device_id = dev['id']
+            device_config['devices'][device_id] = {}
+            device_config['devices'][device_id]['basic'] = dict(driver = 'default')
+            device_config['devices'][device_id]['accessDevice'] = dict(uplink = uplink,
+                                                                       vlan = uplink_vlan,
+                                                                       defaultVlan = defaultVlan)
 
-        # cls(aaa_app, controller = controller).deactivate()
-        # time.sleep(2)
-        # cls(aaa_app, controller = controller).activate()
-        # time.sleep(2)
+        cls.config(device_config, controller = controller)