Merge branch 'master' into dev-karaf-4.2.1

Change-Id: I059c6a95489ff5cdc51dd7e98ba44a8415238bc2
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index ffc0e4d..ae35f7b 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -448,18 +448,37 @@
      * @param pairRemotePort pair remote port
      */
     private void probe(Host host, ConnectPoint location, DeviceId pairDeviceId, PortNumber pairRemotePort) {
+        //Check if the host still exists in the host store
+        if (hostService.getHost(host.id()) == null) {
+            log.debug("Host entry for host {} no more present. Aborting hostprobe discover for this host", host.id());
+            return;
+        }
+
         VlanId vlanToProbe = host.vlan().equals(VlanId.NONE) ?
                 srManager.getInternalVlanId(location) : host.vlan();
-        srManager.interfaceService.getInterfaces().stream()
-                .filter(i -> i.vlanTagged().contains(vlanToProbe) ||
-                        i.vlanUntagged().equals(vlanToProbe) ||
-                        i.vlanNative().equals(vlanToProbe))
-                .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId))
-                .filter(i -> !i.connectPoint().port().equals(pairRemotePort))
-                .forEach(i -> {
-                    log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint());
-                    srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER);
-                });
+        if (srManager.symmetricProbing) {
+            srManager.interfaceService.getInterfaces().stream()
+                    .filter(i -> i.vlanTagged().contains(vlanToProbe) ||
+                            i.vlanUntagged().equals(vlanToProbe) ||
+                            i.vlanNative().equals(vlanToProbe))
+                    .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId))
+                    .filter(i -> i.connectPoint().port().equals(location.port()))
+                    .forEach(i -> {
+                        log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint());
+                        srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER);
+                    });
+        } else {
+            srManager.interfaceService.getInterfaces().stream()
+                    .filter(i -> i.vlanTagged().contains(vlanToProbe) ||
+                            i.vlanUntagged().equals(vlanToProbe) ||
+                            i.vlanNative().equals(vlanToProbe))
+                    .filter(i -> i.connectPoint().deviceId().equals(pairDeviceId))
+                    .filter(i -> !i.connectPoint().port().equals(pairRemotePort))
+                    .forEach(i -> {
+                        log.debug("Probing host {} on pair device {}", host.id(), i.connectPoint());
+                        srManager.probingService.probeHost(host, i.connectPoint(), ProbeMode.DISCOVER);
+                    });
+        }
     }
 
     /**
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java
index 399e95b..7b5a6fc 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/OsgiPropertyConstants.java
@@ -41,4 +41,7 @@
     public static final String PROP_PW_TRANSPORT_VLAN = "pwTransportVlan";
     public static final int PW_TRANSPORT_VLAN_DEFAULT = 4090;
 
+    static final String PROP_SYMMETRIC_PROBING = "symmetricProbing";
+    static final boolean SYMMETRIC_PROBING_DEFAULT = false;
+
 }
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 17e733c..c75de3c 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -165,10 +165,12 @@
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_RESPOND_TO_UNKNOWN_HOSTS;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_ROUTE_DOUBLE_TAGGED_HOSTS;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_SINGLE_HOMED_DOWN;
+import static org.onosproject.segmentrouting.OsgiPropertyConstants.PROP_SYMMETRIC_PROBING;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.PW_TRANSPORT_VLAN_DEFAULT;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.RESPOND_TO_UNKNOWN_HOSTS_DEFAULT;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.ROUTE_DOUBLE_TAGGED_HOSTS_DEFAULT;
 import static org.onosproject.segmentrouting.OsgiPropertyConstants.SINGLE_HOMED_DOWN_DEFAULT;
+import static org.onosproject.segmentrouting.OsgiPropertyConstants.SYMMETRIC_PROBING_DEFAULT;
 
 /**
  * Segment routing manager.
@@ -183,6 +185,7 @@
         PROP_ROUTE_DOUBLE_TAGGED_HOSTS + ":Boolean=" + ROUTE_DOUBLE_TAGGED_HOSTS_DEFAULT,
         PROP_DEFAULT_INTERNAL_VLAN + ":Integer=" + DEFAULT_INTERNAL_VLAN_DEFAULT,
         PROP_PW_TRANSPORT_VLAN + ":Integer=" + PW_TRANSPORT_VLAN_DEFAULT,
+        PROP_SYMMETRIC_PROBING + ":Boolean=" + SYMMETRIC_PROBING_DEFAULT
     }
 )
 public class SegmentRoutingManager implements SegmentRoutingService {
@@ -256,6 +259,9 @@
     /** Enable active probing to discover dual-homed hosts. */
     boolean activeProbing = ACTIVE_PROBING_DEFAULT;
 
+    /** Enable only send probe on the same port number of the pair device. */
+    boolean symmetricProbing = SYMMETRIC_PROBING_DEFAULT;
+
     /** Enable administratively taking down single-homed hosts. */
     boolean singleHomedDown = SINGLE_HOMED_DOWN_DEFAULT;
 
@@ -625,6 +631,14 @@
             log.info("{} active probing", activeProbing ? "Enabling" : "Disabling");
         }
 
+
+        String strSymmetricProbing = Tools.get(properties, PROP_SYMMETRIC_PROBING);
+        boolean expectSymmetricProbing = Boolean.parseBoolean(strSymmetricProbing);
+        if (expectSymmetricProbing != symmetricProbing) {
+            symmetricProbing = expectSymmetricProbing;
+            log.info("{} symmetric probing", symmetricProbing ? "Enabling" : "Disabling");
+        }
+
         String strSingleHomedDown = Tools.get(properties, PROP_SINGLE_HOMED_DOWN);
         boolean expectSingleHomedDown = Boolean.parseBoolean(strSingleHomedDown);
         if (expectSingleHomedDown != singleHomedDown) {