Secure LLDP-based Topology Detection
Current LLDP/BDDP-based Topology Detection is vulnerable to the
creation of fake links via forged, modified, or replayed LLDP packets.
This patch fixes this vulnerability by authenticating LLDP/BDDP packets
using a Message Authentication Code and adding a timestamp to prevent
replay. We use HMAC with SHA-256 has our Messge Authentication Code and
derive the key from the config/cluster.json file via the
ClusterMetadata class.
Change-Id: I01dd6edc5cffd6dfe274bcdb97189f2661a6c4f1
diff --git a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
index 317fda8..3d69235 100644
--- a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
+++ b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
@@ -173,6 +173,12 @@
} else {
lt = eth.getEtherType() == Ethernet.TYPE_LLDP ?
Type.DIRECT : Type.INDIRECT;
+
+ /* Verify MAC in LLDP packets */
+ if (!ONOSLLDP.verify(onoslldp, context.lldpSecret(), context.maxDiscoveryDelay())) {
+ log.warn("LLDP Packet failed to validate!");
+ return true;
+ }
}
PortNumber srcPort = portNumber(onoslldp.getPort());
@@ -269,7 +275,8 @@
}
private ONOSLLDP getLinkProbe(Long portNumber, String portDesc) {
- return ONOSLLDP.onosLLDP(device.id().toString(), device.chassisId(), portNumber.intValue(), portDesc);
+ return ONOSLLDP.onosSecureLLDP(device.id().toString(), device.chassisId(), portNumber.intValue(), portDesc,
+ context.lldpSecret());
}
private void sendProbes(Long portNumber, String portDesc) {
diff --git a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
index e4a025e..a325b95 100644
--- a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
+++ b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscoveryContext.java
@@ -81,4 +81,18 @@
* @return the cluster identifier
*/
String fingerprint();
+
+ /**
+ * Returns the cluster-wide MAC secret used to secure LLDP packets.
+ *
+ * @return the secret
+ */
+ String lldpSecret();
+
+ /**
+ * Returns the maximum delay in milliseconds between sending an LLDP packet and receiving it elsewhere.
+ *
+ * @return delay in ms
+ */
+ long maxDiscoveryDelay();
}