diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index 6709efd..0ca1ba9 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -35,12 +35,14 @@
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostService;
-import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Sets;
 import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkArgument;
 
 /**
  * Handles host-related events.
@@ -56,120 +58,158 @@
      *
      * @param srManager Segment Routing manager
      */
-    public HostHandler(SegmentRoutingManager srManager) {
+    HostHandler(SegmentRoutingManager srManager) {
         this.srManager = srManager;
         hostService = srManager.hostService;
         flowObjectiveService = srManager.flowObjectiveService;
     }
 
     protected void init(DeviceId devId) {
-        hostService.getHosts().forEach(host -> {
-            DeviceId deviceId = host.location().deviceId();
-            // The host does not attach to this device
-            if (!deviceId.equals(devId)) {
-                return;
-            }
-            processHostAdded(host);
-        });
+        hostService.getHosts().forEach(host ->
+            host.locations().stream()
+                    .filter(location -> location.deviceId().equals(devId))
+                    .forEach(location -> processHostAddedAtLocation(host, location))
+        );
     }
 
-    protected void processHostAddedEvent(HostEvent event) {
+    void processHostAddedEvent(HostEvent event) {
         processHostAdded(event.subject());
     }
 
-    protected void processHostAdded(Host host) {
-        MacAddress mac = host.mac();
-        VlanId vlanId = host.vlan();
-        HostLocation location = host.location();
-        DeviceId deviceId = location.deviceId();
-        PortNumber port = location.port();
-        Set<IpAddress> ips = host.ipAddresses();
-        log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port);
-
-        if (accepted(host)) {
-            processBridgingRule(deviceId, port, mac, vlanId, false);
-            ips.forEach(ip -> {
-                processRoutingRule(deviceId, port, mac, vlanId, ip, false);
-            });
-        }
+    private void processHostAdded(Host host) {
+        host.locations().forEach(location -> processHostAddedAtLocation(host, location));
     }
 
-    protected void processHostRemoveEvent(HostEvent event) {
+    void processHostAddedAtLocation(Host host, HostLocation location) {
+        checkArgument(host.locations().contains(location), "{} is not a location of {}", location, host);
+
+        MacAddress mac = host.mac();
+        VlanId vlanId = host.vlan();
+        Set<HostLocation> locations = host.locations();
+        Set<IpAddress> ips = host.ipAddresses();
+        log.info("Host {}/{} is added at {}", mac, vlanId, locations);
+
+        processBridgingRule(location.deviceId(), location.port(), mac, vlanId, false);
+        ips.forEach(ip ->
+                processRoutingRule(location.deviceId(), location.port(), mac, vlanId, ip, false)
+        );
+    }
+
+    void processHostRemovedEvent(HostEvent event) {
         processHostRemoved(event.subject());
     }
 
-    protected void processHostRemoved(Host host) {
+    private void processHostRemoved(Host host) {
         MacAddress mac = host.mac();
         VlanId vlanId = host.vlan();
-        HostLocation location = host.location();
-        DeviceId deviceId = location.deviceId();
-        PortNumber port = location.port();
+        Set<HostLocation> locations = host.locations();
         Set<IpAddress> ips = host.ipAddresses();
-        log.info("Host {}/{} is removed from {}:{}", mac, vlanId, deviceId, port);
+        log.info("Host {}/{} is removed from {}", mac, vlanId, locations);
 
-        if (accepted(host)) {
-            processBridgingRule(deviceId, port, mac, vlanId, true);
-            ips.forEach(ip -> {
-                processRoutingRule(deviceId, port, mac, vlanId, ip, true);
-            });
-        }
+        locations.forEach(location -> {
+            processBridgingRule(location.deviceId(), location.port(), mac, vlanId, true);
+            ips.forEach(ip ->
+                processRoutingRule(location.deviceId(), location.port(), mac, vlanId, ip, true)
+            );
+        });
     }
 
-    protected void processHostMovedEvent(HostEvent event) {
+    void processHostMovedEvent(HostEvent event) {
         MacAddress mac = event.subject().mac();
         VlanId vlanId = event.subject().vlan();
-        HostLocation prevLocation = event.prevSubject().location();
-        DeviceId prevDeviceId = prevLocation.deviceId();
-        PortNumber prevPort = prevLocation.port();
+        Set<HostLocation> prevLocations = event.prevSubject().locations();
         Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
-        HostLocation newLocation = event.subject().location();
-        DeviceId newDeviceId = newLocation.deviceId();
-        PortNumber newPort = newLocation.port();
+        Set<HostLocation> newLocations = event.subject().locations();
         Set<IpAddress> newIps = event.subject().ipAddresses();
-        log.info("Host {}/{} is moved from {}:{} to {}:{}",
-                mac, vlanId, prevDeviceId, prevPort, newDeviceId, newPort);
+        log.info("Host {}/{} is moved from {} to {}", mac, vlanId, prevLocations, newLocations);
 
-        if (accepted(event.prevSubject())) {
-            processBridgingRule(prevDeviceId, prevPort, mac, vlanId, true);
-            prevIps.forEach(ip -> {
-                processRoutingRule(prevDeviceId, prevPort, mac, vlanId, ip, true);
-            });
-        }
+        Set<DeviceId> newDeviceIds = newLocations.stream().map(HostLocation::deviceId)
+                .collect(Collectors.toSet());
 
-        if (accepted(event.subject())) {
-            processBridgingRule(newDeviceId, newPort, mac, vlanId, false);
-            newIps.forEach(ip -> {
-                processRoutingRule(newDeviceId, newPort, mac, vlanId, ip, false);
+        // For each old location
+        Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
+            // TODO Switch to backup link when pair device is configured
+
+            // Remove bridging rule and routing rules for unchanged IPs if the host moves from a switch to another.
+            // Otherwise, do not remove and let the adding part update the old flow
+            if (!newDeviceIds.contains(prevLocation.deviceId())) {
+                processBridgingRule(prevLocation.deviceId(), prevLocation.port(), mac, vlanId, true);
+                Sets.intersection(prevIps, newIps).forEach(ip ->
+                        processRoutingRule(prevLocation.deviceId(), prevLocation.port(), mac, vlanId,
+                                ip, true)
+                );
+            }
+
+            // Remove bridging rules if new interface vlan is different from old interface vlan
+            // Otherwise, do not remove and let the adding part update the old flow
+            if (newLocations.stream().noneMatch(newLocation -> {
+                VlanId oldAssignedVlan = srManager.getInternalVlanId(prevLocation);
+                VlanId newAssignedVlan = srManager.getInternalVlanId(newLocation);
+                // Host is tagged and the new location has the host vlan in vlan-tagged
+                return srManager.getTaggedVlanId(newLocation).contains(vlanId) ||
+                        (oldAssignedVlan != null && newAssignedVlan != null &&
+                        // Host is untagged and the new location has the same assigned vlan
+                        oldAssignedVlan.equals(newAssignedVlan));
+            })) {
+                processBridgingRule(prevLocation.deviceId(), prevLocation.port(), mac, vlanId, true);
+            }
+
+            // Remove routing rules for unchanged IPs if none of the subnet of new location contains
+            // the IP. Otherwise, do not remove and let the adding part update the old flow
+            Sets.intersection(prevIps, newIps).forEach(ip -> {
+                if (newLocations.stream().noneMatch(newLocation ->
+                        srManager.deviceConfiguration.inSameSubnet(newLocation, ip))) {
+                    processRoutingRule(prevLocation.deviceId(), prevLocation.port(), mac, vlanId,
+                            ip, true);
+                }
             });
-        }
+
+            // Remove routing rules for old IPs
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                processRoutingRule(prevLocation.deviceId(), prevLocation.port(), mac, vlanId,
+                        ip, true)
+            );
+        });
+
+        // For each new location, add all new IPs.
+        Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
+            processBridgingRule(newLocation.deviceId(), newLocation.port(), mac, vlanId, false);
+            newIps.forEach(ip ->
+                    processRoutingRule(newLocation.deviceId(), newLocation.port(), mac, vlanId,
+                            ip, false)
+            );
+        });
+
+        // For each unchanged location, add new IPs and remove old IPs.
+        Sets.intersection(newLocations, prevLocations).forEach(unchangedLocation -> {
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                    processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), mac,
+                            vlanId, ip, true)
+            );
+
+            Sets.difference(newIps, prevIps).forEach(ip ->
+                    processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), mac,
+                        vlanId, ip, false)
+            );
+        });
     }
 
