Merge "[CORD-642] Support IPv6 in fabric emulation"
diff --git a/TestON/drivers/common/cli/emulator/lincoemininetdriver.py b/TestON/drivers/common/cli/emulator/lincoemininetdriver.py
index bcdbf33..49ceea8 100644
--- a/TestON/drivers/common/cli/emulator/lincoemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/lincoemininetdriver.py
@@ -130,7 +130,7 @@
             main.lastResult = main.TRUE
             return main.TRUE
         else:
-            main.log.error(
+            main.log.info(
                 self.name +
                 ": PACKET LOST, HOST IS NOT REACHABLE" )
             main.lastResult = main.FALSE
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 2d61501..90f79a9 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -587,11 +587,10 @@
                 main.log.info( self.name + ": no packets lost, host is reachable" )
                 return main.TRUE
             else:
-                main.log.error(
+                main.log.warn(
                     self.name +
                     ": PACKET LOST, HOST IS NOT REACHABLE" )
                 return main.FALSE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
@@ -636,7 +635,7 @@
                 main.log.info( self.name + ": no packets lost, host is reachable" )
                 return main.TRUE
             else:
-                main.log.error(
+                main.log.info(
                     self.name +
                     ": PACKET LOST, HOST IS NOT REACHABLE" )
                 return main.FALSE
@@ -1603,7 +1602,7 @@
             main.log.info( self.name + ": Ping between two hosts SUCCESSFUL" )
             return main.TRUE
         else:
-            main.log.error( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
+            main.log.info( self.name + ": PACKET LOST, HOSTS NOT REACHABLE" )
             return main.FALSE
 
     def link( self, **linkargs ):
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index f4adb81..8788af0 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -318,7 +318,7 @@
             main.lastResult = main.TRUE
             return main.TRUE
         else:
-            main.log.error(
+            main.log.info(
                 self.name +
                 ": PACKET LOST, HOST IS NOT REACHABLE" )
             main.lastResult = main.FALSE
@@ -345,7 +345,7 @@
                 main.lastResult = main.TRUE
                 return main.TRUE
             else:
-                main.log.error( "PACKET LOST, HOST IS NOT REACHABLE" )
+                main.log.info( "PACKET LOST, HOST IS NOT REACHABLE" )
                 main.lastResult = main.FALSE
                 return main.FALSE
         except pexpect.EOF:
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 08f8a5b..d7847b6 100755
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -3347,7 +3347,7 @@
             main.cleanup()
             main.exit()
 
-    def partitions( self, jsonFormat=True ):
+    def partitions( self, candidates=False, jsonFormat=True ):
         """
         Returns the output of the raft partitions command for ONOS.
         """
@@ -3364,6 +3364,8 @@
         # },
         try:
             cmdStr = "onos:partitions"
+            if candidates:
+                cmdStr += " -c"
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
@@ -4704,7 +4706,7 @@
             return main.TRUE
         except AssertionError:
             main.log.exception( "" )
-            return None
+            return main.FALSE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4788,7 +4790,7 @@
             return main.TRUE
         except AssertionError:
             main.log.exception( "" )
-            return None
+            return main.FALSE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4824,7 +4826,7 @@
             return main.TRUE
         except AssertionError:
             main.log.exception( "" )
-            return None
+            return main.FALSE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4838,20 +4840,22 @@
             main.cleanup()
             main.exit()
 
-    def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
+    def portstate( self, dpid, port, state ):
         '''
         Description:
              Changes the state of port in an OF switch by means of the
              PORTSTATUS OF messages.
         params:
-            dpid - (string) Datapath ID of the device
-            port - (string) target port in the device
-            state - (string) target state (enable or disabled)
+            dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
+            port - (string) target port in the device. Ex: '2'
+            state - (string) target state (enable or disable)
         returns:
             main.TRUE if no exceptions were thrown and no Errors are
             present in the resoponse. Otherwise, returns main.FALSE
         '''
         try:
+            state = state.lower()
+            assert state == 'enable' or state == 'disable', "Unknown state"
             cmd =  "portstate {} {} {}".format( dpid, port, state )
             response = self.sendline( cmd, showResponse=True )
             assert response is not None, "Error in sendline"
@@ -4862,7 +4866,7 @@
             return main.TRUE
         except AssertionError:
             main.log.exception( "" )
-            return None
+            return main.FALSE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -5057,3 +5061,346 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
+    def vplsShow( self, jsonFormat=True ):
+        """
+        Description: Returns result of onos:vpls show, which should list the
+                     configured VPLS networks and the assigned interfaces.
+        Optional:
+            * jsonFormat: enable json formatting of output
+        Returns:
+            The output of the command or None on error.
+        """
+        try:
+            cmdStr = "vpls show"
+            if jsonFormat:
+                raise NotImplementedError
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            assert handle is not None, "Error in sendline"
+            assert "Command not found:" not in handle, handle
+            return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except NotImplementedError:
+            main.log.exception( self.name + ": Json output not supported")
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def parseVplsShow( self ):
+        """
+        Parse the cli output of 'vpls show' into json output. This is required
+        as there is currently no json output available.
+        """
+        try:
+            output = []
+            raw = self.vplsShow( jsonFormat=False )
+            namePat = "VPLS name: (?P<name>\w+)"
+            interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
+            encapPat = "Encapsulation: (?P<encap>\w+)"
+            pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
+            mIter = re.finditer( pattern, raw )
+            for match in mIter:
+                item = {}
+                item[ 'name' ] = match.group( 'name' )
+                ifaces = match.group( 'interfaces' ).split( ', ')
+                if ifaces == [ "" ]:
+                    ifaces = []
+                item[ 'interfaces' ] = ifaces
+                encap = match.group( 'encap' )
+                if encap != 'NONE':
+                    item[ 'encapsulation' ] = encap.lower()
+                output.append( item )
+            return output
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsList( self, jsonFormat=True ):
+        """
+        Description: Returns result of onos:vpls list, which should list the
+                     configured VPLS networks.
+        Optional:
+            * jsonFormat: enable json formatting of output
+        """
+        try:
+            cmdStr = "vpls list"
+            if jsonFormat:
+                raise NotImplementedError
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            assert handle is not None, "Error in sendline"
+            assert "Command not found:" not in handle, handle
+            return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except NotImplementedError:
+            main.log.exception( self.name + ": Json output not supported")
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsCreate( self, network ):
+        """
+        CLI command to create a new VPLS network.
+        Required arguments:
+            network - String name of the network to create.
+        returns:
+            main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            network = str( network )
+            cmdStr = "vpls create "
+            cmdStr += network
+            output = self.sendline( cmdStr )
+            assert output is not None, "Error in sendline"
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
+            assert "VPLS already exists:" not in output, output
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsDelete( self, network ):
+        """
+        CLI command to delete a VPLS network.
+        Required arguments:
+            network - Name of the network to delete.
+        returns:
+            main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            network = str( network )
+            cmdStr = "vpls delete "
+            cmdStr += network
+            output = self.sendline( cmdStr )
+            assert output is not None, "Error in sendline"
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
+            assert " not found" not in output, output
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsAddIface( self, network, iface ):
+        """
+        CLI command to add an interface to a VPLS network.
+        Required arguments:
+            network - Name of the network to add the interface to.
+            iface - The ONOS name for an interface.
+        returns:
+            main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            network = str( network )
+            iface = str( iface )
+            cmdStr = "vpls add-if "
+            cmdStr += network + " " + iface
+            output = self.sendline( cmdStr )
+            assert output is not None, "Error in sendline"
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
+            assert "already associated to network" not in output, output
+            assert "Interface cannot be added." not in output, output
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsRemIface( self, network, iface ):
+        """
+        CLI command to remove an interface from a VPLS network.
+        Required arguments:
+            network - Name of the network to remove the interface from.
+            iface - Name of the interface to remove.
+        returns:
+            main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            iface = str( iface )
+            cmdStr = "vpls rem-if "
+            cmdStr += network + " " + iface
+            output = self.sendline( cmdStr )
+            assert output is not None, "Error in sendline"
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
+            assert "is not configured" not in output, output
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsClean( self ):
+        """
+        Description: Clears the VPLS app configuration.
+        Returns: main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            cmdStr = "vpls clean"
+            handle = self.sendline( cmdStr )
+            assert handle is not None, "Error in sendline"
+            assert "Command not found:" not in handle, handle
+            return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def vplsSetEncap( self, network, encapType ):
+        """
+        CLI command to add an interface to a VPLS network.
+        Required arguments:
+            network - Name of the network to create.
+            encapType - Type of encapsulation.
+        returns:
+            main.TRUE on success and main.FALSE on failure
+        """
+        try:
+            network = str( network )
+            encapType = str( encapType ).upper()
+            assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
+            cmdStr = "vpls set-encap "
+            cmdStr += network + " " + encapType
+            output = self.sendline( cmdStr )
+            assert output is not None, "Error in sendline"
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
+            assert "already associated to network" not in output, output
+            assert "Encapsulation type " not in output, output
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def interfaces( self, jsonFormat=True ):
+        """
+        Description: Returns result of interfaces command.
+        Optional:
+            * jsonFormat: enable json formatting of output
+        Returns:
+            The output of the command or None on error.
+        """
+        try:
+            cmdStr = "interfaces"
+            if jsonFormat:
+                #raise NotImplementedError
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            assert handle is not None, "Error in sendline"
+            assert "Command not found:" not in handle, handle
+            return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except NotImplementedError:
+            main.log.exception( self.name + ": Json output not supported")
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 655f17e..4514047 100755
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -745,43 +745,43 @@
         NOTE: Assumes cells are located at:
             ~/<self.home>/tools/test/cells/
         """
-        # Variable initialization
-        cellDirectory = self.home + "/tools/test/cells/"
-        # We want to create the cell file in the dependencies directory
-        # of TestON first, then copy over to ONOS bench
-        tempDirectory = "/tmp/"
-        # Create the cell file in the directory for writing ( w+ )
-        cellFile = open( tempDirectory + fileName, 'w+' )
-        if isinstance( onosIpAddrs, types.StringType ):
-            onosIpAddrs = [ onosIpAddrs ]
-
-        # App string is hardcoded environment variables
-        # That you may wish to use by default on startup.
-        # Note that you  may not want certain apps listed
-        # on here.
-        appString = "export ONOS_APPS=" + appString
-        onosGroup = "export ONOS_GROUP=" + onosUser
-        onosUser = "export ONOS_USER=" + onosUser
-        if useSSH:
-            onosUseSSH = "export ONOS_USE_SSH=true"
-        mnString = "export OCN="
-        if mnIpAddrs == "":
-            mnString = ""
-        onosString = "export OC"
-        tempCount = 1
-
-        # Create ONOSNIC ip address prefix
-        tempOnosIp = str( onosIpAddrs[ 0 ] )
-        tempList = []
-        tempList = tempOnosIp.split( "." )
-        # Omit last element of list to format for NIC
-        tempList = tempList[ :-1 ]
-        # Structure the nic string ip
-        nicAddr = ".".join( tempList ) + ".*"
-        self.nicAddr = nicAddr
-        onosNicString = "export ONOS_NIC=" + nicAddr
-
         try:
+            # Variable initialization
+            cellDirectory = self.home + "/tools/test/cells/"
+            # We want to create the cell file in the dependencies directory
+            # of TestON first, then copy over to ONOS bench
+            tempDirectory = "/tmp/"
+            # Create the cell file in the directory for writing ( w+ )
+            cellFile = open( tempDirectory + fileName, 'w+' )
+            if isinstance( onosIpAddrs, types.StringType ):
+                onosIpAddrs = [ onosIpAddrs ]
+
+            # App string is hardcoded environment variables
+            # That you may wish to use by default on startup.
+            # Note that you  may not want certain apps listed
+            # on here.
+            appString = "export ONOS_APPS=" + appString
+            onosGroup = "export ONOS_GROUP=" + onosUser
+            onosUser = "export ONOS_USER=" + onosUser
+            if useSSH:
+                onosUseSSH = "export ONOS_USE_SSH=true"
+            mnString = "export OCN="
+            if mnIpAddrs == "":
+                mnString = ""
+            onosString = "export OC"
+            tempCount = 1
+
+            # Create ONOSNIC ip address prefix
+            tempOnosIp = str( onosIpAddrs[ 0 ] )
+            tempList = []
+            tempList = tempOnosIp.split( "." )
+            # Omit last element of list to format for NIC
+            tempList = tempList[ :-1 ]
+            # Structure the nic string ip
+            nicAddr = ".".join( tempList ) + ".*"
+            self.nicAddr = nicAddr
+            onosNicString = "export ONOS_NIC=" + nicAddr
+
             # Start writing to file
             cellFile.write( onosNicString + "\n" )
 
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
index 3570fd0..104fe3f 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
@@ -4,6 +4,7 @@
 
     #Environment variables
     <ENV>
+        #Cells that you use
         <cellName>sdnip_single</cellName>
         <appString>drivers,openflow,proxyarp</appString>
     </ENV>
@@ -21,14 +22,14 @@
     </DEPENDENCY>
 
     <config>
-        <peerNum> 3 </peerNum>
+        <peerNum> 7 </peerNum>
         <switchNum> 39 </switchNum>
     </config>
 
     <timers>
         <SdnIpSetup>10</SdnIpSetup>
         <TopoDiscovery>60</TopoDiscovery>
-        <PingTestWithRoutes>20</PingTestWithRoutes>
+        <PingTestWithRoutes>30</PingTestWithRoutes>
         <PingTestWithoutRoutes>100</PingTestWithoutRoutes>
         <RouteDelivery>60</RouteDelivery>
         <PathAvailable>20</PathAvailable>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
index f1ace78..aa7f34a 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
@@ -10,7 +10,6 @@
             Start mininet
         """
         import os
-        import imp
         main.case( "Setup the Mininet testbed" )
         main.dependencyPath = main.testDir + \
                               main.params[ 'DEPENDENCY' ][ 'path' ]
@@ -69,10 +68,8 @@
            onos-install -f
            onos-wait-for-start
         """
-        import json
         import time
         import os
-        from operator import eq
 
         main.case( "Setting up ONOS environment" )
 
@@ -200,6 +197,9 @@
             main.exit()
 
     def CASE200( self, main ):
+        import json
+        import time
+
         main.case( "Activate sdn-ip application" )
         main.log.info( "waiting link discovery......" )
         time.sleep( int( main.params['timers']['TopoDiscovery'] ) )
@@ -242,6 +242,8 @@
         '''
         This test case is to load the methods from other Python files.
         '''
+        import imp
+
         main.case( "Loading methods from other Python file" )
         # load the methods from other file
         wrapperFile = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
@@ -253,20 +255,29 @@
 
     def CASE1( self, main ):
         '''
-        ping test from 3 bgp peers to BGP speaker
+        ping test from 7 bgp peers to BGP speaker
         '''
 
         main.case( "Ping tests between BGP peers and speakers" )
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
-                       expectAllSuccess=True )
+        main.Functions.pingSpeakerToPeer( main, speakers=[ "spk1" ],
+                                          peers=[ "p64514", "p64515", "p64516" ],
+                                          expectAllSuccess=True )
 
+        main.Functions.pingSpeakerToPeer( main, speakers=[ "spk2" ],
+                                          peers=[ "p64517", "p64518" ],
+                                          expectAllSuccess=True )
+
+        main.Functions.pingSpeakerToPeer( main, speakers=[ "spk3" ],
+                                          peers=[ "p64519", "p64520" ],
+                                          expectAllSuccess=True )
 
     def CASE2( self, main ):
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
         import time
+        from operator import eq
+
         main.case( "Check point-to-point intents" )
         main.log.info( "There are %s BGP peers in total "
                        % main.params[ 'config' ][ 'peerNum' ] )
@@ -304,6 +315,11 @@
         allRoutesExpected.append( "5.0.0.0/24" + "/" + "10.0.5.1" )
         allRoutesExpected.append( "6.0.0.0/24" + "/" + "10.0.6.1" )
 
+        allRoutesExpected.append( "7.0.0.0/24" + "/" + "10.0.7.1" )
+        allRoutesExpected.append( "8.0.0.0/24" + "/" + "10.0.8.1" )
+        allRoutesExpected.append( "9.0.0.0/24" + "/" + "10.0.9.1" )
+        allRoutesExpected.append( "20.0.0.0/24" + "/" + "10.0.20.1" )
+
         getRoutesResult = main.ONOScli.routes( jsonFormat=True )
         allRoutesActual = \
             main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
@@ -330,7 +346,7 @@
         getIntentsResult = main.ONOScli.intents( jsonFormat=True )
         routeIntentsActualNum = \
             main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-        routeIntentsExpectedNum = 3
+        routeIntentsExpectedNum = 7
         if routeIntentsActualNum != routeIntentsExpectedNum:
             time.sleep( int( main.params['timers']['RouteDelivery'] ) )
             getIntentsResult = main.ONOScli.intents( jsonFormat=True )
@@ -364,10 +380,19 @@
         Ping test in data plane for each route
         '''
         main.case( "Ping test for each route, all hosts behind BGP peers" )
+        #No vlan
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=True )
+                                       hosts=[ "h64514", "h64515", "h64516" ],
+                                       expectAllSuccess=True )
+        #vlan 10
+        main.Functions.pingHostToHost( main,
+                                       hosts=[ "h64519", "h64520" ],
+                                       expectAllSuccess=True )
 
+        # vlan 20
+        main.Functions.pingHostToHost( main,
+                                       hosts=[ "h64517", "h64518" ],
+                                       expectAllSuccess=True )
 
     def CASE5( self, main ):
         '''
@@ -375,8 +400,8 @@
         '''
         import time
         main.case( "Bring down links and check routes/intents" )
-        main.step( "Bring down the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="peer64514",
+        main.step( "Bring down the link between sw32 and p64514" )
+        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
                                          OPTION="down" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult1,
@@ -385,15 +410,15 @@
 
         if linkResult1 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
+            main.Functions.checkRouteNum( main, 6 ) #We have 7 links between peers and sw. After one link down, 7-1=6.
+            main.Functions.checkM2SintentNum( main, 6 )
         else:
             main.log.error( "Bring down link failed!" )
             main.cleanup()
             main.exit()
 
-        main.step( "Bring down the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="peer64515",
+        main.step( "Bring down the link between sw8 and p64515" )
+        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
                                          OPTION="down" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult2,
@@ -401,15 +426,15 @@
                                 onfail="Bring down link failed!" )
         if linkResult2 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
+            main.Functions.checkRouteNum( main, 5 ) #2 links down, 7-2=5.
+            main.Functions.checkM2SintentNum( main, 5 )
         else:
             main.log.error( "Bring down link failed!" )
             main.cleanup()
             main.exit()
 
-        main.step( "Bring down the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="peer64516",
+        main.step( "Bring down the link between sw28 and p64516" )
+        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
                                          OPTION="down" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult3,
@@ -417,8 +442,8 @@
                                 onfail="Bring down link failed!" )
         if linkResult3 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 0 )
-            main.Functions.checkM2SintentNum( main, 0 )
+            main.Functions.checkRouteNum( main, 4 ) #3 links downs 7-3=4
+            main.Functions.checkM2SintentNum( main, 4 )
         else:
             main.log.error( "Bring down link failed!" )
             main.cleanup()
@@ -436,12 +461,13 @@
             onfail="Flow status is wrong!" )
 
         # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
-                       expectAllSuccess=False )
+        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
+                                          peers=["p64514", "p64515", "p64516"],
+                                          expectAllSuccess=False )
+
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=False )
+                                       hosts=["h64514", "h64515", "h64516"],
+                                       expectAllSuccess=False )
 
 
     def CASE6( self, main ):
@@ -450,8 +476,8 @@
         '''
         import time
         main.case( "Bring up links and check routes/intents" )
-        main.step( "Bring up the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="peer64514",
+        main.step( "Bring up the link between sw32 and p64514" )
+        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
                                          OPTION="up" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult1,
@@ -459,15 +485,15 @@
                                 onfail="Bring up link failed!" )
         if linkResult1 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
+            main.Functions.checkRouteNum( main, 5 ) #one links up, 4+1=5
+            main.Functions.checkM2SintentNum( main, 5 )
         else:
             main.log.error( "Bring up link failed!" )
             main.cleanup()
             main.exit()
 
-        main.step( "Bring up the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="peer64515",
+        main.step( "Bring up the link between sw8 and p64515" )
+        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
                                          OPTION="up" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult2,
@@ -475,15 +501,15 @@
                                 onfail="Bring up link failed!" )
         if linkResult2 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
+            main.Functions.checkRouteNum( main, 6 )
+            main.Functions.checkM2SintentNum( main, 6 )
         else:
             main.log.error( "Bring up link failed!" )
             main.cleanup()
             main.exit()
 
-        main.step( "Bring up the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="peer64516",
+        main.step( "Bring up the link between sw28 and p64516" )
+        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
                                          OPTION="up" )
         utilities.assertEquals( expect=main.TRUE,
                                 actual=linkResult3,
@@ -491,8 +517,8 @@
                                 onfail="Bring up link failed!" )
         if linkResult3 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
+            main.Functions.checkRouteNum( main, 7 )
+            main.Functions.checkM2SintentNum( main, 7 )
         else:
             main.log.error( "Bring up link failed!" )
             main.cleanup()
@@ -510,11 +536,11 @@
             onfail="Flow status is wrong!" )
 
         # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
+        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
+                       peers=["p64514", "p64515", "p64516"],
                        expectAllSuccess=True )
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
+                        hosts=["h64514", "h64515", "h64516"],
                         expectAllSuccess=True )
 
 
@@ -532,18 +558,18 @@
 
         if result == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
-            main.Functions.checkP2PintentNum( main, 12 )
+            main.Functions.checkRouteNum( main, 6 ) #stop one sw, which bring one link between peer and sw down.
+            main.Functions.checkM2SintentNum( main, 6 )
+            main.Functions.checkP2PintentNum( main, 36 ) #6 intents from sw to speakers x 6 intents to sw x 2 intents between them
         else:
             main.log.error( "Stopping switch failed!" )
             main.cleanup()
             main.exit()
 
         main.step( "Check ping between hosts behind BGP peers" )
-        result1 = main.Mininet.pingHost( src="host64514", target="host64515" )
-        result2 = main.Mininet.pingHost( src="host64515", target="host64516" )
-        result3 = main.Mininet.pingHost( src="host64514", target="host64516" )
+        result1 = main.Mininet.pingHost( src="h64514", target="h64515" )
+        result2 = main.Mininet.pingHost( src="h64515", target="h64516" )
+        result3 = main.Mininet.pingHost( src="h64514", target="h64516" )
 
         pingResult1 = ( result1 == main.FALSE ) and ( result2 == main.TRUE ) \
                                                 and ( result3 == main.FALSE )
@@ -556,9 +582,9 @@
             main.exit()
 
         main.step( "Check ping between BGP peers and speakers" )
-        result4 = main.Mininet.pingHost( src="speaker1", target="peer64514" )
-        result5 = main.Mininet.pingHost( src="speaker1", target="peer64515" )
-        result6 = main.Mininet.pingHost( src="speaker1", target="peer64516" )
+        result4 = main.Mininet.pingHost( src="spk1", target="p64514" )
+        result5 = main.Mininet.pingHost( src="spk1", target="p64515" )
+        result6 = main.Mininet.pingHost( src="spk1", target="p64516" )
 
         pingResult2 = ( result4 == main.FALSE ) and ( result5 == main.TRUE ) \
                                                 and ( result6 == main.TRUE )
@@ -606,9 +632,9 @@
 
         if result1 and result2:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
-            main.Functions.checkP2PintentNum( main, 18 )
+            main.Functions.checkRouteNum( main, 7 )
+            main.Functions.checkM2SintentNum( main, 7 )
+            main.Functions.checkP2PintentNum( main, 42 )
         else:
             main.log.error( "Starting switch failed!" )
             main.cleanup()
@@ -626,11 +652,11 @@
             onfail="Flow status is wrong!" )
 
         # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
