Ayaka Koshibe
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
...@@ -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 }
......
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 }
......