[ONOS-7736] Add vlan tagged host movement tests

Change-Id: I5948a8536286bf1d31ce2f8f1a6f58f5329edbe0
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 5bf06fb..af69d68 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -912,233 +912,6 @@
         else:
             return main.TRUE
 
-    def moveHost( self, host, oldSw, newSw, macAddr=None, prefixLen=24 ):
-        """
-           Moves an IPv4 host from one switch to another on the fly
-           If macAddr is specified, change MAC address of the host interface
-           to specified MAC address.
-           Note: The intf between host and oldSw when detached
-                using detach(), will still show up in the 'net'
-                cmd, because switch.detach() doesn't affect switch.intfs[]
-                ( which is correct behavior since the interfaces
-                haven't moved ).
-        """
-        if self.handle:
-            try:
-                # Bring link between oldSw-host down
-                cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
-                      "'," + "'down')"
-                print "cmd1= ", cmd
-                response = self.execute( cmd=cmd,
-                                         prompt="mininet>",
-                                         timeout=10 )
-
-                # Determine hostintf and Oldswitchintf
-                cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
-                      ")[0]"
-                print "cmd2= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Determine ip and mac address of the host-oldSw interface
-                cmd = "px ipaddr = hintf.IP()"
-                print "cmd3= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                if macAddr is None:
-                    cmd = "px macaddr = hintf.MAC()"
-                else:
-                    cmd = 'px macaddr = "%s"' % macAddr
-                print "cmd3= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Detach interface between oldSw-host
-                cmd = "px " + oldSw + ".detach( sintf )"
-                print "cmd4= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Add link between host-newSw
-                cmd = "py net.addLink(" + host + "," + newSw + ")"
-                print "cmd5= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Determine hostintf and Newswitchintf
-                cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
-                      ")[-1]"
-                print "cmd6= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Attach interface between newSw-host
-                cmd = "px " + newSw + ".attach( sintf )"
-                print "cmd3= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Set ipaddress of the host-newSw interface
-                cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf, " \
-                                     "prefixLen = %s )" % str( prefixLen )
-                print "cmd7 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Set macaddress of the host-newSw interface
-                cmd = "px " + host + ".setMAC( mac = macaddr, intf = hintf)"
-                print "cmd8 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                cmd = "net"
-                print "cmd9 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-                print "output = ", self.handle.before
-
-                # Determine ipaddress of the host-newSw interface
-                cmd = host + " ifconfig"
-                print "cmd10= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-                print "ifconfig o/p = ", self.handle.before
-
-                return main.TRUE
-
-            except pexpect.TIMEOUT:
-                main.log.error( self.name + ": TIMEOUT exception found" )
-                main.log.error( self.name + ":     " + self.handle.before )
-                main.cleanAndExit()
-            except pexpect.EOF:
-                main.log.error( self.name + ": EOF exception found" )
-                main.log.error( self.name + ":     " + self.handle.before )
-                return main.FALSE
-            except Exception:
-                main.log.exception( self.name + ": Uncaught exception!" )
-                return main.FALSE
-
-    def moveHostv6( self, host, oldSw, newSw, macAddr=None, prefixLen=64 ):
-        """
-           Moves an IPv6 host from one switch to another on the fly
-           If macAddr is specified, change MAC address of the host interface
-           to specified MAC address.
-           Note: The intf between host and oldSw when detached
-                using detach(), will still show up in the 'net'
-                cmd, because switch.detach() doesn't affect switch.intfs[]
-                ( which is correct behavior since the interfaces
-                haven't moved ).
-        """
-        if self.handle:
-            try:
-                IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/" + str( prefixLen )
-                # Bring link between oldSw-host down
-                cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host +\
-                      "'," + "'down')"
-                print "cmd1= ", cmd
-                response = self.execute( cmd=cmd,
-                                         prompt="mininet>",
-                                         timeout=10 )
-
-                # Determine hostintf and Oldswitchintf
-                cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
-                      ")[0]"
-                print "cmd2= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Determine ip and mac address of the host-oldSw interface
-                cmd = 'px ipaddr = "{}"'.format( IP )
-                print "cmd3= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                if macAddr is None:
-                    cmd = "px macaddr = hintf.MAC()"
-                else:
-                    cmd = 'px macaddr = "%s"' % macAddr
-                print "cmd3= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Detach interface between oldSw-host
-                cmd = "px " + oldSw + ".detach(sintf)"
-                print "cmd4= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Add link between host-newSw
-                cmd = "py net.addLink(" + host + "," + newSw + ")"
-                print "cmd5= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Determine hostintf and Newswitchintf
-                cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
-                      ")[-1]"
-                print "cmd6= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Attach interface between newSw-host
-                cmd = "px " + newSw + ".attach(sintf)"
-                print "cmd6= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Set macaddress of the host-newSw interface
-                cmd = "px " + host + ".setMAC(mac = macaddr, intf = hintf)"
-                print "cmd7 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                # Set ipaddress of the host-newSw interface
-                cmd = "px " + host + ".setIP( ip = ipaddr, intf = hintf, " \
-                                     "prefixLen = %s )" % str( prefixLen )
-                print "cmd8 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                cmd = host + " ifconfig"
-                print "cmd9 =", cmd
-                response = self.execute( cmd = cmd, prompt="mininet>", timeout=10 )
-                print response
-                pattern = "-eth([\w])"
-                ipAddressSearch = re.search( pattern, response )
-                print ipAddressSearch.group( 1 )
-                intf = host + "-eth" + str( ipAddressSearch.group( 1 ) )
-                cmd = host + " ip -6 addr add %s dev %s" % ( IP, intf )
-                print "cmd10 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-
-                cmd = "net"
-                print "cmd11 = ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-                print "output = ", self.handle.before
-
-                # Determine ipaddress of the host-newSw interface
-                cmd = host + " ifconfig"
-                print "cmd12= ", cmd
-                self.handle.sendline( cmd )
-                self.handle.expect( "mininet>" )
-                print "ifconfig o/p = ", self.handle.before
-
-                return main.TRUE
-            except pexpect.TIMEOUT:
-                main.log.error( self.name + ": TIMEOUT exception found" )
-                main.log.error( self.name + ":     " + self.handle.before )
-                main.cleanAndExit()
-            except pexpect.EOF:
-                main.log.error( self.name + ": EOF exception found" )
-                main.log.error( self.name + ":     " + self.handle.before )
-                return main.FALSE
-            except Exception:
-                main.log.exception( self.name + ": Uncaught exception!" )
-                return main.FALSE
-
     def changeIP( self, host, intf, newIP, newNetmask ):
         """
            Changes the ip address of a host on the fly
@@ -4053,80 +3826,73 @@
             main.log.warn( "Interface status should be up or down!" )
             return main.FALSE
 
-    def moveDualHomedHost( self, host, oldSw, oldPairSw, newSw, newPairSw,
-                           macAddr=None, prefixLen=None, bondedName='bond1' ):
+    def moveHost( self, host, oldSw, newSw, macAddr=None, prefixLen=64, ipv6=False, intfSuffix="eth1", vlan=None ):
         """
