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