+        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
+                       peers=["p64514", "p64515", "p64516"],
                        expectAllSuccess=True )
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
+                        hosts=["h64514", "h64515", "h64516"],
                         expectAllSuccess=True )
 
 
@@ -643,9 +669,9 @@
         check route number, P2P intent number, M2S intent number, ping test" )
 
         main.log.info( "Check the flow number correctness before stopping sw11" )
-        main.Functions.checkFlowNum( main, "sw11", 13 )
+        main.Functions.checkFlowNum( main, "sw11", 43 )
         main.Functions.checkFlowNum( main, "sw1", 3 )
-        main.Functions.checkFlowNum( main, "sw7", 3 )
+        main.Functions.checkFlowNum( main, "sw7", 34 )
         main.log.debug( main.Mininet.checkFlows( "sw11" ) )
         main.log.debug( main.Mininet.checkFlows( "sw1" ) )
         main.log.debug( main.Mininet.checkFlows( "sw7" ) )
@@ -658,9 +684,9 @@
         if result:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
-            main.Functions.checkP2PintentNum( main, 18 )
+            main.Functions.checkRouteNum( main, 7 )
+            main.Functions.checkM2SintentNum( main, 7 )
+            main.Functions.checkP2PintentNum( main, 42 )
         else:
             main.log.error( "Stopping switch failed!" )
             main.cleanup()
