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/cordSubscriber/cordSubscriberTest.json b/src/test/cordSubscriber/cordSubscriberTest.json
index 859baf7..5f1bf21 100644
--- a/src/test/cordSubscriber/cordSubscriberTest.json
+++ b/src/test/cordSubscriber/cordSubscriberTest.json
@@ -1,9 +1,10 @@
 {
-    "VOLTHA_HOST": "172.17.0.1",
-    "VOLTHA_REST_PORT": 8882,
-    "VOLTHA_IGMP_ITERATIONS": 100,
-    "VOLTHA_CONFIG_FAKE": true,
-    "VOLTHA_OLT_TYPE": "ponsim_olt",
-    "VOLTHA_OLT_MAC": "00:0c:e2:31:12:00",
-    "VOLTHA_UPLINK_VLAN_START": 333
-}
+    "VOLTHA_HOST": "172.17.0.1", 
+    "VOLTHA_REST_PORT": 8882, 
+    "VOLTHA_IGMP_ITERATIONS": 100, 
+    "VOLTHA_CONFIG_FAKE": true, 
+    "VOLTHA_OLT_TYPE": "ponsim_olt", 
+    "VOLTHA_OLT_MAC": "00:0c:e2:31:12:00", 
+    "VOLTHA_UPLINK_VLAN_START": 333, 
+    "VOLTHA_TEARDOWN": false
+}
\ No newline at end of file
diff --git a/src/test/cordSubscriber/cordSubscriberTest.py b/src/test/cordSubscriber/cordSubscriberTest.py
index 9d1f268..b98ad84 100644
--- a/src/test/cordSubscriber/cordSubscriberTest.py
+++ b/src/test/cordSubscriber/cordSubscriberTest.py
@@ -347,7 +347,7 @@
           cls.num_ports = cls.port_map['num_ports']
           if cls.num_ports > 1:
                 cls.num_ports -= 1 ##account for the tx port
-          cls.activate_apps(cls.apps + cls.olt_apps, deactivate = True)
+          cls.activate_apps(cls.apps + cls.olt_apps)
 
       @classmethod
       def tearDownClass(cls):
diff --git a/src/test/setup/cord-test.py b/src/test/setup/cord-test.py
index b058a5c..f017cc0 100755
--- a/src/test/setup/cord-test.py
+++ b/src/test/setup/cord-test.py
@@ -30,7 +30,7 @@
 from CordTestServer import cord_test_server_start,cord_test_server_stop,cord_test_server_shutdown,CORD_TEST_HOST,CORD_TEST_PORT
 from TestManifest import TestManifest
 from VolthaCtrl import VolthaService
-from EapolAAA import get_radius_macs
+from EapolAAA import get_radius_macs, get_radius_networks, radius_restore_users, RADIUS_USER_MAC_START, RADIUS_USER_MAC_END
 
 try:
     from docker import APIClient as Client
@@ -448,6 +448,10 @@
                 wan = 'ponmgmt'
         vcpe_port_num = port_num
         port_list = self.port_map['switch_port_list'] + self.port_map['switch_relay_port_list']
+        subscribers = self.port_map['num_ports'] * len(self.port_map['switch_port_list'])
+        subscriber_macs = get_radius_macs(subscribers,
+                                          start = RADIUS_USER_MAC_START,
+                                          end = RADIUS_USER_MAC_END)
         print('Provisioning the ports for the test container\n')
         for host_intf, ports in port_list:
             if self.switch_started is False and host_intf.startswith('br-int'):
@@ -480,13 +484,19 @@
                         host_intf = '{}_{}'.format(host_intf_base, host_index)
                         host_index += 1
 
+                port_mac = ''
+                if len(subscriber_macs) > 0:
+                    port_mac = subscriber_macs.pop(0)
+
                 ##Use pipeworks to configure container interfaces on host/bridge interfaces
-                pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4}'.format(host_intf, guest_if,
-                                                                           local_if, self.name, guest_ip)
+                pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4} {5}'.format(host_intf, guest_if,
+                                                                               local_if, self.name, guest_ip,
+                                                                               port_mac)
                 #if the wan interface is specified for uplink, then use it instead
                 if wan and port == self.port_map[uplink]:
