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
Showing
8 changed files
with
148 additions
and
120 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment