Ayaka Koshibe
Committed by Yuta HIGUCHI

[ONOS-4424] Tag LLDP/BDDP source address with fingerprint

Link probes incorporate cluster fingerprint in source
MAC address. This removes the need for an additional TLV and the
complexity associated with it, and also adds fingerprinting to
BDDPs for free.

 - fingerprint in Ethernet source address. The old default MAC
   value is only used when the CusterMetadata service isn't ready.
 - remove support for TLV fingerprint field and associated config
   knobs.
 - links at control domain boundary are classified as EDGE type links.

Change-Id: Idb07dd06fbeee25e9fcee3fbdddec7a7dbb2c397
...@@ -25,11 +25,14 @@ import org.onosproject.net.provider.ProviderId; ...@@ -25,11 +25,14 @@ import org.onosproject.net.provider.ProviderId;
25 25
26 import static com.google.common.base.Preconditions.checkNotNull; 26 import static com.google.common.base.Preconditions.checkNotNull;
27 import static com.google.common.base.Verify.verify; 27 import static com.google.common.base.Verify.verify;
28 +import static com.google.common.base.Charsets.UTF_8;
28 29
29 import com.google.common.base.MoreObjects; 30 import com.google.common.base.MoreObjects;
30 import com.google.common.collect.Collections2; 31 import com.google.common.collect.Collections2;
31 import com.google.common.collect.ImmutableSet; 32 import com.google.common.collect.ImmutableSet;
32 import com.google.common.collect.Sets; 33 import com.google.common.collect.Sets;
34 +import com.google.common.hash.Funnel;
35 +import com.google.common.hash.PrimitiveSink;
33 36
34 /** 37 /**
35 * Cluster metadata. 38 * Cluster metadata.
...@@ -40,14 +43,18 @@ import com.google.common.collect.Sets; ...@@ -40,14 +43,18 @@ import com.google.common.collect.Sets;
40 */ 43 */
41 public final class ClusterMetadata implements Provided { 44 public final class ClusterMetadata implements Provided {
42 45
43 - // Name to use when the ClusterMetadataService is in transient state
44 - public static final String NO_NAME = "";
45 -
46 private final ProviderId providerId; 46 private final ProviderId providerId;
47 private final String name; 47 private final String name;
48 private final Set<ControllerNode> nodes; 48 private final Set<ControllerNode> nodes;
49 private final Set<Partition> partitions; 49 private final Set<Partition> partitions;
50 50
51 + public static final Funnel<ClusterMetadata> HASH_FUNNEL = new Funnel<ClusterMetadata>() {
52 + @Override
53 + public void funnel(ClusterMetadata cm, PrimitiveSink into) {
54 + into.putString(cm.name, UTF_8);
55 + }
56 + };
57 +
51 @SuppressWarnings("unused") 58 @SuppressWarnings("unused")
52 private ClusterMetadata() { 59 private ClusterMetadata() {
53 providerId = null; 60 providerId = null;
......
1 +/*
2 + * Copyright 2014-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.net.link;
17 +
18 +import com.google.common.hash.HashFunction;
19 +import com.google.common.hash.HashCode;
20 +import com.google.common.hash.Hashing;
21 +
22 +import org.onosproject.cluster.ClusterMetadata;
23 +
24 +/**
25 + * Abstraction for an entity that provides information about infrastructure
26 + * links that are discovered or verified using probe messages.
27 + */
28 +public interface ProbedLinkProvider extends LinkProvider {
29 +
30 + static final String DEFAULT_MAC = "DE:AD:BE:EF:BA:11";
31 +
32 + static String defaultMac() {
33 + return DEFAULT_MAC;
34 + }
35 +
36 + /**
37 + * Build a stringified MAC address using the ClusterMetadata hash for uniqueness.
38 + * Form of MAC is "02:eb" followed by four bytes of clusterMetadata hash.
39 + */
40 + static String fingerprintMac(ClusterMetadata cm) {
41 + if (cm == null) {
42 + return DEFAULT_MAC;
43 + }
44 +
45 + HashFunction hf = Hashing.murmur3_32();
46 + HashCode hc = hf.newHasher().putObject(cm, ClusterMetadata.HASH_FUNNEL).hash();
47 + int unqf = hc.asInt();
48 +
49 + StringBuilder sb = new StringBuilder();
50 + sb.append("02:eb");
51 + for (int i = 0; i < 4; i++) {
52 + byte b = (byte) (unqf >> i * 8);
53 + sb.append(String.format(":%02X", b));
54 + }
55 + return sb.toString();
56 + }
57 +}
1 /* 1 /*
2 - * Copyright 2015-present Open Networking Laboratory 2 + * Copyright 2014-present Open Networking Laboratory
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
...@@ -13,21 +13,38 @@ ...@@ -13,21 +13,38 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.provider.lldp.impl; 16 +package org.onosproject.cluster;
17 17
18 -import org.onosproject.net.DeviceId; 18 +import org.onlab.packet.IpAddress;
19 -import org.onosproject.net.config.basics.BasicFeatureConfig; 19 +
20 +import com.google.common.collect.Sets;
20 21
21 /** 22 /**
22 - * A feature to send and receive probes carrying a cluster-unique fingerprint. 23 + * Test adapter for the ClusterMetadata service.
23 - * Note that, as it leverages LinkDiscovery, disabling linkDiscovery will disable
24 - * this function.
25 */ 24 */
26 -public class FingerprintProbeFromDevice extends BasicFeatureConfig<DeviceId> { 25 +public class ClusterMetadataServiceAdapter implements ClusterMetadataService {
26 +
27 + @Override
28 + public ClusterMetadata getClusterMetadata() {
29 + final NodeId nid = new NodeId("test-node");
30 + final IpAddress addr = IpAddress.valueOf(0);
31 + final Partition p = new DefaultPartition(PartitionId.from(1), Sets.newHashSet(nid));
32 + return new ClusterMetadata("test-cluster",
33 + Sets.newHashSet(new DefaultControllerNode(nid, addr)),
34 + Sets.newHashSet(p));
35 + }
36 +
37 + @Override
38 + public ControllerNode getLocalNode() {
39 + return null;
40 + }
41 +
42 + @Override
43 + public void addListener(ClusterMetadataEventListener listener) {
44 + }
27 45
28 - protected FingerprintProbeFromDevice() { 46 + @Override
29 - // default:disabled 47 + public void removeListener(ClusterMetadataEventListener listener) {
30 - super(false);
31 } 48 }
32 49
33 } 50 }
......
...@@ -29,7 +29,6 @@ import org.onlab.packet.Ethernet; ...@@ -29,7 +29,6 @@ import org.onlab.packet.Ethernet;
29 import org.onlab.util.SharedExecutors; 29 import org.onlab.util.SharedExecutors;
30 import org.onlab.util.Tools; 30 import org.onlab.util.Tools;
31 import org.onosproject.cfg.ComponentConfigService; 31 import org.onosproject.cfg.ComponentConfigService;
32 -import org.onosproject.cluster.ClusterMetadata;
33 import org.onosproject.cluster.ClusterMetadataService; 32 import org.onosproject.cluster.ClusterMetadataService;
34 import org.onosproject.cluster.ClusterService; 33 import org.onosproject.cluster.ClusterService;
35 import org.onosproject.core.ApplicationId; 34 import org.onosproject.core.ApplicationId;
...@@ -53,7 +52,7 @@ import org.onosproject.net.device.DeviceService; ...@@ -53,7 +52,7 @@ import org.onosproject.net.device.DeviceService;
53 import org.onosproject.net.flow.DefaultTrafficSelector; 52 import org.onosproject.net.flow.DefaultTrafficSelector;
54 import org.onosproject.net.flow.TrafficSelector; 53 import org.onosproject.net.flow.TrafficSelector;
55 import org.onosproject.net.link.DefaultLinkDescription; 54 import org.onosproject.net.link.DefaultLinkDescription;
56 -import org.onosproject.net.link.LinkProvider; 55 +import org.onosproject.net.link.ProbedLinkProvider;
57 import org.onosproject.net.link.LinkProviderRegistry; 56 import org.onosproject.net.link.LinkProviderRegistry;
58 import org.onosproject.net.link.LinkProviderService; 57 import org.onosproject.net.link.LinkProviderService;
59 import org.onosproject.net.link.LinkService; 58 import org.onosproject.net.link.LinkService;
...@@ -85,7 +84,6 @@ import static org.onlab.packet.Ethernet.TYPE_BSN; ...@@ -85,7 +84,6 @@ import static org.onlab.packet.Ethernet.TYPE_BSN;
85 import static org.onlab.packet.Ethernet.TYPE_LLDP; 84 import static org.onlab.packet.Ethernet.TYPE_LLDP;
86 import static org.onlab.util.Tools.get; 85 import static org.onlab.util.Tools.get;
87 import static org.onlab.util.Tools.groupedThreads; 86 import static org.onlab.util.Tools.groupedThreads;
88 -import static org.onosproject.cluster.ClusterMetadata.NO_NAME;
89 import static org.onosproject.net.Link.Type.DIRECT; 87 import static org.onosproject.net.Link.Type.DIRECT;
90 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; 88 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
91 import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY; 89 import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
...@@ -96,7 +94,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -96,7 +94,7 @@ import static org.slf4j.LoggerFactory.getLogger;
96 * Provider which uses LLDP and BDDP packets to detect network infrastructure links. 94 * Provider which uses LLDP and BDDP packets to detect network infrastructure links.
97 */ 95 */
98 @Component(immediate = true) 96 @Component(immediate = true)
99 -public class LldpLinkProvider extends AbstractProvider implements LinkProvider { 97 +public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProvider {
100 98
101 private static final String PROVIDER_NAME = "org.onosproject.provider.lldp"; 99 private static final String PROVIDER_NAME = "org.onosproject.provider.lldp";
102 100
...@@ -194,7 +192,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -194,7 +192,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
194 192
195 public static final String CONFIG_KEY = "suppression"; 193 public static final String CONFIG_KEY = "suppression";
196 public static final String FEATURE_NAME = "linkDiscovery"; 194 public static final String FEATURE_NAME = "linkDiscovery";
197 - public static final String FINGERPRINT_FEATURE_NAME = "fingerprint";
198 195
199 private final Set<ConfigFactory<?, ?>> factories = ImmutableSet.of( 196 private final Set<ConfigFactory<?, ?>> factories = ImmutableSet.of(
200 new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY, 197 new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY,
...@@ -218,19 +215,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -218,19 +215,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
218 public LinkDiscoveryFromPort createConfig() { 215 public LinkDiscoveryFromPort createConfig() {
219 return new LinkDiscoveryFromPort(); 216 return new LinkDiscoveryFromPort();
220 } 217 }
221 - },
222 - new ConfigFactory<DeviceId, FingerprintProbeFromDevice>(DEVICE_SUBJECT_FACTORY,
223 - FingerprintProbeFromDevice.class, FINGERPRINT_FEATURE_NAME) {
224 - @Override
225 - public FingerprintProbeFromDevice createConfig() {
226 - return new FingerprintProbeFromDevice();
227 - }
228 } 218 }
229 ); 219 );
230 220
231 private final InternalConfigListener cfgListener = new InternalConfigListener(); 221 private final InternalConfigListener cfgListener = new InternalConfigListener();
232 222
233 -
234 /** 223 /**
235 * Creates an OpenFlow link provider. 224 * Creates an OpenFlow link provider.
236 */ 225 */
...@@ -238,6 +227,17 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -238,6 +227,17 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
238 super(new ProviderId("lldp", PROVIDER_NAME)); 227 super(new ProviderId("lldp", PROVIDER_NAME));
239 } 228 }
240 229
230 + private final String buildSrcMac() {
231 + String srcMac = ProbedLinkProvider.fingerprintMac(clusterMetadataService.getClusterMetadata());
232 + String defMac = ProbedLinkProvider.defaultMac();
233 + if (srcMac.equals(defMac)) {
234 + log.warn("Couldn't generate fingerprint. Using default value {}", defMac);
235 + return defMac;
236 + }
237 + log.trace("Generated MAC address {}", srcMac);
238 + return srcMac;
239 + }
240 +
241 @Activate 241 @Activate
242 public void activate(ComponentContext context) { 242 public void activate(ComponentContext context) {
243 cfgService.registerProperties(getClass()); 243 cfgService.registerProperties(getClass());
...@@ -404,14 +404,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -404,14 +404,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
404 return isBlacklisted(new ConnectPoint(port.element().id(), port.number())); 404 return isBlacklisted(new ConnectPoint(port.element().id(), port.number()));
405 } 405 }
406 406
407 - private boolean isFingerprinted(DeviceId did) {
408 - FingerprintProbeFromDevice cfg = cfgRegistry.getConfig(did, FingerprintProbeFromDevice.class);
409 - if (cfg == null) {
410 - return false;
411 - }
412 - return cfg.enabled();
413 - }
414 -
415 /** 407 /**
416 * Updates discovery helper for specified device. 408 * Updates discovery helper for specified device.
417 * 409 *
...@@ -433,11 +425,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -433,11 +425,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
433 425
434 LinkDiscovery ld = discoverers.computeIfAbsent(device.id(), 426 LinkDiscovery ld = discoverers.computeIfAbsent(device.id(),
435 did -> new LinkDiscovery(device, context)); 427 did -> new LinkDiscovery(device, context));
436 - if (isFingerprinted(device.id())) {
437 - ld.enableFingerprint();
438 - } else {
439 - ld.disableFingerprint();
440 - }
441 if (ld.isStopped()) { 428 if (ld.isStopped()) {
442 ld.start(); 429 ld.start();
443 } 430 }
...@@ -753,14 +740,13 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -753,14 +740,13 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
753 } 740 }
754 741
755 @Override 742 @Override
756 - public String fingerprint() { 743 + public DeviceService deviceService() {
757 - ClusterMetadata mdata = clusterMetadataService.getClusterMetadata(); 744 + return deviceService;
758 - return mdata == null ? NO_NAME : mdata.getName();
759 } 745 }
760 746
761 @Override 747 @Override
762 - public DeviceService deviceService() { 748 + public String fingerprint() {
763 - return deviceService; 749 + return buildSrcMac();
764 } 750 }
765 } 751 }
766 752
...@@ -808,15 +794,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -808,15 +794,6 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
808 } 794 }
809 } 795 }
810 796
811 - } else if (event.configClass() == FingerprintProbeFromDevice.class &&
812 - CONFIG_CHANGED.contains(event.type())) {
813 -
814 - if (event.subject() instanceof DeviceId) {
815 - final DeviceId did = (DeviceId) event.subject();
816 - Device device = deviceService.getDevice(did);
817 - updateDevice(device);
818 - }
819 -
820 } else if (event.configClass().equals(SuppressionConfig.class) && 797 } else if (event.configClass().equals(SuppressionConfig.class) &&
821 (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || 798 (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
822 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { 799 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) {
......
...@@ -34,6 +34,7 @@ import org.onosproject.net.link.LinkDescription; ...@@ -34,6 +34,7 @@ import org.onosproject.net.link.LinkDescription;
34 import org.onosproject.net.packet.DefaultOutboundPacket; 34 import org.onosproject.net.packet.DefaultOutboundPacket;
35 import org.onosproject.net.packet.OutboundPacket; 35 import org.onosproject.net.packet.OutboundPacket;
36 import org.onosproject.net.packet.PacketContext; 36 import org.onosproject.net.packet.PacketContext;
37 +import org.onosproject.net.link.ProbedLinkProvider;
37 import org.slf4j.Logger; 38 import org.slf4j.Logger;
38 39
39 import java.nio.ByteBuffer; 40 import java.nio.ByteBuffer;
...@@ -43,7 +44,6 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; ...@@ -43,7 +44,6 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS;
43 import static org.onosproject.net.PortNumber.portNumber; 44 import static org.onosproject.net.PortNumber.portNumber;
44 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder; 45 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
45 import static org.slf4j.LoggerFactory.getLogger; 46 import static org.slf4j.LoggerFactory.getLogger;
46 -import static org.onosproject.cluster.ClusterMetadata.NO_NAME;
47 47
48 /** 48 /**
49 * Run discovery process from a physical switch. Ports are initially labeled as 49 * Run discovery process from a physical switch. Ports are initially labeled as
...@@ -56,8 +56,6 @@ public class LinkDiscovery implements TimerTask { ...@@ -56,8 +56,6 @@ public class LinkDiscovery implements TimerTask {
56 56
57 private final Logger log = getLogger(getClass()); 57 private final Logger log = getLogger(getClass());
58 58
59 - private static final String SRC_MAC = "DE:AD:BE:EF:BA:11";
60 -
61 private final Device device; 59 private final Device device;
62 private final LinkDiscoveryContext context; 60 private final LinkDiscoveryContext context;
63 61
...@@ -66,8 +64,6 @@ public class LinkDiscovery implements TimerTask { ...@@ -66,8 +64,6 @@ public class LinkDiscovery implements TimerTask {
66 64
67 private Timeout timeout; 65 private Timeout timeout;
68 private volatile boolean isStopped; 66 private volatile boolean isStopped;
69 - // This LinkDiscovery can handle remote link probes (default false).
70 - private volatile boolean fingerprinted;
71 // Set of ports to be probed 67 // Set of ports to be probed
72 private final Set<Long> ports = Sets.newConcurrentHashSet(); 68 private final Set<Long> ports = Sets.newConcurrentHashSet();
73 69
...@@ -93,7 +89,6 @@ public class LinkDiscovery implements TimerTask { ...@@ -93,7 +89,6 @@ public class LinkDiscovery implements TimerTask {
93 bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST); 89 bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST);
94 bddpEth.setPad(true); 90 bddpEth.setPad(true);
95 91
96 - fingerprinted = false;
97 isStopped = true; 92 isStopped = true;
98 start(); 93 start();
99 log.debug("Started discovery manager for switch {}", device.id()); 94 log.debug("Started discovery manager for switch {}", device.id());
...@@ -160,8 +155,12 @@ public class LinkDiscovery implements TimerTask { ...@@ -160,8 +155,12 @@ public class LinkDiscovery implements TimerTask {
160 155
161 ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth); 156 ONOSLLDP onoslldp = ONOSLLDP.parseONOSLLDP(eth);
162 if (onoslldp != null) { 157 if (onoslldp != null) {
163 - if (notMy(onoslldp)) { 158 + Type lt;
164 - return true; 159 + if (notMy(eth.getSourceMAC().toString())) {
160 + lt = Type.EDGE;
161 + } else {
162 + lt = eth.getEtherType() == Ethernet.TYPE_LLDP ?
163 + Type.DIRECT : Type.INDIRECT;
165 } 164 }
166 165
167 PortNumber srcPort = portNumber(onoslldp.getPort()); 166 PortNumber srcPort = portNumber(onoslldp.getPort());
...@@ -172,10 +171,7 @@ public class LinkDiscovery implements TimerTask { ...@@ -172,10 +171,7 @@ public class LinkDiscovery implements TimerTask {
172 ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort); 171 ConnectPoint src = new ConnectPoint(srcDeviceId, srcPort);
173 ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort); 172 ConnectPoint dst = new ConnectPoint(dstDeviceId, dstPort);
174 173
175 - LinkDescription ld = eth.getEtherType() == Ethernet.TYPE_LLDP ? 174 + LinkDescription ld = new DefaultLinkDescription(src, dst, lt);
176 - new DefaultLinkDescription(src, dst, Type.DIRECT) :
177 - new DefaultLinkDescription(src, dst, Type.INDIRECT);
178 -
179 try { 175 try {
180 context.providerService().linkDetected(ld); 176 context.providerService().linkDetected(ld);
181 context.touchLink(LinkKey.linkKey(src, dst)); 177 context.touchLink(LinkKey.linkKey(src, dst));
...@@ -188,24 +184,13 @@ public class LinkDiscovery implements TimerTask { ...@@ -188,24 +184,13 @@ public class LinkDiscovery implements TimerTask {
188 } 184 }
189 185
190 // true if *NOT* this cluster's own probe. 186 // true if *NOT* this cluster's own probe.
191 - private boolean notMy(ONOSLLDP onoslldp) { 187 + private boolean notMy(String mac) {
192 - if (onoslldp.getDomainTLV() == null) { 188 + // if we are using DEFAULT_MAC, clustering hadn't initialized, so conservative 'yes'
193 - // not finger-printed - but we can check the source 189 + String ourMac = context.fingerprint();
194 - DeviceId src = DeviceId.deviceId(onoslldp.getDeviceString()); 190 + if (ProbedLinkProvider.defaultMac().equalsIgnoreCase(ourMac)) {
195 - if (context.deviceService().getDevice(src) == null) {
196 - return true;
197 - }
198 - return false;
199 - }
200 -
201 - String us = context.fingerprint();
202 - String them = onoslldp.getDomainString();
203 - // if: Our and/or their MetadataService in poorly state, conservative 'yes'
204 - if (NO_NAME.equals(us) || NO_NAME.equals(them)) {
205 return true; 191 return true;
206 - } else {
207 - return !us.equals(them);
208 } 192 }
193 + return !mac.equalsIgnoreCase(ourMac);
209 } 194 }
210 195
211 /** 196 /**
...@@ -242,7 +227,7 @@ public class LinkDiscovery implements TimerTask { ...@@ -242,7 +227,7 @@ public class LinkDiscovery implements TimerTask {
242 return null; 227 return null;
243 } 228 }
244 ONOSLLDP lldp = getLinkProbe(port); 229 ONOSLLDP lldp = getLinkProbe(port);
245 - ethPacket.setSourceMACAddress(SRC_MAC).setPayload(lldp); 230 + ethPacket.setSourceMACAddress(context.fingerprint()).setPayload(lldp);
246 return new DefaultOutboundPacket(device.id(), 231 return new DefaultOutboundPacket(device.id(),
247 builder().setOutput(portNumber(port)).build(), 232 builder().setOutput(portNumber(port)).build(),
248 ByteBuffer.wrap(ethPacket.serialize())); 233 ByteBuffer.wrap(ethPacket.serialize()));
...@@ -259,18 +244,14 @@ public class LinkDiscovery implements TimerTask { ...@@ -259,18 +244,14 @@ public class LinkDiscovery implements TimerTask {
259 return null; 244 return null;
260 } 245 }
261 ONOSLLDP lldp = getLinkProbe(port); 246 ONOSLLDP lldp = getLinkProbe(port);
262 - bddpEth.setSourceMACAddress(SRC_MAC).setPayload(lldp); 247 + bddpEth.setSourceMACAddress(context.fingerprint()).setPayload(lldp);
263 return new DefaultOutboundPacket(device.id(), 248 return new DefaultOutboundPacket(device.id(),
264 builder().setOutput(portNumber(port)).build(), 249 builder().setOutput(portNumber(port)).build(),
265 ByteBuffer.wrap(bddpEth.serialize())); 250 ByteBuffer.wrap(bddpEth.serialize()));
266 } 251 }
267 252
268 private ONOSLLDP getLinkProbe(Long port) { 253 private ONOSLLDP getLinkProbe(Long port) {
269 - return fingerprinted 254 + return ONOSLLDP.onosLLDP(device.id().toString(), device.chassisId(), port.intValue());
270 - ? ONOSLLDP.fingerprintedLLDP(device.id().toString(), device.chassisId(),
271 - port.intValue(), context.fingerprint())
272 - : ONOSLLDP.onosLLDP(device.id().toString(), device.chassisId(),
273 - port.intValue());
274 } 255 }
275 256
276 private void sendProbes(Long portNumber) { 257 private void sendProbes(Long portNumber) {
...@@ -286,12 +267,4 @@ public class LinkDiscovery implements TimerTask { ...@@ -286,12 +267,4 @@ public class LinkDiscovery implements TimerTask {
286 public boolean containsPort(long portNumber) { 267 public boolean containsPort(long portNumber) {
287 return ports.contains(portNumber); 268 return ports.contains(portNumber);
288 } 269 }
289 -
290 - public void enableFingerprint() {
291 - fingerprinted = true;
292 - }
293 -
294 - public void disableFingerprint() {
295 - fingerprinted = false;
296 - }
297 } 270 }
......
...@@ -29,6 +29,7 @@ import org.apache.felix.scr.annotations.Reference; ...@@ -29,6 +29,7 @@ import org.apache.felix.scr.annotations.Reference;
29 import org.apache.felix.scr.annotations.ReferenceCardinality; 29 import org.apache.felix.scr.annotations.ReferenceCardinality;
30 import org.onlab.packet.Ethernet; 30 import org.onlab.packet.Ethernet;
31 import org.onlab.packet.ONOSLLDP; 31 import org.onlab.packet.ONOSLLDP;
32 +import org.onosproject.cluster.ClusterMetadataService;
32 import org.onosproject.core.ApplicationId; 33 import org.onosproject.core.ApplicationId;
33 import org.onosproject.core.CoreService; 34 import org.onosproject.core.CoreService;
34 import org.onosproject.mastership.MastershipService; 35 import org.onosproject.mastership.MastershipService;
...@@ -50,7 +51,7 @@ import org.onosproject.net.device.DeviceService; ...@@ -50,7 +51,7 @@ import org.onosproject.net.device.DeviceService;
50 import org.onosproject.net.flow.DefaultTrafficSelector; 51 import org.onosproject.net.flow.DefaultTrafficSelector;
51 import org.onosproject.net.flow.TrafficSelector; 52 import org.onosproject.net.flow.TrafficSelector;
52 import org.onosproject.net.link.DefaultLinkDescription; 53 import org.onosproject.net.link.DefaultLinkDescription;
53 -import org.onosproject.net.link.LinkProvider; 54 +import org.onosproject.net.link.ProbedLinkProvider;
54 import org.onosproject.net.link.LinkProviderRegistry; 55 import org.onosproject.net.link.LinkProviderRegistry;
55 import org.onosproject.net.link.LinkProviderService; 56 import org.onosproject.net.link.LinkProviderService;
56 import org.onosproject.net.packet.InboundPacket; 57 import org.onosproject.net.packet.InboundPacket;
...@@ -77,7 +78,7 @@ import static org.onosproject.net.PortNumber.portNumber; ...@@ -77,7 +78,7 @@ import static org.onosproject.net.PortNumber.portNumber;
77 @Component(immediate = true) 78 @Component(immediate = true)
78 public class NetworkConfigLinksProvider 79 public class NetworkConfigLinksProvider
79 extends AbstractProvider 80 extends AbstractProvider
80 - implements LinkProvider { 81 + implements ProbedLinkProvider {
81 82
82 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 protected LinkProviderRegistry providerRegistry; 84 protected LinkProviderRegistry providerRegistry;
...@@ -97,6 +98,9 @@ public class NetworkConfigLinksProvider ...@@ -97,6 +98,9 @@ public class NetworkConfigLinksProvider
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected CoreService coreService; 99 protected CoreService coreService;
99 100
101 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 + protected ClusterMetadataService metadataService;
103 +
100 private static final String PROP_PROBE_RATE = "probeRate"; 104 private static final String PROP_PROBE_RATE = "probeRate";
101 private static final int DEFAULT_PROBE_RATE = 3000; 105 private static final int DEFAULT_PROBE_RATE = 3000;
102 @Property(name = PROP_PROBE_RATE, intValue = DEFAULT_PROBE_RATE, 106 @Property(name = PROP_PROBE_RATE, intValue = DEFAULT_PROBE_RATE,
...@@ -125,6 +129,17 @@ public class NetworkConfigLinksProvider ...@@ -125,6 +129,17 @@ public class NetworkConfigLinksProvider
125 super(new ProviderId("lldp", PROVIDER_NAME)); 129 super(new ProviderId("lldp", PROVIDER_NAME));
126 } 130 }
127 131
132 + private final String buildSrcMac() {
133 + String srcMac = ProbedLinkProvider.fingerprintMac(metadataService.getClusterMetadata());
134 + String defMac = ProbedLinkProvider.defaultMac();
135 + if (srcMac.equals(defMac)) {
136 + log.warn("Couldn't generate fingerprint. Using default value {}", defMac);
137 + return defMac;
138 + }
139 + log.trace("Generated MAC address {}", srcMac);
140 + return srcMac;
141 + }
142 +
128 private void createLinks() { 143 private void createLinks() {
129 netCfgService.getSubjects(LinkKey.class) 144 netCfgService.getSubjects(LinkKey.class)
130 .forEach(linkKey -> configuredLinks.add(linkKey)); 145 .forEach(linkKey -> configuredLinks.add(linkKey));
...@@ -240,7 +255,7 @@ public class NetworkConfigLinksProvider ...@@ -240,7 +255,7 @@ public class NetworkConfigLinksProvider
240 255
241 @Override 256 @Override
242 public String fingerprint() { 257 public String fingerprint() {
243 - return ""; 258 + return buildSrcMac();
244 } 259 }
245 260
246 @Override 261 @Override
......
...@@ -24,6 +24,7 @@ import org.junit.Test; ...@@ -24,6 +24,7 @@ import org.junit.Test;
24 import org.onlab.packet.ChassisId; 24 import org.onlab.packet.ChassisId;
25 import org.onlab.packet.Ethernet; 25 import org.onlab.packet.Ethernet;
26 import org.onlab.packet.ONOSLLDP; 26 import org.onlab.packet.ONOSLLDP;
27 +import org.onosproject.cluster.ClusterMetadataServiceAdapter;
27 import org.onosproject.core.CoreServiceAdapter; 28 import org.onosproject.core.CoreServiceAdapter;
28 import org.onosproject.mastership.MastershipServiceAdapter; 29 import org.onosproject.mastership.MastershipServiceAdapter;
29 import org.onosproject.net.ConnectPoint; 30 import org.onosproject.net.ConnectPoint;
...@@ -232,6 +233,7 @@ public class NetworkConfigLinksProviderTest { ...@@ -232,6 +233,7 @@ public class NetworkConfigLinksProviderTest {
232 provider.deviceService = new TestDeviceManager(); 233 provider.deviceService = new TestDeviceManager();
233 provider.masterService = new TestMastershipService(); 234 provider.masterService = new TestMastershipService();
234 provider.packetService = new TestPacketService(); 235 provider.packetService = new TestPacketService();
236 + provider.metadataService = new ClusterMetadataServiceAdapter();
235 provider.netCfgService = configRegistry; 237 provider.netCfgService = configRegistry;
236 238
237 provider.activate(); 239 provider.activate();
......
...@@ -250,24 +250,4 @@ public class ONOSLLDP extends LLDP { ...@@ -250,24 +250,4 @@ public class ONOSLLDP extends LLDP {
250 probe.setChassisId(chassisId); 250 probe.setChassisId(chassisId);
251 return probe; 251 return probe;
252 } 252 }
253 -
254 - /**
255 - * Creates a link probe carrying a fingerprint unique to the ONOS cluster managing
256 - * link discovery/verification.
257 - *
258 - * @param deviceId The device ID as a String
259 - * @param chassisId The chassis ID of the device
260 - * @param portNum Port number of port to send probe out of
261 - * @param domainId The cluster's fingerprint
262 - * @return ONOSLLDP probe message
263 - */
264 - public static ONOSLLDP fingerprintedLLDP(
265 - String deviceId, ChassisId chassisId, int portNum, String domainId) {
266 - ONOSLLDP probe = new ONOSLLDP(NAME_SUBTYPE, DEVICE_SUBTYPE, DOMAIN_SUBTYPE);
267 - probe.setPortId(portNum);
268 - probe.setDevice(deviceId);
269 - probe.setChassisId(chassisId);
270 - probe.setDomainInfo(domainId);
271 - return probe;
272 - }
273 } 253 }
......