Merge branch 'master' into merge

Change-Id: I35af23202e94a114f129f2f000ab237165b26737
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
index 6092cec..06de0f9 100644
--- a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/NetworkConfigLinksProvider.java
@@ -68,6 +68,8 @@
 import static org.onlab.packet.Ethernet.TYPE_BSN;
 import static org.onlab.packet.Ethernet.TYPE_LLDP;
 import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.provider.netcfglinks.OsgiPropertyConstants.DISCOVERY_DELAY_DEFAULT;
+import static org.onosproject.provider.netcfglinks.OsgiPropertyConstants.PROP_DISCOVERY_DELAY;
 import static org.onosproject.provider.netcfglinks.OsgiPropertyConstants.PROP_PROBE_RATE;
 import static org.onosproject.provider.netcfglinks.OsgiPropertyConstants.PROBE_RATE_DEFAULT;
 
@@ -79,6 +81,7 @@
 @Component(immediate = true,
         property = {
             PROP_PROBE_RATE + ":Integer=" + PROBE_RATE_DEFAULT,
+            PROP_DISCOVERY_DELAY + ":Integer=" + DISCOVERY_DELAY_DEFAULT,
         })
 public class NetworkConfigLinksProvider
         extends AbstractProvider
@@ -109,6 +112,10 @@
     //        label = "LLDP and BDDP probe rate specified in millis")
     private int probeRate = PROBE_RATE_DEFAULT;
 
+    //@Property(name = PROP_DISCOVERY_DELAY, intValue = DEFAULT_DISCOVERY_DELAY,
+    //        label = "Number of millis beyond which an LLDP packet will not be accepted")
+    private int maxDiscoveryDelayMs = DISCOVERY_DELAY_DEFAULT;
+
     // Device link discovery helpers.
     protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
 
@@ -267,8 +274,29 @@
         public DeviceService deviceService() {
             return deviceService;
         }
+
+        @Override
+        public String lldpSecret() {
+            return metadataService.getClusterMetadata().getClusterSecret();
+        }
+
+        @Override
+        public long maxDiscoveryDelay() {
+            return maxDiscoveryDelayMs;
+        }
     }
 
+    // true if *NOT* this cluster's own probe.
+    private boolean isOthercluster(String mac) {
+        // if we are using DEFAULT_MAC, clustering hadn't initialized, so conservative 'yes'
+        String ourMac = context.fingerprint();
+        if (ProbedLinkProvider.defaultMac().equalsIgnoreCase(ourMac)) {
+            return true;
+        }
+        return !mac.equalsIgnoreCase(ourMac);
+    }
+
+    //doesn't validate. Used just to decide if this is expected link.
     LinkKey extractLinkKey(PacketContext packetContext) {
         Ethernet eth = packetContext.inPacket().parsed();
         if (eth == null) {
@@ -289,6 +317,27 @@
         return null;
     }
 
+    private boolean verify(PacketContext packetContext) {
+        Ethernet eth = packetContext.inPacket().parsed();
+        if (eth == null) {
+            return false;
+        }
+
+        ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
+        if (onoslldp != null) {
+            if (!isOthercluster(eth.getSourceMAC().toString())) {
+                return false;
+            }
+
+            if (!ONOSLLDP.verify(onoslldp, context.lldpSecret(), context.maxDiscoveryDelay())) {
+                log.warn("LLDP Packet failed to validate!");
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Removes after stopping discovery helper for specified device.
      * @param deviceId device to remove
@@ -346,13 +395,15 @@
                         context.block();
                     }
                 } else {
-                    log.debug("Found link that was not in the configuration {}", linkKey);
-                    providerService.linkDetected(
-                            new DefaultLinkDescription(linkKey.src(),
-                                                       linkKey.dst(),
-                                                       Link.Type.DIRECT,
-                                                       DefaultLinkDescription.NOT_EXPECTED,
-                                                       DefaultAnnotations.EMPTY));
+                    if (verify(context)) {
+                        log.debug("Found link that was not in the configuration {}", linkKey);
+                        providerService.linkDetected(
+                                new DefaultLinkDescription(linkKey.src(),
+                                                           linkKey.dst(),
+                                                           Link.Type.DIRECT,
+                                                           DefaultLinkDescription.NOT_EXPECTED,
+                                                           DefaultAnnotations.EMPTY));
+                    }
                 }
             }
         }
diff --git a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/OsgiPropertyConstants.java b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/OsgiPropertyConstants.java
index c04dedb..5d718ed 100644
--- a/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/OsgiPropertyConstants.java
+++ b/providers/netcfglinks/src/main/java/org/onosproject/provider/netcfglinks/OsgiPropertyConstants.java
@@ -26,4 +26,7 @@
     public static final String PROP_PROBE_RATE = "probeRate";
     public static final int PROBE_RATE_DEFAULT = 3000;
 
+    public static final String PROP_DISCOVERY_DELAY = "maxLLDPAge";
+    public static final int DISCOVERY_DELAY_DEFAULT = 1000;
+
 }