@@ -677,11 +703,11 @@
             onpass="Flow status is correct!",
             onfail="Flow status is wrong!" )
         # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
+        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
+                       peers=["p64514", "p64515", "p64516"],
                        expectAllSuccess=True )
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
+                        hosts=["h64514", "h64515", "h64516"],
                         expectAllSuccess=True )
 
 
@@ -694,8 +720,8 @@
         check route number, P2P intent number, M2S intent number, ping test" )
 
         main.log.info( "Check the flow status before starting sw11" )
-        main.Functions.checkFlowNum( main, "sw1", 11 )
-        main.Functions.checkFlowNum( main, "sw7", 5 )
+        main.Functions.checkFlowNum( main, "sw1", 33 )
+        main.Functions.checkFlowNum( main, "sw7", 28 )
         main.log.debug( main.Mininet.checkFlows( "sw1" ) )
         main.log.debug( main.Mininet.checkFlows( "sw7" ) )
 
@@ -710,9 +736,9 @@
                                 onfail="Connect switch to ONOS failed!" )
         if result1 and result2:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
-            main.Functions.checkP2PintentNum( main, 18 )
+            main.Functions.checkRouteNum( main, 7 )
+            main.Functions.checkM2SintentNum( main, 7 )
+            main.Functions.checkP2PintentNum( main, 42 )
 
             main.log.debug( main.Mininet.checkFlows( "sw11" ) )
             main.log.debug( main.Mininet.checkFlows( "sw1" ) )
@@ -733,9 +759,9 @@
             onpass="Flow status is correct!",
             onfail="Flow status is wrong!" )
         # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["peer64514", "peer64515", "peer64516"],