-    protected void processHostUpdatedEvent(HostEvent event) {
+    void processHostUpdatedEvent(HostEvent event) {
         MacAddress mac = event.subject().mac();
         VlanId vlanId = event.subject().vlan();
-        HostLocation prevLocation = event.prevSubject().location();
-        DeviceId prevDeviceId = prevLocation.deviceId();
-        PortNumber prevPort = prevLocation.port();
+        Set<HostLocation> locations = event.subject().locations();
         Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
-        HostLocation newLocation = event.subject().location();
-        DeviceId newDeviceId = newLocation.deviceId();
-        PortNumber newPort = newLocation.port();
         Set<IpAddress> newIps = event.subject().ipAddresses();
         log.info("Host {}/{} is updated", mac, vlanId);
 
-        if (accepted(event.prevSubject())) {
-            // Revoke previous IP table entry
-            Sets.difference(prevIps, newIps).forEach(ip -> {
-                processRoutingRule(prevDeviceId, prevPort, mac, vlanId, ip, true);
-            });
-        }
-
-        if (accepted(event.subject())) {
-            // Populate new IP table entry
-            Sets.difference(newIps, prevIps).forEach(ip -> {
-                processRoutingRule(newDeviceId, newPort, mac, vlanId, ip, false);
-            });
-        }
+        locations.forEach(location -> {
+            Sets.difference(prevIps, newIps).forEach(ip ->
+                    processRoutingRule(location.deviceId(), location.port(), mac, vlanId, ip, true)
+            );
+            Sets.difference(newIps, prevIps).forEach(ip ->
+                    processRoutingRule(location.deviceId(), location.port(), mac, vlanId, ip, false)
+            );
+        });
     }
 
     /**
@@ -185,7 +225,7 @@
      * @param revoke true if forwarding objective is meant to revoke forwarding rule
      * @return Forwarding objective builder
      */
-    private ForwardingObjective.Builder bridgingFwdObjBuilder(
+    ForwardingObjective.Builder bridgingFwdObjBuilder(
             DeviceId deviceId, MacAddress mac, VlanId hostVlanId,
             PortNumber outport, boolean revoke) {
         ConnectPoint connectPoint = new ConnectPoint(deviceId, outport);
@@ -290,33 +330,16 @@
     private void processRoutingRule(DeviceId deviceId, PortNumber port, MacAddress mac,
                                     VlanId vlanId, IpAddress ip, boolean revoke) {
         ConnectPoint location = new ConnectPoint(deviceId, port);
-        if (srManager.deviceConfiguration.inSameSubnet(location, ip)) {
-            log.info("{} routing rule for {} at {}", revoke ? "Revoking" : "Populating",
-                    ip, location);
-            if (revoke) {
-                srManager.routingRulePopulator.revokeRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
-            } else {
-                srManager.routingRulePopulator.populateRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
-            }
+        if (!srManager.deviceConfiguration.inSameSubnet(location, ip)) {
+            log.info("{} is not included in the subnet config of {}/{}. Ignored.", ip, deviceId, port);
+            return;
         }
-    }
 
-    /**
-     * Determines whether a host should be accepted by SR or not.
-     *
-     * @param host host to be checked
-     * @return true if segment routing accepts the host
-     */
-    private boolean accepted(Host host) {
-        SegmentRoutingAppConfig appConfig = srManager.cfgService
-                .getConfig(srManager.appId, SegmentRoutingAppConfig.class);
-
-        boolean accepted = appConfig == null ||
-                (!appConfig.suppressHostByProvider().contains(host.providerId().id()) &&
-                !appConfig.suppressHostByPort().contains(host.location()));
-        if (!accepted) {
-            log.info("Ignore suppressed host {}", host.id());
+        log.info("{} routing rule for {} at {}", revoke ? "Revoking" : "Populating", ip, location);
+        if (revoke) {
+            srManager.routingRulePopulator.revokeRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
+        } else {
+            srManager.routingRulePopulator.populateRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
         }
-        return accepted;
     }
 }
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 1f126c6..9ac8d1a 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -648,6 +648,21 @@
     }
 
     /**
+     * Returns internal VLAN for untagged hosts on given connect point.
+     * <p>
+     * The internal VLAN is either vlan-untagged for an access port,
+     * or vlan-native for a trunk port.
+     *
+     * @param connectPoint connect point
+     * @return internal VLAN or null if both vlan-untagged and vlan-native are undefined
+     */
+    public VlanId getInternalVlanId(ConnectPoint connectPoint) {
+        VlanId untaggedVlanId = getUntaggedVlanId(connectPoint);
+        VlanId nativeVlanId = getNativeVlanId(connectPoint);
+        return untaggedVlanId != null ? untaggedVlanId : nativeVlanId;
+    }
+
+    /**
      * Returns vlan port map of given device.
      *
      * @param deviceId device id
@@ -1465,7 +1480,7 @@
                     hostHandler.processHostMovedEvent(event);
                     break;
                 case HOST_REMOVED:
-                    hostHandler.processHostRemoveEvent(event);
+                    hostHandler.processHostRemovedEvent(event);
                     break;
                 case HOST_UPDATED:
                     hostHandler.processHostUpdatedEvent(event);
diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
index ba9bf8f..d9900c2 100644
--- a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -48,6 +48,7 @@
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostServiceAdapter;
 import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.segmentrouting.config.DeviceConfiguration;
@@ -73,40 +74,52 @@
     private Map<Integer, TrafficTreatment> nextTable = Maps.newConcurrentMap();
     private AtomicInteger atomicNextId = new AtomicInteger();
 
-    // Host information
+    // Host Mac, VLAN
     private static final ProviderId PROVIDER_ID = ProviderId.NONE;
     private static final MacAddress HOST_MAC = MacAddress.valueOf("00:00:00:00:00:01");
     private static final VlanId HOST_VLAN_UNTAGGED = VlanId.NONE;
     private static final HostId HOST_ID_UNTAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_UNTAGGED);
     private static final VlanId HOST_VLAN_TAGGED = VlanId.vlanId((short) 20);
     private static final HostId HOST_ID_TAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_TAGGED);
-    private static final IpAddress HOST_IP1 = IpAddress.valueOf("10.0.1.1");
-    private static final IpAddress HOST_IP2 = IpAddress.valueOf("10.0.2.1");
-    private static final IpAddress HOST_IP3 = IpAddress.valueOf("10.0.1.2");
-
-    // Untagged interface
-    private static final ConnectPoint CP1 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(10));
-    private static final HostLocation HOST_LOC1 = new HostLocation(CP1, 0);
-    private static final IpPrefix INTF_PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
-    private static final InterfaceIpAddress INTF_IP1 = new InterfaceIpAddress(INTF_PREFIX1.address(),
-            INTF_PREFIX1);
+    // Host IP
+    private static final IpAddress HOST_IP11 = IpAddress.valueOf("10.0.1.1");
+    private static final IpAddress HOST_IP21 = IpAddress.valueOf("10.0.2.1");
+    private static final IpAddress HOST_IP12 = IpAddress.valueOf("10.0.1.2");
+    private static final IpAddress HOST_IP13 = IpAddress.valueOf("10.0.1.3");
+    private static final IpAddress HOST_IP14 = IpAddress.valueOf("10.0.1.4");
+    // Device
+    private static final DeviceId DEV1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV2 = DeviceId.deviceId("of:0000000000000002");
+    // Port
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
+    // Connect Point
+    private static final ConnectPoint CP11 = new ConnectPoint(DEV1, P1);
+    private static final HostLocation HOST_LOC11 = new HostLocation(CP11, 0);
+    private static final ConnectPoint CP12 = new ConnectPoint(DEV1, P2);
+    private static final HostLocation HOST_LOC12 = new HostLocation(CP12, 0);
+    private static final ConnectPoint CP13 = new ConnectPoint(DEV1, P3);
+    private static final HostLocation HOST_LOC13 = new HostLocation(CP13, 0);
+    private static final ConnectPoint CP21 = new ConnectPoint(DEV2, P1);
+    private static final HostLocation HOST_LOC21 = new HostLocation(CP21, 0);
+    private static final ConnectPoint CP22 = new ConnectPoint(DEV2, P2);
+    private static final HostLocation HOST_LOC22 = new HostLocation(CP22, 0);
+    // Interface VLAN
     private static final VlanId INTF_VLAN_UNTAGGED = VlanId.vlanId((short) 10);
-
-    // Another untagged interface with same subnet and vlan
-    private static final ConnectPoint CP3 = new ConnectPoint(DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(30));
-    private static final HostLocation HOST_LOC3 = new HostLocation(CP3, 0);
-
-    // Tagged/Native interface
-    private static final ConnectPoint CP2 = new ConnectPoint(DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(20));
-    private static final HostLocation HOST_LOC2 = new HostLocation(CP2, 0);
-    private static final IpPrefix INTF_PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
-    private static final InterfaceIpAddress INTF_IP2 = new  InterfaceIpAddress(INTF_PREFIX2.address(),
-            INTF_PREFIX2);
     private static final Set<VlanId> INTF_VLAN_TAGGED = Sets.newHashSet(VlanId.vlanId((short) 20));
     private static final VlanId INTF_VLAN_NATIVE = VlanId.vlanId((short) 30);
+    // Interface subnet
+    private static final IpPrefix INTF_PREFIX1 = IpPrefix.valueOf("10.0.1.254/24");
+    private static final IpPrefix INTF_PREFIX2 = IpPrefix.valueOf("10.0.2.254/24");
+    private static final InterfaceIpAddress INTF_IP1 =
+            new InterfaceIpAddress(INTF_PREFIX1.address(), INTF_PREFIX1);
+    private static final InterfaceIpAddress INTF_IP2 =
+            new InterfaceIpAddress(INTF_PREFIX2.address(), INTF_PREFIX2);
+    // Host
+    private static final Host HOST1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC,
+            HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11),
+            false);
 
     @Before
     public void setUp() throws Exception {
@@ -116,6 +129,7 @@
         srManager.flowObjectiveService = new MockFlowObjectiveService();
         srManager.routingRulePopulator = new MockRoutingRulePopulator();
         srManager.interfaceService = new MockInterfaceService();
+        srManager.hostService = new MockHostService();
 
         hostHandler = new HostHandler(srManager);
 
@@ -125,7 +139,34 @@
 
     @Test
     public void init() throws Exception {
-        // TODO Implement test for init()
+        hostHandler.init(DEV1);
+        assertEquals(1, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        hostHandler.init(DEV2);
+        assertEquals(2, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testHostAddedAtWrongLocation() throws Exception {
+        hostHandler.processHostAddedAtLocation(HOST1, HOST_LOC13);
+    }
+
+
+    @Test()
+    public void testHostAddedAtCorrectLocation() throws Exception {
+        hostHandler.processHostAddedAtLocation(HOST1, HOST_LOC11);
+        assertEquals(1, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertEquals(1, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
@@ -135,27 +176,27 @@
         // Untagged host discovered on untagged port
         // Expect: add one routing rule and one bridging rule
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
         assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Untagged host discovered on tagged/native port
         // Expect: add one routing rule and one bridging rule
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP2), false);
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
         assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP2.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
         assertEquals(2, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, INTF_VLAN_NATIVE)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
 
         // Tagged host discovered on untagged port
         // Expect: ignore the host. No rule is added.
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
         assertEquals(2, routingTable.size());
         assertEquals(2, bridgingTable.size());
@@ -163,119 +204,265 @@
         // Tagged host discovered on tagged port with the same IP
         // Expect: update existing route, add one bridging rule
         subject = new DefaultHost(PROVIDER_ID, HOST_ID_TAGGED, HOST_MAC, HOST_VLAN_TAGGED,
-                Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP2), false);
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP21), false);
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
         assertEquals(2, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP2.toIpPrefix())));
-        assertEquals(HOST_VLAN_TAGGED, routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(),
-                HOST_IP2.toIpPrefix())).vlanId);
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertEquals(HOST_VLAN_TAGGED, routingTable.get(new RoutingTableKey(HOST_LOC13.deviceId(),
+                HOST_IP21.toIpPrefix())).vlanId);
         assertEquals(3, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, HOST_VLAN_TAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, HOST_VLAN_TAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostAdded() throws Exception {
+        // Add a dual-homed host that has 2 locations
+        // Expect: add two routing rules and two bridging rules
+        Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
     }
 
     @Test
     public void testHostRemoved() throws Exception {
         Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
 
         // Add a host
         // Expect: add one routing rule and one bridging rule
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
         assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Remove the host
         // Expect: add the routing rule and the bridging rule
-        hostHandler.processHostRemoveEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
+        hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
         assertEquals(0, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
         assertEquals(0, bridgingTable.size());
-        assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostRemoved() throws Exception {
+        // Add a dual-homed host that has 2 locations
+        // Expect: add two routing rules and two bridging rules
+        Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+        assertEquals(2, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Remove a dual-homed host that has 2 locations
+        // Expect: all routing and bridging rules are removed
+        hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
+        assertEquals(0, routingTable.size());
+        assertEquals(0, bridgingTable.size());
     }
 
     @Test
     public void testHostMoved() throws Exception {
         Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC2), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC21), Sets.newHashSet(HOST_IP11), false);
         Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC3), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC13), Sets.newHashSet(HOST_IP11), false);
 
         // Add a host
         // Expect: add a new routing rule. no change to bridging rule.
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
         assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
-        // Move the host to CP2, which has different subnet setting
+        // Move the host to CP13, which has different subnet setting
         // Expect: remove routing rule. Change vlan in bridging rule.
-        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host1));
         assertEquals(0, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC3.deviceId(), HOST_IP1.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC2.deviceId(), HOST_MAC, INTF_VLAN_NATIVE)));
-        assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_NATIVE)));
+        assertNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
-        // Move the host to CP3, which has same subnet setting
+        // Move the host to CP21, which has same subnet setting
         // Expect: add a new routing rule. Change vlan in bridging rule.
-        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host3));
         assertEquals(1, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC2.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC3.deviceId(), HOST_IP1.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC3.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostMoved() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC12, HOST_LOC22), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP13, HOST_IP14), false);
+        Host host4 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC22), Sets.newHashSet(HOST_IP12, HOST_IP13), false);
+
+        // Add a host with IP11, IP12 and LOC11, LOC21
+        // Expect: 4 routing rules and 2 bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, routingTable.size());
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, bridgingTable.size());
+        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC12, LOC22 and keep the IP
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+        assertEquals(4, routingTable.size());
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(2, bridgingTable.size());
+        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC11, LOC21 and change the IP to IP13, IP14 at the same time
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host3, host2));
+        assertEquals(4, routingTable.size());
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV2, HOST_IP14.toIpPrefix())).portNumber);
+        assertEquals(2, bridgingTable.size());
+        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
+        // Move the host to LOC11, LOC22 and change the IP to IP12, IP13 at the same time
+        // Expect: 4 routing rules and 2 bridging rules all at the new location
+        hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host4, host3));
+        assertEquals(4, routingTable.size());
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P1, routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+        assertEquals(P2, routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())).portNumber);
+        assertEquals(2, bridgingTable.size());
+        assertEquals(P1, bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+        assertEquals(P2, bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
     }
 
     @Test
     public void testHostUpdated() throws Exception {
         Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP1), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
         Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP2), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP21), false);
         Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
-                Sets.newHashSet(HOST_LOC1), Sets.newHashSet(HOST_IP3), false);
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP12), false);
 
         // Add a host
-        // Expect: add a new routing rule. no change to bridging rule.
+        // Expect: add one new routing rule. Add one new bridging rule.
         hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
         assertEquals(1, routingTable.size());
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC11.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Update the host IP to same subnet
         // Expect: update routing rule with new IP. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
         assertEquals(1, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
-        assertNotNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
 
         // Update the host IP to different subnet
         // Expect: Remove routing rule. No change to bridging rule.
         hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
         assertEquals(0, routingTable.size());
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP1.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP2.toIpPrefix())));
-        assertNull(routingTable.get(new RoutingTableKey(HOST_LOC1.deviceId(), HOST_IP3.toIpPrefix())));
         assertEquals(1, bridgingTable.size());
-        assertNotNull(bridgingTable.get(new BridingTableKey(HOST_LOC1.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testDualHomedHostUpdated() throws Exception {
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP21), false);
+        Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP13, HOST_IP14), false);
+
+        // Add a dual-homed host with two locations and two IPs
+        // Expect: add four new routing rules. Add two new bridging rules
+        hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+        assertEquals(4, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Update both host IPs
+        // Expect: update routing rules with new IP. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
+        assertEquals(4, routingTable.size());
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP13.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP14.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP13.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP14.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+        // Update one of the host IP to different subnet
+        // Expect: update routing rule with new IP. No change to bridging rule.
+        hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
+        assertEquals(2, routingTable.size());
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
+        assertNotNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP11.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP21.toIpPrefix())));
+        assertNull(routingTable.get(new RoutingTableKey(DEV2, HOST_IP12.toIpPrefix())));
+        assertEquals(2, bridgingTable.size());
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+        assertNotNull(bridgingTable.get(new BridingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)));
+    }
+
+    @Test
+    public void testBridgingFwdObjBuilder() throws Exception {
+        assertNotNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P1, false));
+        assertNull(hostHandler.bridgingFwdObjBuilder(DEV2, HOST_MAC, HOST_VLAN_UNTAGGED, P3, false));
     }
 
     class MockSegmentRoutingManager extends SegmentRoutingManager {
@@ -299,14 +486,20 @@
         public Set<Interface> getInterfacesByPort(ConnectPoint cp) {
             Interface intf = null;
 
-            if (CP1.equals(cp)) {
-                intf = new Interface(null, CP1, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+            if (CP11.equals(cp)) {
+                intf = new Interface(null, CP11, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
                         INTF_VLAN_UNTAGGED, null, null);
-            } else if (CP2.equals(cp)) {
-                intf = new Interface(null, CP2, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
+            } else if (CP12.equals(cp)) {
+                intf = new Interface(null, CP12, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                        INTF_VLAN_UNTAGGED, null, null);
+            } else if (CP13.equals(cp)) {
+                intf = new Interface(null, CP13, Lists.newArrayList(INTF_IP2), MacAddress.NONE, null,
                         null, INTF_VLAN_TAGGED, INTF_VLAN_NATIVE);
-            } else if (CP3.equals(cp)) {
-                intf = new Interface(null, CP3, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+            } else if (CP21.equals(cp)) {
+                intf = new Interface(null, CP21, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
+                        INTF_VLAN_UNTAGGED, null, null);
+            } else if (CP22.equals(cp)) {
+                intf = new Interface(null, CP22, Lists.newArrayList(INTF_IP1), MacAddress.NONE, null,
                         INTF_VLAN_UNTAGGED, null, null);
             }
 
@@ -348,6 +541,13 @@
         }
     }
 
+    class MockHostService extends HostServiceAdapter {
+        @Override
+        public Set<Host> getHosts() {
+            return Sets.newHashSet(HOST1);
+        }
+    }
+
     class MockRoutingRulePopulator extends RoutingRulePopulator {
         MockRoutingRulePopulator() {
             super(srManager);