-                    pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4}'.format(wan, guest_if,
-                                                                               local_if, self.name, guest_ip)
+                    pipework_cmd = 'pipework {0} -i {1} -l {2} {3} {4} {5}'.format(wan, guest_if,
+                                                                                   local_if, self.name, guest_ip,
+                                                                                   port_mac)
                 else:
                     if start_vlan != 0:
                         pipework_cmd += ' @{}'.format(start_vlan)
@@ -502,13 +512,25 @@
         if self.switch_started and self.radius:
             radius_macs = get_radius_macs(len(self.port_map['radius_ports']))
             radius_intf_index = 0
-            radius_intf_subnet = Radius.SUBNET_PREFIX
+            radius_networks = get_radius_networks(len(self.port_map['switch_radius_port_list']))
+            index = 0
             for host_intf, ports in self.port_map['switch_radius_port_list']:
+                prefix, subnet, gw = radius_networks[index]
+                mask = subnet.split('/')[-1]
+                #configure the host interface as the gateway
+                cmds = ( #'ip addr add {}/{} dev {}'.format(gw, mask, host_intf),
+                        'ip link set {} up'.format(host_intf),
+                )
+                print('Configuring host interface %s for radius server' %(host_intf))
+                for cmd in cmds:
+                    print('Running command: %s' %(cmd))
+                    res += os.system(cmd)
+                index += 1
                 for port in ports:
                     guest_if = 'eth{}'.format(radius_intf_index+2)
                     port_index = self.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
                     port_num += 1
@@ -518,6 +540,12 @@
                     print('Configuring Radius port %s on OVS bridge %s' %(guest_if, host_intf))
                     print('Running pipework command: %s' %(pipework_cmd))
                     res += os.system(pipework_cmd)
+                    brd = '{}.255'.format(prefix)
+                    brd_cmd = 'docker exec {} ifconfig {} broadcast {} up'.format(self.radius.name,
+                                                                                  guest_if,
+                                                                                  brd)
+                    print('Setting broadcast address to %s for radius interface %s' %(brd, guest_if))
+                    res += os.system(brd_cmd)
 
         self.setup_vcpes(vcpe_port_num)
         return res, port_num
@@ -938,7 +966,8 @@
     if radius_ip is None:
         ##Create Radius container
         radius = Radius(prefix = Container.IMAGE_PREFIX, update = update_map['radius'],
-                        network = test_manifest.docker_network)
+                        network = test_manifest.docker_network,
+                        olt_config = olt_config_file)
         radius_ip = radius.ip(network = Radius.NETWORK)
 
     print('Radius server running with IP %s' %radius_ip)
@@ -1222,7 +1251,8 @@
     ##Start Radius container if not started
     if radius_ip is None:
         radius = Radius(prefix = Container.IMAGE_PREFIX, update = update_map['radius'],
-                        network = test_manifest.docker_network)
+                        network = test_manifest.docker_network,
+                        olt_config = olt_config_file)
         radius_ip = radius.ip(network = Radius.NETWORK)
 
     print('Radius server running with IP %s' %radius_ip)
@@ -1351,6 +1381,7 @@
     radius_container = '{}{}:candidate'.format(prefix, Radius.IMAGE)
     quagga_container = '{}{}:candidate'.format(prefix, Quagga.IMAGE)
     Container.cleanup(radius_container)
+    radius_restore_users()
     Container.cleanup(quagga_container)
     if args.voltha_loc:
         voltha = VolthaService(args.voltha_loc, args.onos_ip)
diff --git a/src/test/tls/tlsTest.json b/src/test/tls/tlsTest.json
index ddc442b..105156a 100644
--- a/src/test/tls/tlsTest.json
+++ b/src/test/tls/tlsTest.json
@@ -2,5 +2,6 @@
     "VOLTHA_OLT_MAC": "00:0c:e2:31:12:00", 
     "VOLTHA_HOST": "172.17.0.1", 
     "VOLTHA_OLT_TYPE": "ponsim_olt", 
-    "VOLTHA_REST_PORT": 8882
-}
+    "VOLTHA_REST_PORT": 8882, 
+    "VOLTHA_TEARDOWN": false
+}
\ No newline at end of file
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)