+        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
+                       peers=["p64514", "p64515", "p64516"],
                        expectAllSuccess=True )
         main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
+                        hosts=["h64514", "h64515", "h64516"],
                         expectAllSuccess=True )
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
index 428cbce..e99f4f6 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
@@ -78,8 +78,8 @@
         onfail = "Flow number in " + switch + " is wrong!" )
 
 
-def pingSpeakerToPeer( main, speakers = ["speaker1"],
-                       peers = ["peer64514", "peer64515", "peer64516"],
+def pingSpeakerToPeer( main, speakers = [ "spk1" ],
+                       peers = [ "peer64514", "peer64515", "peer64516" ],
                        expectAllSuccess = True ):
     """
     Carry out ping test between each BGP speaker and peer pair
@@ -125,7 +125,8 @@
         main.exit()
 
 
-def pingHostToHost( main, hosts = ["host64514", "host64515", "host64516"],
+def pingHostToHost( main,
+                    hosts = [ "h64514", "h64515", "h64516" ],
                 expectAllSuccess = True ):
     """
     Carry out ping test between each BGP host pair
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/USECASE_SdnipI2MN.py b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/USECASE_SdnipI2MN.py
index 754c03c..71907ea 100755
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/USECASE_SdnipI2MN.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/USECASE_SdnipI2MN.py
@@ -12,16 +12,11 @@
 """
 
 from mininet.net import Mininet
-from mininet.node import Controller, RemoteController
 from mininet.log import setLogLevel, info
 from mininet.cli import CLI
+from mininet.node import Host, RemoteController
 from mininet.topo import Topo
 from mininet.util import quietRun
-from mininet.moduledeps import pathCheck
-
-import os.path
-import time
-from subprocess import Popen, STDOUT, PIPE
 
 QUAGGA_DIR = '/usr/lib/quagga'
 QUAGGA_RUN_DIR = '/usr/local/var/run/quagga'
@@ -29,6 +24,18 @@
 # onos1IP = '10.254.1.201'
 numSw = 39
 
+class VLANHost( Host ):
+    def config( self, vlan=100, intfName=None, **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.intf( intfName )
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
+        self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
+        newName = '%s.%d' % ( intf, vlan )
+        intf.name = newName
+        self.nameToIntf[ newName ] = intf
+        return r
+
 
 class SDNTopo( Topo ):
     "SDN Topology"
@@ -38,9 +45,14 @@
         Topo.__init__( self, *args, **kwargs )
 
         # BGP peer hosts
-        peer64514 = self.addHost( 'peer64514' )
-        peer64515 = self.addHost( 'peer64515' )
-        peer64516 = self.addHost( 'peer64516' )
+        p64514 = self.addHost( 'p64514' )
+        p64515 = self.addHost( 'p64515' )
+        p64516 = self.addHost( 'p64516' )
+
+        p64517 = self.addHost( 'p64517', cls=VLANHost, vlan=20 )
+        p64518 = self.addHost( 'p64518', cls=VLANHost, vlan=20 )
+        p64519 = self.addHost( 'p64519', cls=VLANHost, vlan=10 )
+        p64520 = self.addHost( 'p64520', cls=VLANHost, vlan=10 )
 
         '''
         sw1 = self.addSwitch( 'SEAT', dpid = '00000000000000a1' )
@@ -131,18 +143,26 @@
 
 
         # BGP speaker hosts
-        speaker1 = self.addHost( 'speaker1' )
-        speaker2 = self.addHost( 'speaker2' )
+        spk1 = self.addHost( 'spk1' )
+        spk2 = self.addHost( 'spk2', cls=VLANHost, vlan=20 )
+        spk3 = self.addHost( 'spk3', cls=VLANHost, vlan=10 )
 
         root = self.addHost( 'root', inNamespace = False , ip = '0' )
 
         # hosts behind each AS
-        host64514 = self.addHost( 'host64514' )
-        host64515 = self.addHost( 'host64515' )
-        host64516 = self.addHost( 'host64516' )
+        h64514 = self.addHost( 'h64514' )
+        h64515 = self.addHost( 'h64515' )
+        h64516 = self.addHost( 'h64516' )
 
-        self.addLink( 'speaker1', sw24 )
-        self.addLink( 'speaker2', sw24 )
+        #VLAN hosts behind each AS
+        h64517 = self.addHost( 'h64517', cls=VLANHost, vlan=20 )
+        h64518 = self.addHost( 'h64518', cls=VLANHost, vlan=20 )
+        h64519 = self.addHost( 'h64519', cls=VLANHost, vlan=10 )
+        h64520 = self.addHost( 'h64520', cls=VLANHost, vlan=10 )
+
+        self.addLink( 'spk1', sw24 )
+        self.addLink( 'spk2', sw24 )
+        self.addLink( 'spk3', sw24 )
 
         # connect all switches
         self.addLink( sw1, sw2 )
@@ -197,26 +217,45 @@
         self.addLink( sw38, sw39 )
 
         # connection between switches and peers
-        self.addLink( peer64514, sw32 )
-        self.addLink( peer64515, sw8 )
-        self.addLink( peer64516, sw28 )
+        self.addLink( p64514, sw32 )
+        self.addLink( p64515, sw8 )
+        self.addLink( p64516, sw28 )
+
+        self.addLink( p64517, sw7 )
+        self.addLink( p64518, sw9 )
+        self.addLink( p64519, sw5 )
+        self.addLink( p64520, sw5 )  # should be sw5
 
         # connection between BGP peer and hosts behind the BGP peer
-        self.addLink( peer64514, host64514 )
-        self.addLink( peer64515, host64515 )
-        self.addLink( peer64516, host64516 )
+        self.addLink( p64514, h64514 )
+        self.addLink( p64515, h64515 )
+        self.addLink( p64516, h64516 )
+
+        self.addLink( p64517, h64517 )
+        self.addLink( p64518, h64518 )
+        self.addLink( p64519, h64519 )
+        self.addLink( p64520, h64520 )
+
 
         # Internal Connection To Hosts
-        self.addLink( swCtl100, peer64514 )
-        self.addLink( swCtl100, peer64515 )
-        self.addLink( swCtl100, peer64516 )
-        self.addLink( swCtl100, speaker1 )
-        self.addLink( swCtl100, speaker2 )
+        self.addLink( swCtl100, p64514 )
+        self.addLink( swCtl100, p64515 )
+        self.addLink( swCtl100, p64516 )
+
+        self.addLink( swCtl100, p64517 )
+        self.addLink( swCtl100, p64518 )
+        self.addLink( swCtl100, p64519 )
+        self.addLink( swCtl100, p64520 )
+
+        self.addLink( swCtl100, spk1 )
+        self.addLink( swCtl100, spk2 )
+        self.addLink( swCtl100, spk3 )
 
 
-
-        # add host64514 to control plane for ping test
-        self.addLink( swCtl100, host64514 )
+        # add h64514 to control plane for ping test
+        self.addLink( swCtl100, h64514 )
+        self.addLink( swCtl100, h64517 )
+        self.addLink( swCtl100, h64519 )
         self.addLink( swCtl100, root )
 
 
@@ -265,7 +304,6 @@
     host.cmd( zebra_cmd )
     host.cmd( quagga_cmd )
 
-
 def stopquagga():
     quietRun( 'sudo pkill -9 -f bgpd' )
     quietRun( 'sudo pkill -9 -f zebra' )
@@ -277,60 +315,118 @@
     net = Mininet( topo = topo, controller = RemoteController )
 
 
-    speaker1, speaker2, peer64514, peer64515, peer64516 = \
-    net.get( 'speaker1', 'speaker2' ,
-             'peer64514', 'peer64515', 'peer64516' )
+    spk1, spk2, spk3, p64514, p64515, p64516, p64517, p64518, p64519, p64520 = \
+    net.get( 'spk1', 'spk2', 'spk3',
+             'p64514', 'p64515', 'p64516', 'p64517', 'p64518', 'p64519', 'p64520' )
 
     # Adding addresses to host64513_1 interface connected to sw24
     # for BGP peering
-    speaker1.setMAC( '00:00:00:00:00:01', 'speaker1-eth0' )
-    speaker1.cmd( 'ip addr add 10.0.4.101/24 dev speaker1-eth0' )
-    speaker1.cmd( 'ip addr add 10.0.5.101/24 dev speaker1-eth0' )
-    speaker1.cmd( 'ip addr add 10.0.6.101/24 dev speaker1-eth0' )
+    spk1.setMAC( '00:00:00:00:00:01', 'spk1-eth0' )
+    spk1.cmd( 'ip addr add 10.0.4.101/24 dev spk1-eth0' )
+    spk1.cmd( 'ip addr add 10.0.5.101/24 dev spk1-eth0' )
+    spk1.cmd( 'ip addr add 10.0.6.101/24 dev spk1-eth0' )
+    spk1.defaultIntf().setIP( '10.1.4.101/24' )
+    spk1.defaultIntf().setMAC( '00:00:00:00:00:01' )
 
-    speaker1.defaultIntf().setIP( '10.1.4.101/24' )
-    speaker1.defaultIntf().setMAC( '00:00:00:00:00:01' )
+    spk2.setMAC( '00:00:00:00:00:02', 'spk2-eth0.20' )
+    spk2.cmd( 'ip addr add 10.0.7.101/24 dev spk2-eth0.20' )
+    spk2.cmd( 'ip addr add 10.0.8.101/24 dev spk2-eth0.20' )
+    spk2.defaultIntf().setIP( '10.1.7.101/24' )
+    spk2.defaultIntf().setMAC( '00:00:00:00:00:02' )
+
+    spk3.setMAC( '00:00:00:00:00:03', 'spk3-eth0.10' )
+    spk3.cmd( 'ip addr add 10.0.9.101/24 dev spk3-eth0.10' )
+    spk3.cmd( 'ip addr add 10.0.20.101/24 dev spk3-eth0.10' )
+    spk3.defaultIntf().setIP( '10.1.9.101/24' )
+    spk3.defaultIntf().setMAC( '00:00:00:00:00:03' )
+
+    p64517.config( vlan=20, intfName="p64517-eth1", ip="7.0.0.254" )
+    p64518.config( vlan=20, intfName="p64518-eth1", ip="8.0.0.254" )
+    p64519.config( vlan=10, intfName="p64519-eth1", ip="9.0.0.254" )
+    p64520.config( vlan=10, intfName="p64520-eth1", ip="20.0.0.254" )
 
     # Net has to be start after adding the above link
     net.start()
 
     # setup configuration on the interface connected to switch
-    peer64514.cmd( "ifconfig  peer64514-eth0 10.0.4.1 up" )
-    peer64514.setMAC( '00:00:00:00:00:04', 'peer64514-eth0' )
-    peer64515.cmd( "ifconfig  peer64515-eth0 10.0.5.1 up" )
-    peer64515.setMAC( '00:00:00:00:00:05', 'peer64515-eth0' )
-    peer64516.cmd( "ifconfig  peer64516-eth0 10.0.6.1 up" )
-    peer64516.setMAC( '00:00:00:00:00:06', 'peer64516-eth0' )
+    p64514.cmd( "ifconfig  p64514-eth0 10.0.4.1 up" )
+    p64514.setMAC( '00:00:00:00:00:04', 'p64514-eth0' )
+    p64515.cmd( "ifconfig  p64515-eth0 10.0.5.1 up" )
+    p64515.setMAC( '00:00:00:00:00:05', 'p64515-eth0' )
+    p64516.cmd( "ifconfig  p64516-eth0 10.0.6.1 up" )
+    p64516.setMAC( '00:00:00:00:00:06', 'p64516-eth0' )
+
+    p64517.cmd( "ifconfig  p64517-eth0.20 10.0.7.1 up" )
+    p64517.setMAC( '00:00:00:00:00:07', 'p64517-eth0.20' )
+    p64518.cmd( "ifconfig  p64518-eth0.20 10.0.8.1 up" )
+    p64518.setMAC( '00:00:00:00:00:08', 'p64518-eth0.20' )
+
+    p64519.cmd( "ifconfig  p64519-eth0.10 10.0.9.1 up" )
+    p64519.setMAC( '00:00:00:00:00:09', 'p64519-eth0.10' )
+    p64520.cmd( "ifconfig  p64520-eth0.10 10.0.20.1 up" )
+    p64520.setMAC( '00:00:00:00:00:20', 'p64520-eth0.10' )
 
     # setup configuration on the interface connected to hosts
-    peer64514.setIP( "4.0.0.254", 8, "peer64514-eth1" )
-    peer64514.setMAC( '00:00:00:00:00:44', 'peer64514-eth1' )
-    peer64515.setIP( "5.0.0.254", 8, "peer64515-eth1" )
-    peer64515.setMAC( '00:00:00:00:00:55', 'peer64515-eth1' )
-    peer64516.setIP( "6.0.0.254", 8, "peer64516-eth1" )
-    peer64516.setMAC( '00:00:00:00:00:66', 'peer64516-eth1' )
+    p64514.setIP( "4.0.0.254", 8, "p64514-eth1" )
+    p64514.setMAC( '00:00:00:00:00:44', 'p64514-eth1' )
+    p64515.setIP( "5.0.0.254", 8, "p64515-eth1" )
+    p64515.setMAC( '00:00:00:00:00:55', 'p64515-eth1' )
+    p64516.setIP( "6.0.0.254", 8, "p64516-eth1" )
+    p64516.setMAC( '00:00:00:00:00:66', 'p64516-eth1' )
+
+    p64517.setIP( "7.0.0.254", 8, "p64517-eth1.20" )
+    p64517.setMAC( '00:00:00:00:00:77', 'p64517-eth1.20' )
+    p64518.setIP( "8.0.0.254", 8, "p64518-eth1.20" )
+    p64518.setMAC( '00:00:00:00:00:88', 'p64518-eth1.20' )
+
+    p64519.setIP( "9.0.0.254", 8, "p64519-eth1.10" )
+    p64519.setMAC( '00:00:00:00:00:99', 'p64519-eth1.10' )
+    p64520.setIP( "20.0.0.254", 8, "p64520-eth1.10" )
+    p64520.setMAC( '00:00:00:00:00:20', 'p64520-eth1.10' )
+
 
     # enable forwarding on BGP peer hosts
-    peer64514.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
-    peer64515.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
-    peer64516.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64514.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64515.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64516.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+
+    p64517.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64518.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64519.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    p64520.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
 
     # config interface for control plane connectivity
-    peer64514.setIP( "192.168.0.4", 24, "peer64514-eth2" )
-    peer64515.setIP( "192.168.0.5", 24, "peer64515-eth2" )
-    peer64516.setIP( "192.168.0.6", 24, "peer64516-eth2" )
+    p64514.setIP( "192.168.0.4", 24, "p64514-eth2" )
+    p64515.setIP( "192.168.0.5", 24, "p64515-eth2" )
+    p64516.setIP( "192.168.0.6", 24, "p64516-eth2" )
+
+    p64517.setIP( "192.168.0.7", 24, "p64517-eth2" )
+    p64518.setIP( "192.168.0.8", 24, "p64518-eth2" )
+    p64519.setIP( "192.168.0.9", 24, "p64519-eth2" )
+    p64520.setIP( "192.168.0.20", 24, "p64520-eth2" )
 
     # Setup hosts in each non-SDN AS
-    host64514, host64515, host64516 = \
-    net.get( 'host64514', 'host64515', 'host64516' )
-    host64514.cmd( 'ifconfig host64514-eth0 4.0.0.1 up' )
-    host64514.cmd( 'ip route add default via 4.0.0.254' )
-    host64514.setIP( '192.168.0.44', 24, 'host64514-eth1' )  # for control plane
-    host64515.cmd( 'ifconfig host64515-eth0 5.0.0.1 up' )
-    host64515.cmd( 'ip route add default via 5.0.0.254' )
-    host64516.cmd( 'ifconfig host64516-eth0 6.0.0.1 up' )
-    host64516.cmd( 'ip route add default via 6.0.0.254' )
+    h64514, h64515, h64516, h64517, h64518, h64519, h64520 = \
+    net.get( 'h64514', 'h64515', 'h64516', 'h64517', 'h64518', 'h64519', 'h64520' )
+    h64514.cmd( 'ifconfig h64514-eth0 4.0.0.1 up' )
+    h64514.cmd( 'ip route add default via 4.0.0.254' )
+    h64514.setIP( '192.168.0.44', 24, 'h64514-eth1' )  # for control plane
+    h64515.cmd( 'ifconfig h64515-eth0 5.0.0.1 up' )
+    h64515.cmd( 'ip route add default via 5.0.0.254' )
+    h64516.cmd( 'ifconfig h64516-eth0 6.0.0.1 up' )
+    h64516.cmd( 'ip route add default via 6.0.0.254' )
 
+    h64517.cmd( 'ifconfig h64517-eth0.20 7.0.0.1 up' )
+    h64517.cmd( 'ip route add default via 7.0.0.254' )
+    h64517.setIP( '192.168.0.77', 24, 'h64517-eth1' )  # for control plane
+    h64518.cmd( 'ifconfig h64518-eth0.20 8.0.0.1 up' )
+    h64518.cmd( 'ip route add default via 8.0.0.254' )
+
+    h64519.cmd( 'ifconfig h64519-eth0.10 9.0.0.1 up' )
+    h64519.cmd( 'ip route add default via 9.0.0.254' )
+    h64519.setIP( '192.168.0.99', 24, 'h64519-eth1' )  # for control plane
+    h64520.cmd( 'ifconfig h64520-eth0.10 20.0.0.1 up' )
+    h64520.cmd( 'ip route add default via 20.0.0.254' )
 
     # set up swCtl100 as a learning
     swCtl100 = net.get( 'swCtl100' )
@@ -343,29 +439,38 @@
         swX = net.get( 'sw%s' % ( i ) )
         swX.cmd( 'ovs-vsctl set-controller sw%s tcp:%s:6653' % ( i, onos1IP ) )
     '''
-    # Start Quagga on border routers
+    # Start Quagga as the external BGP routers
     '''
     for i in range ( 64514, 64516 + 1 ):
         startquagga( 'peer%s' % ( i ), i, 'quagga%s.conf' % ( i ) )
     '''
-    startquagga( peer64514, 64514, 'quagga64514.conf' )
-    startquagga( peer64515, 64515, 'quagga64515.conf' )
-    startquagga( peer64516, 64516, 'quagga64516.conf' )
+    startquagga( p64514, 64514, 'quagga64514.conf' )
+    startquagga( p64515, 64515, 'quagga64515.conf' )
+    startquagga( p64516, 64516, 'quagga64516.conf' )
 
-    # start Quagga in SDN network
-    startquagga( speaker1, 64513, 'quagga-sdn.conf' )
+    startquagga( p64517, 64517, 'quagga64517.conf' )
+    startquagga( p64518, 64518, 'quagga64518.conf' )
+    startquagga( p64519, 64519, 'quagga64519.conf' )
+    startquagga( p64520, 64520, 'quagga64520.conf' )
 
+    # start Quagga as the BGP speaker
+    startquagga( spk1, 64513, 'quagga-sdn.conf' )
+    startquagga( spk2, 64512, 'quagga-sdn2.conf' )
+    startquagga( spk3, 64511, 'quagga-sdn3.conf' )
 
     root = net.get( 'root' )
+
     root.intf( 'root-eth0' ).setIP( '1.1.1.2/24' )
     root.cmd( 'ip addr add 192.168.0.100/24 dev root-eth0' )
 
-    speaker1.intf( 'speaker1-eth1' ).setIP( '1.1.1.1/24' )
-
+    spk1.intf( 'spk1-eth1' ).setIP( '1.1.1.1/24' )
+    spk2.intf( 'spk2-eth1' ).setIP( '1.1.1.3/24' )
+    spk3.intf( 'spk3-eth1' ).setIP( '1.1.1.5/24' )
 
     stopsshd()
 
-    hosts = [ peer64514, peer64515, peer64516, host64514];
+    hosts = [ p64514, p64515, p64516, p64517, p64518, p64519, p64520,
+              h64514, h64517, h64519 ];
     startsshds( hosts )
     #
     '''
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn.conf
index b5d8b12..558b2cd 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn.conf
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn.conf
@@ -14,7 +14,6 @@
 router bgp 64513
   bgp router-id 10.0.4.101
   timers bgp 1 3
-  !timers bgp 3 9
   neighbor 10.0.4.1 remote-as 64514
   neighbor 10.0.4.1 ebgp-multihop
   neighbor 10.0.4.1 timers connect 5
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn2.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn2.conf
new file mode 100644
index 0000000..6eb45d7
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn2.conf
@@ -0,0 +1,37 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+!
+router bgp 64513
+  bgp router-id 10.0.7.101
+  timers bgp 1 2
+  neighbor 10.0.7.1 remote-as 64517
+  neighbor 10.0.7.1 ebgp-multihop
+  neighbor 10.0.7.1 timers connect 5
+  neighbor 10.0.8.1 remote-as 64518
+  neighbor 10.0.8.1 ebgp-multihop
+  neighbor 10.0.8.1 timers connect 5
+
+  neighbor 1.1.1.2 remote-as 64513
+  neighbor 1.1.1.2 port 2000
+  neighbor 1.1.1.2 timers connect 5
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn3.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn3.conf
new file mode 100644
index 0000000..9154424
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga-sdn3.conf
@@ -0,0 +1,37 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+!
+router bgp 64513
+  bgp router-id 10.0.9.101
+  timers bgp 1 2
+  neighbor 10.0.9.1 remote-as 64519
+  neighbor 10.0.9.1 ebgp-multihop
+  neighbor 10.0.9.1 timers connect 5
+  neighbor 10.0.20.1 remote-as 64520
+  neighbor 10.0.20.1 ebgp-multihop
+  neighbor 10.0.20.1 timers connect 5
+
+  neighbor 1.1.1.2 remote-as 64513
+  neighbor 1.1.1.2 port 2000
+  neighbor 1.1.1.2 timers connect 5
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64517.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64517.conf
new file mode 100644
index 0000000..00e4cf8
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64517.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64517
+  bgp router-id 10.0.7.1
+!  timers bgp 1 3
+ neighbor 10.0.7.101 remote-as 64513
+ network 7.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64518.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64518.conf
new file mode 100644
index 0000000..c156102
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64518.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64518
+  bgp router-id 10.0.8.1
+!  timers bgp 1 3
+ neighbor 10.0.8.101 remote-as 64513
+ network 8.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64519.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64519.conf
new file mode 100644
index 0000000..11f1801
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64519.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64519
+  bgp router-id 10.0.9.1
+!  timers bgp 1 3
+ neighbor 10.0.9.101 remote-as 64513
+ network 9.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64520.conf b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64520.conf
new file mode 100644
index 0000000..5fa469d
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/quagga64520.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64520
+  bgp router-id 10.0.20.1
+!  timers bgp 1 3
+ neighbor 10.0.20.101 remote-as 64513
+ network 20.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/network-cfg.json b/TestON/tests/USECASE/USECASE_SdnipFunction/network-cfg.json
index 303b1bd..bf6fa1a 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/network-cfg.json
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/network-cfg.json
@@ -3,6 +3,7 @@
         "of:00000000000000a8/5" : {
             "interfaces" : [
                 {
+                    "name": "sw8-5",
                     "ips"  : [ "10.0.5.101/24" ],
                     "mac"  : "00:00:00:00:00:01"
                 }
@@ -11,6 +12,7 @@
         "of:0000000000000a32/4" : {
             "interfaces" : [
                 {
+                    "name" : "sw32-4",
                     "ips"  : [ "10.0.4.101/24" ],
                     "mac"  : "00:00:00:00:00:01"
                 }
@@ -19,10 +21,51 @@
         "of:0000000000000a28/3" : {
             "interfaces" : [
                 {
+                    "name" : "sw28-3",
                     "ips"  : [ "10.0.6.101/24" ],
                     "mac"  : "00:00:00:00:00:01"
                 }
             ]
+        },
+        "of:00000000000000a5/5" : {
+              "interfaces" : [
+                  {
+                      "name" : "sw5-5",
+                      "ips"  : [ "10.0.20.101/24" ],
+                      "mac"  : "00:00:00:00:00:03",
+                      "vlan" : "10"
+                  }
+              ]
+        },
+        "of:00000000000000a5/4" : {
+            "interfaces" : [
+                {
+                    "name" : "sw5-4",
+                    "ips"  : [ "10.0.9.101/24" ],
+                    "mac"  : "00:00:00:00:00:03",
+                    "vlan" : "10"
+                }
+            ]
+        },
+        "of:00000000000000a7/3" : {
+            "interfaces" : [
+                {
+                    "name" : "sw7-3",
+                    "ips"  : [ "10.0.7.101/24" ],
+                    "mac"  : "00:00:00:00:00:02",
+                    "vlan" : "20"
+                }
+            ]
+        },
+        "of:00000000000000a9/3" : {
+              "interfaces" : [
+                  {
+                      "name" : "sw9-3",
+                      "ips"  : [ "10.0.8.101/24" ],
+                      "mac"  : "00:00:00:00:00:02",
+                      "vlan" : "20"
+                  }
+              ]
         }
     },
     "apps" : {
@@ -30,13 +73,33 @@
             "bgp" : {
                 "bgpSpeakers" : [
                     {
+                        "name": "bgpSpeaker1",
                         "connectPoint" : "of:0000000000000a24/1",
                         "peers" : [
                             "10.0.4.1",
                             "10.0.5.1",
                             "10.0.6.1"
                         ]
+                    },
+                    {
+                        "name": "bgpSpeaker2",
+                        "vlan": "20",
+                        "connectPoint" : "of:0000000000000a24/2",
+                        "peers" : [
+                            "10.0.7.1",
+                            "10.0.8.1"
+                        ]
+                    },
+                    {
+                          "name": "bgpSpeaker3",
+                          "vlan": "10",
+                          "connectPoint" : "of:0000000000000a24/3",
+                          "peers" : [
+                              "10.0.9.1",
+                              "10.0.20.1"
+                          ]
                     }
+
                 ]
             }
         }
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params
new file mode 100755
index 0000000..9d9bab2
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.params
@@ -0,0 +1,32 @@
+<PARAMS>
+
+    <testcases>1,2,3</testcases>
+
+    <num_controllers>3</num_controllers>
+
+    <DEPENDENCY>
+        <wrapper1>startUp</wrapper1>
+        <topology>~/onos/tools/test/topos/vpls.json</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>vpls</cellName>
+        <cellApps>drivers,openflow,vpls</cellApps>
+        <cellUser>sdn</cellUser>
+    </ENV>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <vpls>
+        <name>org.onosproject.vpls</name>
+        <hosts>6</hosts>
+    </vpls>
+
+    <SLEEP>
+        <startup>10</startup>
+        <netcfg>10</netcfg>
+    </SLEEP>
+
+</PARAMS>
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
new file mode 100755
index 0000000..b09007e
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
@@ -0,0 +1,370 @@
+# CASE1: Startup
+# CASE2: Load vpls topology and configurations from demo script
+# CASE3: Test CLI commands
+
+class VPLSBasic:
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        """
+        CASE1 is to compile ONOS and push it to the test machines
+
+        Startup sequence:
+        cell <name>
+        onos-verify-cell
+        NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
+        onos-install -f
+        onos-wait-for-start
+        start cli sessions
+        start tcpdump
+        """
+        import imp
+        import time
+        import json
+        main.case( "Setting up test environment" )
+        main.caseExplanation = "Setup the test environment including " +\
+                                "installing ONOS, starting Mininet and ONOS" +\
+                                "cli sessions."
+
+        # load some variables from the params file
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+        main.numCtrls = int( main.params[ 'num_controllers' ] )
+
+        ofPort = main.params[ 'CTRL' ][ 'port' ]
+
+        main.CLIs = []
+        main.RESTs = []
+        main.nodes = []
+        ipList = []
+        for i in range( 1, main.numCtrls + 1 ):
+            try:
+                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+                main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+                ipList.append( main.nodes[ -1 ].ip_address )
+            except AttributeError:
+                break
+
+        main.step( "Create cell file" )
+        cellAppString = main.params[ 'ENV' ][ 'cellApps' ]
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
+                                       main.Mininet1.ip_address,
+                                       cellAppString, ipList )
+        main.step( "Applying cell variable to environment" )
+        cellResult = main.ONOSbench.setCell( cellName )
+        verifyResult = main.ONOSbench.verifyCell()
+
+        main.log.info( "Uninstalling ONOS" )
+        for node in main.nodes:
+            main.ONOSbench.onosUninstall( node.ip_address )
+
+        # Make sure ONOS is DEAD
+        main.log.info( "Killing any ONOS processes" )
+        killResults = main.TRUE
+        for node in main.nodes:
+            killed = main.ONOSbench.onosKill( node.ip_address )
+            killResults = killResults and killed
+
+        cleanInstallResult = main.TRUE
+
+        main.step( "Starting Mininet" )
+        # scp topo file to mininet
+        # TODO: move to params?
+        topoName = "vpls"
+        topoFile = "vpls.py"
+        filePath = main.ONOSbench.home + "/tools/test/topos/"
+        main.ONOSbench.scp( main.Mininet1,
+                            filePath + topoFile,
+                            main.Mininet1.home,
+                            direction="to" )
+        topo = " --custom " + main.Mininet1.home + topoFile + " --topo " + topoName
+        args = " --switch ovs,protocols=OpenFlow13 --controller=remote"
+        for node in main.nodes:
+            args += ",ip=" + node.ip_address
+        mnCmd = "sudo mn" + topo + args
+        mnResult = main.Mininet1.startNet( mnCmd=mnCmd )
+        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
+                                 onpass="Mininet Started",
+                                 onfail="Error starting Mininet" )
+
+        main.ONOSbench.getVersion( report=True )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.buckBuild()
+        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
+                                 onpass="ONOS package successful",
+                                 onfail="ONOS package failed" )
+
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for node in main.nodes:
+            tmpResult = main.ONOSbench.onosInstall( options="-f",
+                                                    node=node.ip_address )
+            onosInstallResult = onosInstallResult and tmpResult
+        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
+                                 onpass="ONOS install successful",
+                                 onfail="ONOS install failed" )
+
+        main.step( "Checking if ONOS is up yet" )
+        for i in range( 2 ):
+            onosIsupResult = main.TRUE
+            for node in main.nodes:
+                started = main.ONOSbench.isup( node.ip_address )
+                if not started:
+                    main.log.error( node.name + " hasn't started" )
+                onosIsupResult = onosIsupResult and started
+            if onosIsupResult == main.TRUE:
+                break
+        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
+                                 onpass="ONOS startup successful",
+                                 onfail="ONOS startup failed" )
+
+        main.step( "Set up ONOS secure SSH" )
+        secureSshResult = main.TRUE
+        for node in main.nodes:
+            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
+        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
+                                 onpass="Test step PASS",
+                                 onfail="Test step FAIL" )
+
+        main.step( "Starting ONOS CLI sessions" )
+        cliResults = main.TRUE
+        threads = []
+        for i in range( main.numCtrls ):
+            t = main.Thread( target=main.CLIs[i].startOnosCli,
+                             name="startOnosCli-" + str( i ),
+                             args=[main.nodes[i].ip_address] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            cliResults = cliResults and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
+                                 onpass="ONOS cli startup successful",
+                                 onfail="ONOS cli startup failed" )
+
+        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
+
+        main.step( "Activate apps defined in the params file" )
+        # get data from the params
+        apps = main.params.get( 'apps' )
+        if apps:
+            apps = apps.split(',')
+            main.log.warn( apps )
+            activateResult = True
+            for app in apps:
+                main.CLIs[ 0 ].app( app, "Activate" )
+            # TODO: check this worked
+            time.sleep( SLEEP )  # wait for apps to activate
+            for app in apps:
+                state = main.CLIs[ 0 ].appStatus( app )
+                if state == "ACTIVE":
+                    activateResult = activeResult and True
+                else:
+                    main.log.error( "{} is in {} state".format( app, state ) )
+                    activeResult = False
+            utilities.assert_equals( expect=True,
+                                     actual=activateResult,
+                                     onpass="Successfully activated apps",
+                                     onfail="Failed to activate apps" )
+        else:
+            main.log.warn( "No apps were specified to be loaded after startup" )
+
+        main.step( "Set ONOS configurations" )
+        config = main.params.get( 'ONOS_Configuration' )
+        if config:
+            main.log.debug( config )
+            checkResult = main.TRUE
+            for component in config:
+                for setting in config[component]:
+                    value = config[component][setting]
+                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
+                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
+                    checkResult = check and checkResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=checkResult,
+                                     onpass="Successfully set config",
+                                     onfail="Failed to set config" )
+        else:
+            main.log.warn( "No configurations were specified to be changed after startup" )
+
+        main.step( "App Ids check" )
+        appCheck = main.TRUE
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[0].apps() )
+            main.log.warn( main.CLIs[0].appIDs() )
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+
+    def CASE2( self, main ):
+        """
+        Load and test vpls configurations from json configuration file
+        """
+        import os.path
+        from tests.USECASE.VPLS.dependencies import vpls
+
+        pprint = main.ONOSrest1.pprint
+        hosts = int( main.params['vpls']['hosts'] )
+        SLEEP = int( main.params['SLEEP']['netcfg'] )
+
+        main.step( "Discover hosts using pings" )
+        for i in range( 1, hosts + 1 ):
+            src = "h" + str( i )
+            for j in range( 1, hosts + 1 ):
+                if j == i:
+                    continue
+                dst = "h" + str( j )
+            pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
+
+        main.step( "Load VPLS configurations" )
+        # TODO: load from params
+        fileName = main.params['DEPENDENCY']['topology']
+        app = main.params['vpls']['name']
+        # TODO make this a function?
+        main.ONOSbench.handle.sendline( "onos-netcfg $OC1 " + fileName )
+        # Time for netcfg to load data
+        time.sleep( SLEEP )
+        # 'Master' copy of test configuration
+        try:
+            with open( os.path.expanduser( fileName ) ) as dataFile:
+                originalCfg = json.load( dataFile )
+                main.vplsConfig = originalCfg['apps'].get( app ).get( 'vpls' ).get( 'vplsList')
+        except Exception as e:
+            main.log.error( "Error loading config file: {}".format( e ) )
+        if main.vplsConfig:
+            result = True
+        else:
+            result = False
+        utilities.assert_equals( expect=True,
+                                 actual=result,
+                                 onpass="Loaded vpls configuration",
+                                 onfail="Failed to load vpls configuration" )
+
+        main.step( "Check interface configurations" )
+        result = False
+        getPorts = main.ONOSrest1.getNetCfg( subjectClass="ports" )
+        onosCfg = pprint( getPorts )
+        sentCfg = pprint( originalCfg.get( "ports" ) )
+
+        if onosCfg == sentCfg:
+            main.log.info( "ONOS interfaces NetCfg matches what was sent" )
+            result = True
+        else:
+            main.log.error( "ONOS interfaces NetCfg doesn't match what was sent" )
+            main.log.debug( "ONOS config: {}".format( onosCfg ) )
+            main.log.debug( "Sent config: {}".format( sentCfg ) )
+        utilities.assert_equals( expect=True,
+                                 actual=result,
+                                 onpass="Net Cfg added for interfaces",
+                                 onfail="Net Cfg not added for interfaces" )
+
+        # Run a bunch of checks to verify functionality based on configs
+        vpls.verify( main )
+
+    def CASE3( self, main ):
+        """
+        Test VPLS cli commands
+        High level steps:
+            remove interface from a network
+            Clean configs
+            create vpls network
+            add interfaces to a network
+            add encap
+            change encap
+            remove encap
+            list?
+        """
+        from tests.USECASE.VPLS.dependencies import vpls
+        SLEEP = int( main.params['SLEEP']['netcfg'] )
+        pprint = main.ONOSrest1.pprint
+
+        main.step( "Remove an interface from a vpls network" )
+        main.CLIs[0].vplsRemIface( 'VPLS1', 'h1' )
+        time.sleep( SLEEP )
+        #update master config json
+        for network in main.vplsConfig:
+            if network.get( 'name' ) == 'VPLS1':
+                ifaces = network.get( 'interfaces' )
+                ifaces.remove('h1')
+        vpls.verify( main )
+
+        main.step( "Clean all vpls configurations" )
+        main.CLIs[0].vplsClean()
+        time.sleep( SLEEP )
+        main.vplsConfig = []
+        vpls.verify( main )
+
+        main.step( "Create a new vpls network" )
+        name = "Network1"
+        main.CLIs[0].vplsCreate( name )
+        time.sleep( SLEEP )
+        network1 = { 'name': name, 'interfaces': [], 'encapsulation': 'NONE' }
+        main.vplsConfig.append( network1 )
+        vpls.verify( main )
+
+        main.step( "Add interfaces to the network" )
+        main.CLIs[0].vplsAddIface( name, "h1" )
+        main.CLIs[0].vplsAddIface( name, "h5" )
+        main.CLIs[0].vplsAddIface( name, "h4" )
+        time.sleep( SLEEP )
+        for network in main.vplsConfig:
+            if network.get( 'name' ) == name:
+                ifaces = network.get( 'interfaces' )
+                ifaces.append( 'h1' )
+                ifaces.append( 'h4' )
+                ifaces.append( 'h5' )
+                network[ 'interfaces' ] = ifaces
+        vpls.verify( main )
+
+        main.step( "Add MPLS encapsulation to a vpls network" )
+        encapType = "MPLS"
+        main.CLIs[0].vplsSetEncap( name, encapType )
+        for network in main.vplsConfig:
+            if network.get( 'name' ) == name:
+                network['encapsulation'] = encapType
+        time.sleep( SLEEP )
+        vpls.verify( main )
+
+        main.step( "Change an encapsulation type" )
+        encapType = "VLAN"
+        main.CLIs[0].vplsSetEncap( name, encapType )
+        for network in main.vplsConfig:
+            if network.get( 'name' ) == name:
+                network['encapsulation'] = encapType
+        time.sleep( SLEEP )
+        vpls.verify( main )
+
+        main.step( "Remove encapsulation" )
+        encapType = "NONE"
+        main.CLIs[0].vplsSetEncap( name, encapType )
+        for network in main.vplsConfig:
+            if network.get( 'name' ) == name:
+                network['encapsulation'] = encapType
+        time.sleep( SLEEP )
+        vpls.verify( main )
+
+        main.step( "Clean all vpls configurations" )
+        main.CLIs[0].vplsClean()
+        time.sleep( SLEEP )
+        main.vplsConfig = []
+        vpls.verify( main )
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
new file mode 100755
index 0000000..e9a1f8e
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
@@ -0,0 +1,115 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <nodes>1</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <ONOS1>
+            <host>OC1</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>OC2</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>OC3</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest1>
+
+        <ONOSrest2>
+            <host>OC2</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest2>
+
+        <ONOSrest3>
+            <host>OC3</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest3>
+
+
+        <Mininet1>
+            <host>OCN</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS>
+                <home>~/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py b/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py b/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/dependencies/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/__init__.py b/TestON/tests/USECASE/VPLS/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/dependencies/__init__.py b/TestON/tests/USECASE/VPLS/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/dependencies/__init__.py
diff --git a/TestON/tests/USECASE/VPLS/dependencies/vpls.py b/TestON/tests/USECASE/VPLS/dependencies/vpls.py
new file mode 100644
index 0000000..8dfdd46
--- /dev/null
+++ b/TestON/tests/USECASE/VPLS/dependencies/vpls.py
@@ -0,0 +1,144 @@
+"""
+Functions for the vpls tests
+"""
+import time
+import json
+
+def sanitizeConfig( config ):
+    """
+    Take a python json object for vpls config and normalize it.
+    Things it does:
+        Converts all strings to the same format
+        Make sure each network has an encapsulation key:value
+        Makes sure encapsulation type is all uppercase
+        Make sure an empty list of interfaces is formated consistently
+        Sorts the list of interfaces
+    """
+    # Convert to same string formats
+    config = json.loads( json.dumps( config ) )
+    for network in config:
+        encap = network.get( 'encapsulation', None )
+        if encap is None:
+            encap = "NONE"
+        network[ 'encapsulation' ] = encap.upper()
+        ifaces = network.get( 'interfaces' )
+        if ifaces == ['']:
+            ifaces = []
+        else:
+            ifaces = sorted( ifaces )
+            network['interfaces'] = ifaces
+    return config
+
+def verify( main ):
+    """
+    Runs some tests to verify the vpls configurations.
+        - Compare sent vpls network configuration to what is stored in each:
+            - ONOS network configuration
+            - ONOS VPLS application configuration
+        - Ping between each pair of hosts to check connectivity
+
+    NOTE: This requires the expected/sent network config json for the vpls
+          application be stored in main.vplsConfig
+    """
+    # Variables
+    app = main.params['vpls']['name']
+    pprint = main.ONOSrest1.pprint
+    SLEEP = int( main.params['SLEEP']['netcfg'] )
+
+    main.step( "Check network configurations for vpls application" )
+    clusterResult = True
+    for node in main.RESTs:
+        result = False
+        getVPLS = node.getNetCfg( subjectClass="apps",
+                                  subjectKey=app )
+        onosCfg = json.loads( getVPLS ).get( 'vpls' ).get( 'vplsList' )
+        onosCfg = pprint( sanitizeConfig( onosCfg ) )
+        sentCfg = pprint( sanitizeConfig( main.vplsConfig ) )
+        result = onosCfg == sentCfg
+        if result:
+            main.log.info( "ONOS NetCfg matches what was sent" )
+        else:
+            clusterResult = False
+            main.log.error( "ONOS NetCfg doesn't match what was sent" )
+            main.log.debug( "ONOS config: {}".format( onosCfg ) )
+            main.log.debug( "Sent config: {}".format( sentCfg ) )
+    utilities.assert_equals( expect=True,
+                             actual=clusterResult,
+                             onpass="Net Cfg added for vpls",
+                             onfail="Net Cfg not added for vpls" )
+
+    main.step( "Check vpls app configurations" )
+    clusterResult = True
+    for node in main.CLIs:
+        result = False
+        #TODO Read from vpls show and match to pushed json
+        vpls = node.parseVplsShow()
+        parsedVpls = pprint( sanitizeConfig( vpls ) )
+        sentVpls = pprint( sanitizeConfig( main.vplsConfig ) )
+        result = parsedVpls == sentVpls
+        if result:
+            main.log.info( "VPLS config matches sent NetCfg" )
+        else:
+            clusterResult = False
+            main.log.error( "VPLS config doesn't match sent NetCfg" )
+            main.log.debug( "ONOS config: {}".format( parsedVpls ) )
+            main.log.debug( "Sent config: {}".format( sentVpls ) )
+    utilities.assert_equals( expect=True,
+                             actual=clusterResult,
+                             onpass="VPLS successfully configured",
+                             onfail="VPLS not configured correctly" )
+
+    # FIXME This doesn't work, some will be withdrawn if interfaces are removed
+    # TODO: if encapsulation is set, look for that
+    # TODO: can we look at the intent keys?
+    """
+    main.step( "Check intent states" )
+    # Print the intent states
+    intents = main.CLIs[0].intents()
+    count = 0
+    while count <= 5:
+        installedCheck = True
+        try:
+            for intent in json.loads( intents ):
+                state = intent.get( 'state', None )
+                if "INSTALLED" not in state:
+                    installedCheck = False
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing intents" )
+        if installedCheck:
+            break
+        count += 1
+    utilities.assert_equals( expect=True,
+                             actual=installedCheck ,
+                             onpass="All Intents in installed state",
+                             onfail="Not all Intents in installed state" )
+    """
+
+    main.step( "Check connectivity" )
+    connectivityCheck = True
+    hosts = int( main.params['vpls']['hosts'] )
+    networks = []
+    for network in main.vplsConfig:
+        nodes = network.get( 'interfaces', None )
+        if nodes:
+            networks.append( nodes )
+    for i in range( 1, hosts + 1 ):
+        src = "h" + str( i )
+        for j in range( 1, hosts + 1 ):
+            if j == i:
+                continue
+            dst = "h" + str( j )
+            pingResult = main.Mininet1.pingHost( SRC=src, TARGET=dst )
+            expected = main.FALSE
+            for network in networks:
+                if src in network and dst in network:
+                    expected = main.TRUE
+                    break
+            if pingResult != expected:
+                connectivityCheck = False
+                main.log.error( "%s <-> %s: %s; Expected: %s" %
+                               ( src, dst, pingResult, expected ) )
+    utilities.assert_equals( expect=True,
+                             actual=connectivityCheck,
+                             onpass="Connectivity is as expected",
+                             onfail="Connectivity is not as expected" )