Committed by
Gerrit Code Review
[Falcon] link discovery -
- Support for TLV containing cluster fingerprint info - Config for enabling extra TLV at device level - Refactored ONOSLLDP constructor for ease of use Change-Id: I93abe6c0ed8b7e37c80af5920649272faad8856e
Showing
6 changed files
with
233 additions
and
40 deletions
| ... | @@ -66,4 +66,11 @@ interface DiscoveryContext { | ... | @@ -66,4 +66,11 @@ interface DiscoveryContext { |
| 66 | * @param key link key | 66 | * @param key link key |
| 67 | */ | 67 | */ |
| 68 | void touchLink(LinkKey key); | 68 | void touchLink(LinkKey key); |
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * Returns the cluster-wide unique identifier. | ||
| 72 | + * | ||
| 73 | + * @return the cluster identifier | ||
| 74 | + */ | ||
| 75 | + String fingerprint(); | ||
| 69 | } | 76 | } | ... | ... |
providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/FingerprintProbeFromDevice.java
0 → 100644
| 1 | +package org.onosproject.provider.lldp.impl; | ||
| 2 | + | ||
| 3 | +import org.onosproject.net.DeviceId; | ||
| 4 | +import org.onosproject.net.config.basics.BasicFeatureConfig; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * A feature to send and receive probes carrying a cluster-unique fingerprint. | ||
| 8 | + * Note that, as it leverages LinkDiscovery, disabling linkDiscovery will disable | ||
| 9 | + * this function. | ||
| 10 | + */ | ||
| 11 | +public class FingerprintProbeFromDevice extends BasicFeatureConfig<DeviceId> { | ||
| 12 | + | ||
| 13 | + protected FingerprintProbeFromDevice() { | ||
| 14 | + // default:disabled | ||
| 15 | + super(false); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | +} |
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.Sets; | 18 | import com.google.common.collect.Sets; |
| 19 | + | ||
| 19 | import org.jboss.netty.util.Timeout; | 20 | import org.jboss.netty.util.Timeout; |
| 20 | import org.jboss.netty.util.TimerTask; | 21 | import org.jboss.netty.util.TimerTask; |
| 21 | import org.onlab.packet.Ethernet; | 22 | import org.onlab.packet.Ethernet; |
| ... | @@ -59,13 +60,13 @@ class LinkDiscovery implements TimerTask { | ... | @@ -59,13 +60,13 @@ class LinkDiscovery implements TimerTask { |
| 59 | private final Device device; | 60 | private final Device device; |
| 60 | private final DiscoveryContext context; | 61 | private final DiscoveryContext context; |
| 61 | 62 | ||
| 62 | - private final ONOSLLDP lldpPacket; | ||
| 63 | private final Ethernet ethPacket; | 63 | private final Ethernet ethPacket; |
| 64 | private final Ethernet bddpEth; | 64 | private final Ethernet bddpEth; |
| 65 | 65 | ||
| 66 | private Timeout timeout; | 66 | private Timeout timeout; |
| 67 | private volatile boolean isStopped; | 67 | private volatile boolean isStopped; |
| 68 | - | 68 | + // This LinkDiscovery can handle remote link probes (default false). |
| 69 | + private volatile boolean fingerprinted; | ||
| 69 | // Set of ports to be probed | 70 | // Set of ports to be probed |
| 70 | private final Set<Long> ports = Sets.newConcurrentHashSet(); | 71 | private final Set<Long> ports = Sets.newConcurrentHashSet(); |
| 71 | 72 | ||
| ... | @@ -81,22 +82,17 @@ class LinkDiscovery implements TimerTask { | ... | @@ -81,22 +82,17 @@ class LinkDiscovery implements TimerTask { |
| 81 | this.device = device; | 82 | this.device = device; |
| 82 | this.context = context; | 83 | this.context = context; |
| 83 | 84 | ||
| 84 | - lldpPacket = new ONOSLLDP(); | ||
| 85 | - lldpPacket.setChassisId(device.chassisId()); | ||
| 86 | - lldpPacket.setDevice(device.id().toString()); | ||
| 87 | - | ||
| 88 | ethPacket = new Ethernet(); | 85 | ethPacket = new Ethernet(); |
| 89 | ethPacket.setEtherType(Ethernet.TYPE_LLDP); | 86 | ethPacket.setEtherType(Ethernet.TYPE_LLDP); |
| 90 | ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA); | 87 | ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA); |
| 91 | - ethPacket.setPayload(this.lldpPacket); | ||
| 92 | ethPacket.setPad(true); | 88 | ethPacket.setPad(true); |
| 93 | 89 | ||
| 94 | bddpEth = new Ethernet(); | 90 | bddpEth = new Ethernet(); |
| 95 | - bddpEth.setPayload(lldpPacket); | ||
| 96 | bddpEth.setEtherType(Ethernet.TYPE_BSN); | 91 | bddpEth.setEtherType(Ethernet.TYPE_BSN); |
| 97 | bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST); | 92 | bddpEth.setDestinationMACAddress(ONOSLLDP.BDDP_MULTICAST); |
| 98 | bddpEth.setPad(true); | 93 | bddpEth.setPad(true); |
| 99 | 94 | ||
| 95 | + fingerprinted = false; | ||
| 100 | isStopped = true; | 96 | isStopped = true; |
| 101 | start(); | 97 | start(); |
| 102 | log.debug("Started discovery manager for switch {}", device.id()); | 98 | log.debug("Started discovery manager for switch {}", device.id()); |
| ... | @@ -220,8 +216,8 @@ class LinkDiscovery implements TimerTask { | ... | @@ -220,8 +216,8 @@ class LinkDiscovery implements TimerTask { |
| 220 | if (port == null) { | 216 | if (port == null) { |
| 221 | return null; | 217 | return null; |
| 222 | } | 218 | } |
| 223 | - lldpPacket.setPortId(port.intValue()); | 219 | + ONOSLLDP lldp = getLinkProbe(port); |
| 224 | - ethPacket.setSourceMACAddress(SRC_MAC); | 220 | + ethPacket.setSourceMACAddress(SRC_MAC).setPayload(lldp); |
| 225 | return new DefaultOutboundPacket(device.id(), | 221 | return new DefaultOutboundPacket(device.id(), |
| 226 | builder().setOutput(portNumber(port)).build(), | 222 | builder().setOutput(portNumber(port)).build(), |
| 227 | ByteBuffer.wrap(ethPacket.serialize())); | 223 | ByteBuffer.wrap(ethPacket.serialize())); |
| ... | @@ -237,13 +233,21 @@ class LinkDiscovery implements TimerTask { | ... | @@ -237,13 +233,21 @@ class LinkDiscovery implements TimerTask { |
| 237 | if (port == null) { | 233 | if (port == null) { |
| 238 | return null; | 234 | return null; |
| 239 | } | 235 | } |
| 240 | - lldpPacket.setPortId(port.intValue()); | 236 | + ONOSLLDP lldp = getLinkProbe(port); |
| 241 | - bddpEth.setSourceMACAddress(SRC_MAC); | 237 | + bddpEth.setSourceMACAddress(SRC_MAC).setPayload(lldp); |
| 242 | return new DefaultOutboundPacket(device.id(), | 238 | return new DefaultOutboundPacket(device.id(), |
| 243 | builder().setOutput(portNumber(port)).build(), | 239 | builder().setOutput(portNumber(port)).build(), |
| 244 | ByteBuffer.wrap(bddpEth.serialize())); | 240 | ByteBuffer.wrap(bddpEth.serialize())); |
| 245 | } | 241 | } |
| 246 | 242 | ||
| 243 | + private ONOSLLDP getLinkProbe(Long port) { | ||
| 244 | + return fingerprinted | ||
| 245 | + ? ONOSLLDP.fingerprintedLLDP(device.id().toString(), device.chassisId(), | ||
| 246 | + port.intValue(), context.fingerprint()) | ||
| 247 | + : ONOSLLDP.onosLLDP(device.id().toString(), device.chassisId(), | ||
| 248 | + port.intValue()); | ||
| 249 | + } | ||
| 250 | + | ||
| 247 | private void sendProbes(Long portNumber) { | 251 | private void sendProbes(Long portNumber) { |
| 248 | log.trace("Sending probes out to {}@{}", portNumber, device.id()); | 252 | log.trace("Sending probes out to {}@{}", portNumber, device.id()); |
| 249 | OutboundPacket pkt = createOutBoundLldp(portNumber); | 253 | OutboundPacket pkt = createOutBoundLldp(portNumber); |
| ... | @@ -258,4 +262,11 @@ class LinkDiscovery implements TimerTask { | ... | @@ -258,4 +262,11 @@ class LinkDiscovery implements TimerTask { |
| 258 | return ports.contains(portNumber); | 262 | return ports.contains(portNumber); |
| 259 | } | 263 | } |
| 260 | 264 | ||
| 265 | + protected void enableFingerprint() { | ||
| 266 | + fingerprinted = true; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + protected void disableFingerprint() { | ||
| 270 | + fingerprinted = false; | ||
| 271 | + } | ||
| 261 | } | 272 | } | ... | ... |
| ... | @@ -47,6 +47,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -47,6 +47,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 47 | import org.onlab.packet.Ethernet; | 47 | import org.onlab.packet.Ethernet; |
| 48 | import org.onlab.util.Tools; | 48 | import org.onlab.util.Tools; |
| 49 | import org.onosproject.cfg.ComponentConfigService; | 49 | import org.onosproject.cfg.ComponentConfigService; |
| 50 | +import org.onosproject.cluster.ClusterMetadataService; | ||
| 50 | import org.onosproject.cluster.ClusterService; | 51 | import org.onosproject.cluster.ClusterService; |
| 51 | import org.onosproject.core.ApplicationId; | 52 | import org.onosproject.core.ApplicationId; |
| 52 | import org.onosproject.core.CoreService; | 53 | import org.onosproject.core.CoreService; |
| ... | @@ -133,6 +134,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -133,6 +134,9 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 133 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 134 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 134 | protected NetworkConfigRegistry cfgRegistry; | 135 | protected NetworkConfigRegistry cfgRegistry; |
| 135 | 136 | ||
| 137 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 138 | + protected ClusterMetadataService clusterMetadataService; | ||
| 139 | + | ||
| 136 | private LinkProviderService providerService; | 140 | private LinkProviderService providerService; |
| 137 | 141 | ||
| 138 | private ScheduledExecutorService executor; | 142 | private ScheduledExecutorService executor; |
| ... | @@ -185,6 +189,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -185,6 +189,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 185 | 189 | ||
| 186 | public static final String CONFIG_KEY = "suppression"; | 190 | public static final String CONFIG_KEY = "suppression"; |
| 187 | public static final String FEATURE_NAME = "linkDiscovery"; | 191 | public static final String FEATURE_NAME = "linkDiscovery"; |
| 192 | + public static final String FINGERPRINT_FEATURE_NAME = "fingerprint"; | ||
| 188 | 193 | ||
| 189 | private final Set<ConfigFactory<?, ?>> factories = ImmutableSet.of( | 194 | private final Set<ConfigFactory<?, ?>> factories = ImmutableSet.of( |
| 190 | new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY, | 195 | new ConfigFactory<ApplicationId, SuppressionConfig>(APP_SUBJECT_FACTORY, |
| ... | @@ -208,6 +213,13 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -208,6 +213,13 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 208 | public LinkDiscoveryFromPort createConfig() { | 213 | public LinkDiscoveryFromPort createConfig() { |
| 209 | return new LinkDiscoveryFromPort(); | 214 | return new LinkDiscoveryFromPort(); |
| 210 | } | 215 | } |
| 216 | + }, | ||
| 217 | + new ConfigFactory<DeviceId, FingerprintProbeFromDevice>(DEVICE_SUBJECT_FACTORY, | ||
| 218 | + FingerprintProbeFromDevice.class, FINGERPRINT_FEATURE_NAME) { | ||
| 219 | + @Override | ||
| 220 | + public FingerprintProbeFromDevice createConfig() { | ||
| 221 | + return new FingerprintProbeFromDevice(); | ||
| 222 | + } | ||
| 211 | } | 223 | } |
| 212 | ); | 224 | ); |
| 213 | 225 | ||
| ... | @@ -385,6 +397,14 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -385,6 +397,14 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 385 | return isBlacklisted(new ConnectPoint(port.element().id(), port.number())); | 397 | return isBlacklisted(new ConnectPoint(port.element().id(), port.number())); |
| 386 | } | 398 | } |
| 387 | 399 | ||
| 400 | + private boolean isFingerprinted(DeviceId did) { | ||
| 401 | + FingerprintProbeFromDevice cfg = cfgRegistry.getConfig(did, FingerprintProbeFromDevice.class); | ||
| 402 | + if (cfg == null) { | ||
| 403 | + return false; | ||
| 404 | + } | ||
| 405 | + return cfg.enabled(); | ||
| 406 | + } | ||
| 407 | + | ||
| 388 | /** | 408 | /** |
| 389 | * Updates discovery helper for specified device. | 409 | * Updates discovery helper for specified device. |
| 390 | * | 410 | * |
| ... | @@ -405,6 +425,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -405,6 +425,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 405 | } | 425 | } |
| 406 | LinkDiscovery ld = discoverers.computeIfAbsent(device.id(), | 426 | LinkDiscovery ld = discoverers.computeIfAbsent(device.id(), |
| 407 | did -> new LinkDiscovery(device, context)); | 427 | did -> new LinkDiscovery(device, context)); |
| 428 | + if (isFingerprinted(device.id())) { | ||
| 429 | + ld.enableFingerprint(); | ||
| 430 | + } else { | ||
| 431 | + ld.disableFingerprint(); | ||
| 432 | + } | ||
| 408 | if (ld.isStopped()) { | 433 | if (ld.isStopped()) { |
| 409 | ld.start(); | 434 | ld.start(); |
| 410 | } | 435 | } |
| ... | @@ -715,6 +740,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -715,6 +740,11 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 715 | public void touchLink(LinkKey key) { | 740 | public void touchLink(LinkKey key) { |
| 716 | linkTimes.put(key, System.currentTimeMillis()); | 741 | linkTimes.put(key, System.currentTimeMillis()); |
| 717 | } | 742 | } |
| 743 | + | ||
| 744 | + @Override | ||
| 745 | + public String fingerprint() { | ||
| 746 | + return clusterMetadataService.getClusterMetadata().getName(); | ||
| 747 | + } | ||
| 718 | } | 748 | } |
| 719 | 749 | ||
| 720 | static final EnumSet<NetworkConfigEvent.Type> CONFIG_CHANGED | 750 | static final EnumSet<NetworkConfigEvent.Type> CONFIG_CHANGED |
| ... | @@ -760,6 +790,15 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { | ... | @@ -760,6 +790,15 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider { |
| 760 | } | 790 | } |
| 761 | } | 791 | } |
| 762 | 792 | ||
| 793 | + } else if (event.configClass() == FingerprintProbeFromDevice.class && | ||
| 794 | + CONFIG_CHANGED.contains(event.type())) { | ||
| 795 | + | ||
| 796 | + if (event.subject() instanceof DeviceId) { | ||
| 797 | + final DeviceId did = (DeviceId) event.subject(); | ||
| 798 | + Device device = deviceService.getDevice(did); | ||
| 799 | + updateDevice(device); | ||
| 800 | + } | ||
| 801 | + | ||
| 763 | } else if (event.configClass().equals(SuppressionConfig.class) && | 802 | } else if (event.configClass().equals(SuppressionConfig.class) && |
| 764 | (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | 803 | (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || |
| 765 | event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { | 804 | event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { | ... | ... |
| ... | @@ -21,14 +21,22 @@ import com.google.common.collect.ImmutableMap; | ... | @@ -21,14 +21,22 @@ import com.google.common.collect.ImmutableMap; |
| 21 | import com.google.common.collect.ImmutableSet; | 21 | import com.google.common.collect.ImmutableSet; |
| 22 | import com.google.common.collect.Lists; | 22 | import com.google.common.collect.Lists; |
| 23 | import com.google.common.collect.Maps; | 23 | import com.google.common.collect.Maps; |
| 24 | +import com.google.common.collect.Sets; | ||
| 25 | + | ||
| 24 | import org.junit.After; | 26 | import org.junit.After; |
| 25 | import org.junit.Before; | 27 | import org.junit.Before; |
| 26 | import org.junit.Test; | 28 | import org.junit.Test; |
| 27 | import org.onlab.packet.ChassisId; | 29 | import org.onlab.packet.ChassisId; |
| 28 | import org.onlab.packet.Ethernet; | 30 | import org.onlab.packet.Ethernet; |
| 31 | +import org.onlab.packet.IpAddress; | ||
| 29 | import org.onlab.packet.ONOSLLDP; | 32 | import org.onlab.packet.ONOSLLDP; |
| 30 | import org.onosproject.cfg.ComponentConfigAdapter; | 33 | import org.onosproject.cfg.ComponentConfigAdapter; |
| 34 | +import org.onosproject.cluster.ClusterMetadata; | ||
| 35 | +import org.onosproject.cluster.ClusterMetadataService; | ||
| 36 | +import org.onosproject.cluster.ControllerNode; | ||
| 37 | +import org.onosproject.cluster.DefaultControllerNode; | ||
| 31 | import org.onosproject.cluster.NodeId; | 38 | import org.onosproject.cluster.NodeId; |
| 39 | +import org.onosproject.cluster.Partition; | ||
| 32 | import org.onosproject.cluster.RoleInfo; | 40 | import org.onosproject.cluster.RoleInfo; |
| 33 | import org.onosproject.core.ApplicationId; | 41 | import org.onosproject.core.ApplicationId; |
| 34 | import org.onosproject.core.CoreService; | 42 | import org.onosproject.core.CoreService; |
| ... | @@ -80,7 +88,6 @@ import java.util.concurrent.CompletableFuture; | ... | @@ -80,7 +88,6 @@ import java.util.concurrent.CompletableFuture; |
| 80 | import static org.easymock.EasyMock.createMock; | 88 | import static org.easymock.EasyMock.createMock; |
| 81 | import static org.easymock.EasyMock.expect; | 89 | import static org.easymock.EasyMock.expect; |
| 82 | import static org.easymock.EasyMock.replay; | 90 | import static org.easymock.EasyMock.replay; |
| 83 | - | ||
| 84 | import static org.junit.Assert.assertNull; | 91 | import static org.junit.Assert.assertNull; |
| 85 | import static org.junit.Assert.assertNotNull; | 92 | import static org.junit.Assert.assertNotNull; |
| 86 | import static org.junit.Assert.assertEquals; | 93 | import static org.junit.Assert.assertEquals; |
| ... | @@ -143,7 +150,7 @@ public class LldpLinkProviderTest { | ... | @@ -143,7 +150,7 @@ public class LldpLinkProviderTest { |
| 143 | provider.packetService = packetService; | 150 | provider.packetService = packetService; |
| 144 | provider.providerRegistry = linkRegistry; | 151 | provider.providerRegistry = linkRegistry; |
| 145 | provider.masterService = masterService; | 152 | provider.masterService = masterService; |
| 146 | - | 153 | + provider.clusterMetadataService = new TestMetadataService(); |
| 147 | provider.activate(null); | 154 | provider.activate(null); |
| 148 | } | 155 | } |
| 149 | 156 | ||
| ... | @@ -696,11 +703,9 @@ public class LldpLinkProviderTest { | ... | @@ -696,11 +703,9 @@ public class LldpLinkProviderTest { |
| 696 | 703 | ||
| 697 | @Override | 704 | @Override |
| 698 | public InboundPacket inPacket() { | 705 | public InboundPacket inPacket() { |
| 699 | - ONOSLLDP lldp = new ONOSLLDP(); | 706 | + ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(), |
| 700 | - lldp.setChassisId(device.chassisId()); | 707 | + device.chassisId(), |
| 701 | - lldp.setPortId((int) pd1.number().toLong()); | 708 | + (int) pd1.number().toLong()); |
| 702 | - lldp.setDevice(deviceService.getDevice(DID1).id().toString()); | ||
| 703 | - | ||
| 704 | 709 | ||
| 705 | Ethernet ethPacket = new Ethernet(); | 710 | Ethernet ethPacket = new Ethernet(); |
| 706 | ethPacket.setEtherType(Ethernet.TYPE_LLDP); | 711 | ethPacket.setEtherType(Ethernet.TYPE_LLDP); |
| ... | @@ -708,8 +713,6 @@ public class LldpLinkProviderTest { | ... | @@ -708,8 +713,6 @@ public class LldpLinkProviderTest { |
| 708 | ethPacket.setPayload(lldp); | 713 | ethPacket.setPayload(lldp); |
| 709 | ethPacket.setPad(true); | 714 | ethPacket.setPad(true); |
| 710 | 715 | ||
| 711 | - | ||
| 712 | - | ||
| 713 | ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11"); | 716 | ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11"); |
| 714 | 717 | ||
| 715 | ConnectPoint cp = new ConnectPoint(device.id(), pd3.number()); | 718 | ConnectPoint cp = new ConnectPoint(device.id(), pd3.number()); |
| ... | @@ -941,4 +944,26 @@ public class LldpLinkProviderTest { | ... | @@ -941,4 +944,26 @@ public class LldpLinkProviderTest { |
| 941 | return this; | 944 | return this; |
| 942 | } | 945 | } |
| 943 | } | 946 | } |
| 947 | + | ||
| 948 | + private final class TestMetadataService implements ClusterMetadataService { | ||
| 949 | + @Override | ||
| 950 | + public ClusterMetadata getClusterMetadata() { | ||
| 951 | + final NodeId nid = new NodeId("test-node"); | ||
| 952 | + final IpAddress addr = IpAddress.valueOf(0); | ||
| 953 | + final Partition p = new Partition("test-pt", Sets.newHashSet(nid)); | ||
| 954 | + return ClusterMetadata.builder() | ||
| 955 | + .withName("test-cluster") | ||
| 956 | + .withControllerNodes(Sets.newHashSet(new DefaultControllerNode(nid, addr))) | ||
| 957 | + .withPartitions(Sets.newHashSet(p)).build(); | ||
| 958 | + } | ||
| 959 | + | ||
| 960 | + @Override | ||
| 961 | + public void setClusterMetadata(ClusterMetadata metadata) { | ||
| 962 | + } | ||
| 963 | + | ||
| 964 | + @Override | ||
| 965 | + public ControllerNode getLocalNode() { | ||
| 966 | + return null; | ||
| 967 | + } | ||
| 968 | + } | ||
| 944 | } | 969 | } | ... | ... |
| ... | @@ -15,14 +15,21 @@ | ... | @@ -15,14 +15,21 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onlab.packet; | 16 | package org.onlab.packet; |
| 17 | 17 | ||
| 18 | +import java.util.HashMap; | ||
| 19 | + | ||
| 18 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
| 21 | +import com.google.common.collect.Maps; | ||
| 22 | + | ||
| 19 | import org.apache.commons.lang.ArrayUtils; | 23 | import org.apache.commons.lang.ArrayUtils; |
| 20 | 24 | ||
| 21 | import java.nio.ByteBuffer; | 25 | import java.nio.ByteBuffer; |
| 22 | import java.nio.charset.StandardCharsets; | 26 | import java.nio.charset.StandardCharsets; |
| 23 | 27 | ||
| 28 | +import static org.onlab.packet.LLDPOrganizationalTLV.OUI_LENGTH; | ||
| 29 | +import static org.onlab.packet.LLDPOrganizationalTLV.SUBTYPE_LENGTH; | ||
| 30 | + | ||
| 24 | /** | 31 | /** |
| 25 | - * ONOS LLDP containing organizational TLV for ONOS device dicovery. | 32 | + * ONOS LLDP containing organizational TLV for ONOS device discovery. |
| 26 | */ | 33 | */ |
| 27 | public class ONOSLLDP extends LLDP { | 34 | public class ONOSLLDP extends LLDP { |
| 28 | 35 | ||
| ... | @@ -37,12 +44,16 @@ public class ONOSLLDP extends LLDP { | ... | @@ -37,12 +44,16 @@ public class ONOSLLDP extends LLDP { |
| 37 | public static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff, | 44 | public static final byte[] BDDP_MULTICAST = {(byte) 0xff, (byte) 0xff, |
| 38 | (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; | 45 | (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; |
| 39 | 46 | ||
| 40 | - private static final byte NAME_SUBTYPE = 1; | 47 | + protected static final byte NAME_SUBTYPE = 1; |
| 41 | - private static final byte DEVICE_SUBTYPE = 2; | 48 | + protected static final byte DEVICE_SUBTYPE = 2; |
| 42 | - private static final short NAME_LENGTH = 4; //1 for subtype + 3 for OUI | 49 | + protected static final byte DOMAIN_SUBTYPE = 3; |
| 43 | - private static final short DEVICE_LENGTH = 4; //1 for subtype + 3 for OUI | 50 | + |
| 44 | - private final LLDPOrganizationalTLV nameTLV = new LLDPOrganizationalTLV(); | 51 | + private static final short NAME_LENGTH = OUI_LENGTH + SUBTYPE_LENGTH; |
| 45 | - private final LLDPOrganizationalTLV deviceTLV = new LLDPOrganizationalTLV(); | 52 | + private static final short DEVICE_LENGTH = OUI_LENGTH + SUBTYPE_LENGTH; |
| 53 | + private static final short DOMAIN_LENGTH = OUI_LENGTH + SUBTYPE_LENGTH; | ||
| 54 | + | ||
| 55 | + private final HashMap<Byte, LLDPOrganizationalTLV> opttlvs = | ||
| 56 | + Maps.<Byte, LLDPOrganizationalTLV>newHashMap(); | ||
| 46 | 57 | ||
| 47 | // TLV constants: type, size and subtype | 58 | // TLV constants: type, size and subtype |
| 48 | // Organizationally specific TLV also have packet offset and contents of TLV | 59 | // Organizationally specific TLV also have packet offset and contents of TLV |
| ... | @@ -57,18 +68,24 @@ public class ONOSLLDP extends LLDP { | ... | @@ -57,18 +68,24 @@ public class ONOSLLDP extends LLDP { |
| 57 | 68 | ||
| 58 | private static final byte TTL_TLV_TYPE = 3; | 69 | private static final byte TTL_TLV_TYPE = 3; |
| 59 | 70 | ||
| 60 | - | ||
| 61 | private final byte[] ttlValue = new byte[] {0, 0x78}; | 71 | private final byte[] ttlValue = new byte[] {0, 0x78}; |
| 62 | 72 | ||
| 63 | - public ONOSLLDP() { | 73 | + // Only needs to be accessed from LinkProbeFactory. |
| 74 | + protected ONOSLLDP(byte ... subtype) { | ||
| 64 | super(); | 75 | super(); |
| 76 | + for (byte st : subtype) { | ||
| 77 | + opttlvs.put(st, new LLDPOrganizationalTLV()); | ||
| 78 | + } | ||
| 79 | + // guarantee the following (name and device) TLVs exist | ||
| 80 | + opttlvs.putIfAbsent(NAME_SUBTYPE, new LLDPOrganizationalTLV()); | ||
| 81 | + opttlvs.putIfAbsent(DEVICE_SUBTYPE, new LLDPOrganizationalTLV()); | ||
| 65 | setName(DEFAULT_NAME); | 82 | setName(DEFAULT_NAME); |
| 66 | setDevice(DEFAULT_DEVICE); | 83 | setDevice(DEFAULT_DEVICE); |
| 67 | - setOptionalTLVList(Lists.<LLDPTLV>newArrayList(nameTLV, deviceTLV)); | 84 | + |
| 85 | + setOptionalTLVList(Lists.<LLDPTLV>newArrayList(opttlvs.values())); | ||
| 68 | setTtl(new LLDPTLV().setType(TTL_TLV_TYPE) | 86 | setTtl(new LLDPTLV().setType(TTL_TLV_TYPE) |
| 69 | .setLength((short) ttlValue.length) | 87 | .setLength((short) ttlValue.length) |
| 70 | .setValue(ttlValue)); | 88 | .setValue(ttlValue)); |
| 71 | - | ||
| 72 | } | 89 | } |
| 73 | 90 | ||
| 74 | private ONOSLLDP(LLDP lldp) { | 91 | private ONOSLLDP(LLDP lldp) { |
| ... | @@ -79,17 +96,31 @@ public class ONOSLLDP extends LLDP { | ... | @@ -79,17 +96,31 @@ public class ONOSLLDP extends LLDP { |
| 79 | } | 96 | } |
| 80 | 97 | ||
| 81 | public void setName(String name) { | 98 | public void setName(String name) { |
| 82 | - nameTLV.setLength((short) (name.length() + NAME_LENGTH)); | 99 | + LLDPOrganizationalTLV nametlv = opttlvs.get(NAME_SUBTYPE); |
| 83 | - nameTLV.setInfoString(name); | 100 | + nametlv.setLength((short) (name.length() + NAME_LENGTH)); |
| 84 | - nameTLV.setSubType(NAME_SUBTYPE); | 101 | + nametlv.setInfoString(name); |
| 85 | - nameTLV.setOUI(ONLAB_OUI); | 102 | + nametlv.setSubType(NAME_SUBTYPE); |
| 103 | + nametlv.setOUI(ONLAB_OUI); | ||
| 86 | } | 104 | } |
| 87 | 105 | ||
| 88 | public void setDevice(String device) { | 106 | public void setDevice(String device) { |
| 89 | - deviceTLV.setInfoString(device); | 107 | + LLDPOrganizationalTLV devicetlv = opttlvs.get(DEVICE_SUBTYPE); |
| 90 | - deviceTLV.setLength((short) (device.length() + DEVICE_LENGTH)); | 108 | + devicetlv.setInfoString(device); |
| 91 | - deviceTLV.setSubType(DEVICE_SUBTYPE); | 109 | + devicetlv.setLength((short) (device.length() + DEVICE_LENGTH)); |
| 92 | - deviceTLV.setOUI(ONLAB_OUI); | 110 | + devicetlv.setSubType(DEVICE_SUBTYPE); |
| 111 | + devicetlv.setOUI(ONLAB_OUI); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + public void setDomainInfo(String domainId) { | ||
| 115 | + LLDPOrganizationalTLV domaintlv = opttlvs.get(DOMAIN_SUBTYPE); | ||
| 116 | + if (domaintlv == null) { | ||
| 117 | + // maybe warn people not to set this if remote probes aren't. | ||
| 118 | + return; | ||
| 119 | + } | ||
| 120 | + domaintlv.setInfoString(domainId); | ||
| 121 | + domaintlv.setLength((short) (domainId.length() + DOMAIN_LENGTH)); | ||
| 122 | + domaintlv.setSubType(DOMAIN_SUBTYPE); | ||
| 123 | + domaintlv.setOUI(ONLAB_OUI); | ||
| 93 | } | 124 | } |
| 94 | 125 | ||
| 95 | public void setChassisId(final ChassisId chassisId) { | 126 | public void setChassisId(final ChassisId chassisId) { |
| ... | @@ -139,6 +170,24 @@ public class ONOSLLDP extends LLDP { | ... | @@ -139,6 +170,24 @@ public class ONOSLLDP extends LLDP { |
| 139 | return null; | 170 | return null; |
| 140 | } | 171 | } |
| 141 | 172 | ||
| 173 | + /** | ||
| 174 | + * Gets the TLV associated with remote probing. This TLV will be null if | ||
| 175 | + * remote probing is disabled. | ||
| 176 | + * | ||
| 177 | + * @return A TLV containing domain ID, or null. | ||
| 178 | + */ | ||
| 179 | + public LLDPOrganizationalTLV getDomainTLV() { | ||
| 180 | + for (LLDPTLV tlv : this.getOptionalTLVList()) { | ||
| 181 | + if (tlv.getType() == LLDPOrganizationalTLV.ORGANIZATIONAL_TLV_TYPE) { | ||
| 182 | + LLDPOrganizationalTLV orgTLV = (LLDPOrganizationalTLV) tlv; | ||
| 183 | + if (orgTLV.getSubType() == DOMAIN_SUBTYPE) { | ||
| 184 | + return orgTLV; | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + } | ||
| 188 | + return null; | ||
| 189 | + } | ||
| 190 | + | ||
| 142 | public String getNameString() { | 191 | public String getNameString() { |
| 143 | LLDPOrganizationalTLV tlv = getNameTLV(); | 192 | LLDPOrganizationalTLV tlv = getNameTLV(); |
| 144 | if (tlv != null) { | 193 | if (tlv != null) { |
| ... | @@ -155,6 +204,14 @@ public class ONOSLLDP extends LLDP { | ... | @@ -155,6 +204,14 @@ public class ONOSLLDP extends LLDP { |
| 155 | return null; | 204 | return null; |
| 156 | } | 205 | } |
| 157 | 206 | ||
| 207 | + public String getDomainString() { | ||
| 208 | + LLDPOrganizationalTLV tlv = getDomainTLV(); | ||
| 209 | + if (tlv != null) { | ||
| 210 | + return new String(tlv.getInfoString(), StandardCharsets.UTF_8); | ||
| 211 | + } | ||
| 212 | + return null; | ||
| 213 | + } | ||
| 214 | + | ||
| 158 | public Integer getPort() { | 215 | public Integer getPort() { |
| 159 | ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue()); | 216 | ByteBuffer portBB = ByteBuffer.wrap(this.getPortId().getValue()); |
| 160 | portBB.position(1); | 217 | portBB.position(1); |
| ... | @@ -177,4 +234,40 @@ public class ONOSLLDP extends LLDP { | ... | @@ -177,4 +234,40 @@ public class ONOSLLDP extends LLDP { |
| 177 | } | 234 | } |
| 178 | return null; | 235 | return null; |
| 179 | } | 236 | } |
| 237 | + | ||
| 238 | + /** | ||
| 239 | + * Creates a link probe for link discovery/verification. | ||
| 240 | + * | ||
| 241 | + * @param deviceId The device ID as a String | ||
| 242 | + * @param chassisId The chassis ID of the device | ||
| 243 | + * @param portNum Port number of port to send probe out of | ||
| 244 | + * @return ONOSLLDP probe message | ||
| 245 | + */ | ||
| 246 | + public static ONOSLLDP onosLLDP(String deviceId, ChassisId chassisId, int portNum) { | ||
| 247 | + ONOSLLDP probe = new ONOSLLDP(NAME_SUBTYPE, DEVICE_SUBTYPE); | ||
| 248 | + probe.setPortId(portNum); | ||
| 249 | + probe.setDevice(deviceId); | ||
| 250 | + probe.setChassisId(chassisId); | ||
| 251 | + return probe; | ||
| 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 | + } | ||
| 180 | } | 273 | } | ... | ... |
-
Please register or login to post a comment