-        Moves a dual-homed IPv4 host from one switch-pair to another pair on the fly
-        If macAddr is specified, change MAC address of the bonded host interface
-        to specified MAC address.
-        Assumes that the host has two interfaces (eth0 and eth1) originally.
+           Moves a host from one switch to another on the fly
+           Optional:
+               macAddr: when specified, change MAC address of the host interface to specified MAC address.
+               prefixLen: length of the host IP prefix
+               ipv6: move an IPv6 host if True
+               intfSuffix: suffix of the new interface after host movement
+               vlan: vlan ID of the host. Use None for non-vlan host
+           Note: The intf between host and oldSw when detached
+                using detach(), will still show up in the 'net'
+                cmd, because switch.detach() doesn't affect switch.intfs[]
+                ( which is correct behavior since the interfaces
+                haven't moved ).
         """
-
-        bond1 = "%s-%s" % ( host, bondedName )
-        newIntf = host + '-eth2'
-        newIntfPair = host + '-eth3'
-        commands = [
-            # Bring link between oldSw-host down
-            "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," + "'down')",
-            # Bring link between oldPairSw-host down
-            "py net.configLinkStatus('" + oldPairSw + "'," + "'" + host + "'," + "'down')",
-            # Determine hostintf and Oldswitchintf
-            "px hintf,sintf = " + host + ".connectionsTo(" + oldSw + ")[0]",
-            # Determine ip and mac address of the host-oldSw interface
-            "px ipaddr = hintf.IP()",
-            "px macaddr = hintf.MAC()" if macAddr is None else 'px macaddr = "%s"' % macAddr,
-            # Detach interface between oldSw-host
-            "px " + oldSw + ".detach( sintf )",
-            # Determine hostintf and Oldpairswitchintf
-            "px sintfpair,hintfpair = " + oldPairSw + ".connectionsTo(" + host + ")[0]",
-            # Detach interface between oldPairSw-host
-            "px " + oldPairSw + ".detach( sintfpair )",
-            # Add link between host-newSw
-            "py net.addLink(" + host + "," + newSw + ", 2)",
-            # Add link between host-newPairSw
-            "py net.addLink(" + host + "," + newPairSw + ")",
-            # Determine hostintf and Newswitchintf
-            "px hintf,sintf = " + host + ".connectionsTo(" + newSw + ")[-1]",
-            # Determine hostintf and NewPairswitchintf
-            "px hintfpair,sintfpair = " + host + ".connectionsTo(" + newPairSw + ")[-1]",
-            # Attach interface between newSw-host
-            "px " + newSw + ".attach( sintf )",
-            # Attach interface between newPairSw-host
-            "px " + newPairSw + ".attach( sintfpair )",
-            # Bond two interfaces
-            host + ' ip link add %s type bond' % bond1,
-            host + ' ip link set %s down' % newIntf,
-            host + ' ip link set %s down' % newIntfPair,
-            host + ' ip link set %s master %s' % ( newIntf, bond1 ),
-            host + ' ip link set %s master %s' % ( newIntfPair, bond1 ),
-            host + ' ip addr flush dev %s' % newIntf,
-            host + ' ip addr flush dev %s' % newIntfPair,
-            host + ' ip link set %s up' % bond1,
-            "px lowestIntf = min( [ hintf, hintfpair ] )",
-            "px highestIntf = max( [ hintf, hintfpair ] )",
-            "px lowestIntf.name = '" + bond1 + "'",
-            "px " + host + ".nameToIntf['" + bond1 + "'] = lowestIntf",
-            "px del " + host + ".intfs[ " + host + ".ports[ highestIntf ] ]",
-            "px del " + host + ".ports[ highestIntf ]",
-            # Set ipaddress of the host-newSw interface
-            "px " + host + ".setIP( ip = ipaddr, intf = lowestIntf " +
-            ( ", prefixLen = %s )" % str( prefixLen ) if prefixLen is not None else " )" ),
-            # Set macaddress of the host-newSw interface
-            "px " + host + ".setMAC( mac = macaddr, intf = lowestIntf)",
-            "net",
-            # Determine ipaddress of the bonded host interface
-            host + " ifconfig",
-        ]
-
         if self.handle:
             try:
+                newIntf = "%s-%s" % ( host, intfSuffix )
+                commands = [
+                    # Bring link between oldSw-host down
+                    "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," + "'down')",
+                    # Determine hostintf and Oldswitchintf
+                    "px hintf,sintf = " + host + ".connectionsTo(" + oldSw + ")[0]",
+                ]
+                # Determine ip address of the host-oldSw interface
+                IP = str( self.getIPAddress( host, proto='IPV6' if ipv6 else 'IPV4' ) ) + "/" + str( prefixLen )
+                commands.append( 'px ipaddr = "{}"'.format( IP ) )
+                commands += [
+                    # Determine mac address of the host-oldSw interface
+                    "px macaddr = hintf.MAC()" if macAddr is None else 'px macaddr = "%s"' % macAddr,
+                    # Detach interface between oldSw-host
+                    "px " + oldSw + ".detach( sintf )",
+                    # Add link between host-newSw
+                    "py net.addLink(" + host + "," + newSw + ")",
+                    # Determine hostintf and Newswitchintf
+                    "px hintf,sintf = " + host + ".connectionsTo(" + newSw + ")[-1]",
+                    # Attach interface between newSw-host
+                    "px " + newSw + ".attach( sintf )",
+                ]
+                if vlan:
+                    vlanIntf = "%s.%s" % ( newIntf, vlan )
+                    commands += [
+                        host + " ip link add link %s name %s type vlan id %s" % ( newIntf, vlanIntf, vlan ),
+                        host + " ip link set up %s" % vlanIntf,
+                        "px hintf.name = '" + vlanIntf + "'",
+                        "px " + host + ".nameToIntf[ '" + vlanIntf + "' ] = hintf"
+                    ]
+                    newIntf = vlanIntf
+                commands += [
+                    # Set mac address of the host-newSw interface
+                    "px " + host + ".setMAC( mac = macaddr, intf = hintf )",
+                    # Set IP address of the host-newSw interface
+                    "px " + host + ".setIP( ip = ipaddr, intf = hintf " +
+                    ( ", prefixLen = %s )" % str( prefixLen ) if prefixLen is not None else " )" )
+                ]
+                if ipv6:
+                    commands.append( host + " ip -6 addr add %s dev %s" % ( IP, newIntf ) )
+                commands += [
+                    "net",
+                    host + " ifconfig"
+                ]
                 for cmd in commands:
                     print "cmd= ", cmd
                     self.handle.sendline( cmd )
                     self.handle.expect( "mininet>" )
                     main.log.info( "====> %s ", self.handle.before )
                 return main.TRUE
-
             except pexpect.TIMEOUT:
                 main.log.error( self.name + ": TIMEOUT exception found" )
                 main.log.error( self.name + ":     " + self.handle.before )
@@ -4139,21 +3905,25 @@
                 main.log.exception( self.name + ": Uncaught exception!" )
                 return main.FALSE
 
-    def moveDualHomedHostv6( self, host, oldSw, oldPairSw, newSw, newPairSw,
-                             macAddr=None, prefixLen=None, bondedName='bond1' ):
+    def moveDualHomedHost( self, host, oldSw, oldPairSw, newSw, newPairSw,
+                           macAddr=None, prefixLen=None, ipv6=False,
+                           intfSuffix1='eth2', intfSuffix2='eth3', bondSuffix='bond1', vlan=None ):
         """
-        Moves a dual-homed IPv6 host from one switch-pair to another pair on the fly
-        If macAddr is specified, change MAC address of the bonded host interface
-        to specified MAC address.
-        Assumes that the host has two interfaces (eth0 and eth1) originally.
+           Moves a dual-homed host from one switch-pair to another pair on the fly
+           Optional:
+               macAddr: when specified, change MAC address of the host interface to specified MAC address.
+               prefixLen: length of the host IP prefix
+               ipv6: move an IPv6 host if True
+               intfSuffix1: suffix of the first new interface
+               intfSuffix2: suffix of the second new interface
+               bondSuffix: suffix of the new bond interface
+               vlan: vlan ID of the host. Use None for non-vlan host
         """
-
         if self.handle:
             try:
-                IP = str( self.getIPAddress( host, proto='IPV6' ) ) + "/" + str( prefixLen )
-                bond1 = "%s-%s" % ( host, bondedName )
-                newIntf = host + '-eth2'
-                newIntfPair = host + '-eth3'
+                bondIntf = "%s-%s" % ( host, bondSuffix )
+                newIntf = "%s-%s" % ( host, intfSuffix1 )
+                newIntfPair = "%s-%s" % ( host, intfSuffix2 )
                 commands = [
                     # Bring link between oldSw-host down
                     "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," + "'down')",
@@ -4161,8 +3931,12 @@
                     "py net.configLinkStatus('" + oldPairSw + "'," + "'" + host + "'," + "'down')",
                     # Determine hostintf and Oldswitchintf
                     "px hintf,sintf = " + host + ".connectionsTo(" + oldSw + ")[0]",
-                    # Determine ip and mac address of the host-oldSw interface
-                    'px ipaddr = "{}"'.format( IP ),
+                ]
+                # Determine ip address of the host-oldSw interface
+                IP = str( self.getIPAddress( host, proto='IPV6' if ipv6 else 'IPV4' ) ) + "/" + str( prefixLen )
+                commands.append( 'px ipaddr = "{}"'.format( IP ) )
+                commands += [
+                    # Determine mac address of the host-oldSw interface
                     "px macaddr = hintf.MAC()" if macAddr is None else 'px macaddr = "%s"' % macAddr,
                     # Detach interface between oldSw-host
                     "px " + oldSw + ".detach( sintf )",
@@ -4183,38 +3957,49 @@
                     # Attach interface between newPairSw-host
                     "px " + newPairSw + ".attach( sintfpair )",
                     # Bond two interfaces
-                    host + ' ip link add %s type bond' % bond1,
+                    host + ' ip link add %s type bond' % bondIntf,
                     host + ' ip link set %s down' % newIntf,
                     host + ' ip link set %s down' % newIntfPair,
-                    host + ' ip link set %s master %s' % ( newIntf, bond1 ),
-                    host + ' ip link set %s master %s' % ( newIntfPair, bond1 ),
+                    host + ' ip link set %s master %s' % ( newIntf, bondIntf ),
+                    host + ' ip link set %s master %s' % ( newIntfPair, bondIntf ),
                     host + ' ip addr flush dev %s' % newIntf,
                     host + ' ip addr flush dev %s' % newIntfPair,
-                    host + ' ip link set %s up' % bond1,
+                    host + ' ip link set %s up' % bondIntf,
                     "px lowestIntf = min( [ hintf, hintfpair ] )",
                     "px highestIntf = max( [ hintf, hintfpair ] )",
-                    "px lowestIntf.name = '" + bond1 + "'",
-                    "px " + host + ".nameToIntf['" + bond1 + "'] = lowestIntf",
+                    "px lowestIntf.name = '" + bondIntf + "'",
+                    "px " + host + ".nameToIntf['" + bondIntf + "'] = lowestIntf",
                     "px del " + host + ".intfs[ " + host + ".ports[ highestIntf ] ]",
                     "px del " + host + ".ports[ highestIntf ]",
+                ]
+                if vlan:
+                    vlanIntf = "%s.%s" % ( bondIntf, vlan )
+                    commands += [
+                        host + " ip link add link %s name %s type vlan id %s" % ( bondIntf, vlanIntf, vlan ),
+                        host + " ip link set up %s" % vlanIntf,
+                        "px lowestIntf.name = '" + vlanIntf + "'",
+                        "px " + host + ".nameToIntf[ '" + vlanIntf + "' ] = lowestIntf",
+                    ]
+                    bondIntf = vlanIntf
+                commands += [
+                    # Set macaddress of the host-newSw interface
+                    "px " + host + ".setMAC( mac = macaddr, intf = lowestIntf)",
                     # Set ipaddress of the host-newSw interface
                     "px " + host + ".setIP( ip = ipaddr, intf = lowestIntf " +
                     ( ", prefixLen = %s )" % str( prefixLen ) if prefixLen is not None else " )" ),
-                    # Set macaddress of the host-newSw interface
-                    "px " + host + ".setMAC( mac = macaddr, intf = lowestIntf)",
-                    host + " ip -6 addr add %s dev %s" % ( IP, bond1 ),
-                    "net",
-                    # Determine ipaddress of the bonded host interface
-                    host + " ifconfig",
                 ]
-
+                if ipv6:
+                    commands.append( host + " ip -6 addr add %s dev %s" % ( IP, bondIntf ) )
+                commands += [
+                    "net",
+                    host + " ifconfig"
+                ]
                 for cmd in commands:
                     print "cmd= ", cmd
                     self.handle.sendline( cmd )
                     self.handle.expect( "mininet>" )
                     main.log.info( "====> %s ", self.handle.before )
                 return main.TRUE
-
             except pexpect.TIMEOUT:
                 main.log.error( self.name + ": TIMEOUT exception found" )
                 main.log.error( self.name + ":     " + self.handle.before )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
index ca1ff80..150d7fd 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
@@ -1306,11 +1306,13 @@
         verify( main )
 
         h1v6cfg = '{"of:0000000000000001/8" : { "interfaces" : [ { "ips" : [ "1000::3ff/120" ], "vlan-untagged": 21 } ] } }'
-        lib.moveHost( main, "h1v6", "leaf1", "leaf1", "1000::3fe", prefixLen=128, cfg=h1v6cfg, ipv6=True )
+        lib.moveHost( main, "h1v6", "leaf1", "leaf1", "1000::3ff", prefixLen=128, cfg=h1v6cfg, ipv6=True )
         hostLocations = { "h1v6": "of:0000000000000001/8" }
         lib.verifyHostLocations( main, hostLocations )
         verify( main )
 
+        # FIXME: We don't have any tagged hosts on DAAS-1
+
         h13v4cfg = '{"of:0000000000000006/7" : { "interfaces" : [ { "ips" : [ "10.5.20.254/24" ], "vlan-untagged": 20 } ] } }'
         lib.moveHost( main, "h13v4", "leaf6", "leaf6", "10.5.20.254", prefixLen=24, cfg=h13v4cfg )
         hostLocations = { "h13v4": "of:0000000000000006/7" }
@@ -1318,12 +1320,26 @@
         verify( main )
 
         h13v6cfg = '{"of:0000000000000006/8" : { "interfaces" : [ { "ips" : [ "1012::3ff/120" ], "vlan-untagged": 26 } ] } }'
-        lib.moveHost( main, "h13v6", "leaf6", "leaf6", "1012::3fe", prefixLen=128, cfg=h13v6cfg, ipv6=True )
+        lib.moveHost( main, "h13v6", "leaf6", "leaf6", "1012::3ff", prefixLen=128, cfg=h13v6cfg, ipv6=True )
         hostLocations = { "h13v6": "of:0000000000000006/8" }
         lib.verifyHostLocations( main, hostLocations )
         verify( main )
 
-        # TODO: test vlan tagged hosts
+        h12v4cfg = '{"of:0000000000000006/9" : { "interfaces" : [ { "ips" : [ "10.5.10.254/24" ], "vlan-tagged": [80] } ] } }'
+        lib.moveHost( main, "h12v4", "leaf6", "leaf6", "10.5.10.254", prefixLen=24, cfg=h12v4cfg, vlan=80 )
+        hostLocations = { "h12v4": "of:0000000000000006/9" }
+        lib.verifyHostLocations( main, hostLocations )
+        verify( main )
+
+        # FIXME: Due to CORD-3079, we are not able to test movement of tagged IPv6 hosts at the moment
+        '''
+        h12v6cfg = '{"of:0000000000000006/10" : { "interfaces" : [ { "ips" : [ "1011::3ff/120" ], "vlan-tagged": [127] } ] } }'
+        lib.moveHost( main, "h12v6", "leaf6", "leaf6", "1011::3ff", prefixLen=128, cfg=h12v6cfg, ipv6=True, vlan=127 )
+        hostLocations = { "h12v6": "of:0000000000000006/10" }
+        lib.verifyHostLocations( main, hostLocations )
+        verify( main )
+        '''
+
         lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
 
     def CASE652( self, main ):
@@ -1355,8 +1371,14 @@
         lib.verifyHostLocations( main, hostLocations )
         verify( main )
 
+        h5v4cfg = '''{"of:0000000000000002/14" : { "interfaces" : [ { "ips" : [ "10.2.20.254/24" ], "vlan-tagged": [30] } ] },
+                      "of:0000000000000003/16" : { "interfaces" : [ { "ips" : [ "10.2.20.254/24" ], "vlan-tagged": [30] } ] } }'''
+        lib.moveDualHomedHost( main, "h5v4", "leaf2", "leaf3", "leaf2", "leaf3", "10.2.20.254", prefixLen=24, cfg=h5v4cfg, vlan=30 )
+        hostLocations = { "h5v4": [ "of:0000000000000002/14", "of:0000000000000003/16" ] }
+        lib.verifyHostLocations( main, hostLocations )
+        verify( main )
+
         # TODO: test static routes that point to the moved host
-        # TODO: test vlan tagged hosts
         lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
 
     def CASE653( self, main ):
@@ -1388,6 +1410,12 @@
         lib.verifyHostLocations( main, hostLocations )
         verify( main )
 
+        h5v4cfg = '''{"of:0000000000000002/14" : { "interfaces" : [ { "ips" : [ "10.2.20.254/24" ], "vlan-tagged": [30] } ] },
+                      "of:0000000000000003/16" : { "interfaces" : [ { "ips" : [ "10.2.20.254/24" ], "vlan-tagged": [30] } ] } }'''
+        lib.moveDualHomedHost( main, "h5v4", "leaf2", "leaf3", "leaf2", "leaf3", "10.2.20.254", macAddr="00:aa:01:00:00:04", prefixLen=24, cfg=h5v4cfg, vlan=30 )
+        hostLocations = { "h5v4": [ "of:0000000000000002/14", "of:0000000000000003/16" ] }
+        lib.verifyHostLocations( main, hostLocations )
+        verify( main )
+
         # TODO: test static routes that point to the moved host
-        # TODO: test vlan tagged hosts
         lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index 1838fc3..8c6e22a 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -1235,7 +1235,7 @@
                                  onfail="Location verification failed" )
 
     @staticmethod
-    def moveHost( main, hostName, srcSw, dstSw, gw, macAddr=None, prefixLen=None, cfg='', ipv6=False ):
+    def moveHost( main, hostName, srcSw, dstSw, gw, macAddr=None, prefixLen=None, cfg='', ipv6=False, vlan=None ):
         """
         Move specified host from srcSw to dstSw.
         If srcSw and dstSw are same, the host will be moved from current port to
@@ -1250,16 +1250,15 @@
             prefixLen: prefix length
             cfg: port configuration as JSON string
             ipv6: Use True to move IPv6 host
+            vlan: vlan number of the host
         """
         if not hasattr( main, 'Mininet1' ):
             main.log.warn( "moveHost is supposed to be used only in Mininet." )
             return
 
-        main.step( "Moving host {} from {} to {}".format( hostName, srcSw, dstSw ) )
-        if ipv6:
-            main.Mininet1.moveHostv6( hostName, srcSw, dstSw, macAddr, prefixLen )
-        else:
-            main.Mininet1.moveHost( hostName, srcSw, dstSw, macAddr, prefixLen )
+        main.step( "Moving {} host {} from {} to {}".format( 'tagged' if vlan else 'untagged', hostName, srcSw, dstSw ) )
+        main.Mininet1.moveHost( hostName, srcSw, dstSw, macAddr, prefixLen, ipv6, vlan=vlan )
+        if not ipv6:
             main.Mininet1.changeDefaultGateway( hostName, gw )
         if cfg:
             main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),
@@ -1282,7 +1281,7 @@
 
     @staticmethod
     def moveDualHomedHost( main, hostName, srcSw, srcPairSw, dstSw, dstPairSw, gw,
-                           macAddr=None, prefixLen=24, cfg='', ipv6=False ):
+                           macAddr=None, prefixLen=24, cfg='', ipv6=False, vlan=None ):
         """
         Move specified dual-homed host from srcSw-srcPairSw to dstSw-dstPairSw.
         If srcSw-srcPairSw and dstSw-dstPairSw are same, the host will be moved from current port
@@ -1299,20 +1298,17 @@
             prefixLen: prefix length
             cfg: port configurations as JSON string
             ipv6: Use True to move IPv6 host
+            vlan: vlan number of the host
         """
-        # TODO: support vlan-tagged hosts.
         if not hasattr( main, 'Mininet1' ):
             main.log.warn( "moveDualHomedHost is supposed to be used only in Mininet." )
             return
 
-        main.step( "Moving host {} from {} and {} to {} and {}".format( hostName, srcSw, srcPairSw,
-                                                                        dstSw, dstPairSw ) )
-        if ipv6:
-            main.Mininet1.moveDualHomedHostv6( hostName, srcSw, srcPairSw, dstSw, dstPairSw,
-                                               macAddr=macAddr, prefixLen=prefixLen )
-        else:
-            main.Mininet1.moveDualHomedHost( hostName, srcSw, srcPairSw, dstSw, dstPairSw,
-                                             macAddr=macAddr, prefixLen=prefixLen )
+        main.step( "Moving {} host {} from {} and {} to {} and {}".format( 'tagged' if vlan else 'untagged', hostName,
+                                                                           srcSw, srcPairSw, dstSw, dstPairSw ) )
+        main.Mininet1.moveDualHomedHost( hostName, srcSw, srcPairSw, dstSw, dstPairSw,
+                                         macAddr=macAddr, prefixLen=prefixLen, ipv6=ipv6, vlan=vlan )
+        if not ipv6:
             main.Mininet1.changeDefaultGateway( hostName, gw )
         if cfg:
             main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),