Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
diff --git a/net/api/src/main/java/org/onlab/onos/net/ConnectPoint.java b/net/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
index f870698..8f332e9 100644
--- a/net/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
+++ b/net/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
@@ -2,7 +2,7 @@
import java.util.Objects;
-import static com.google.common.base.MoreObjects.toStringHelper;
+import com.google.common.base.MoreObjects;
/**
* Abstraction of a network connection point expressed as a pair of the
@@ -42,13 +42,12 @@
* @throws java.lang.IllegalStateException if connection point is not
* associated with a device
*/
- @SuppressWarnings("unchecked")
public DeviceId deviceId() {
if (elementId instanceof DeviceId) {
return (DeviceId) elementId;
}
throw new IllegalStateException("Connection point not associated " +
- "with an infrastructure device");
+ "with an infrastructure device");
}
/**
@@ -77,7 +76,7 @@
@Override
public String toString() {
- return toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("elementId", elementId)
.add("portNumber", portNumber)
.toString();
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
index c7b56c0..88d0663 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
@@ -1,6 +1,10 @@
package org.onlab.onos.net.trivial.impl;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Set;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -24,10 +28,7 @@
import org.onlab.onos.net.provider.AbstractProviderService;
import org.slf4j.Logger;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
+import com.google.common.collect.Sets;
/**
* Provides basic implementation of the link SB & NB APIs.
@@ -35,8 +36,8 @@
@Component(immediate = true)
@Service
public class SimpleLinkManager
- extends AbstractProviderRegistry<LinkProvider, LinkProviderService>
- implements LinkService, LinkAdminService, LinkProviderRegistry {
+extends AbstractProviderRegistry<LinkProvider, LinkProviderService>
+implements LinkService, LinkAdminService, LinkProviderRegistry {
private static final String DEVICE_ID_NULL = "Device ID cannot be null";
private static final String LINK_DESC_NULL = "Link description cannot be null";
@@ -45,7 +46,7 @@
private final Logger log = getLogger(getClass());
private final AbstractListenerRegistry<LinkEvent, LinkListener>
- listenerRegistry = new AbstractListenerRegistry<>();
+ listenerRegistry = new AbstractListenerRegistry<>();
private final SimpleLinkStore store = new SimpleLinkStore();
@@ -83,7 +84,7 @@
public Set<Link> getDeviceLinks(DeviceId deviceId) {
checkNotNull(deviceId, DEVICE_ID_NULL);
return Sets.union(store.getDeviceEgressLinks(deviceId),
- store.getDeviceIngressLinks(deviceId));
+ store.getDeviceIngressLinks(deviceId));
}
@Override
@@ -102,7 +103,7 @@
public Set<Link> getLinks(ConnectPoint connectPoint) {
checkNotNull(connectPoint, CONNECT_POINT_NULL);
return Sets.union(store.getEgressLinks(connectPoint),
- store.getIngressLinks(connectPoint));
+ store.getIngressLinks(connectPoint));
}
@Override
@@ -146,7 +147,7 @@
// Personalized link provider service issued to the supplied provider.
private class InternalLinkProviderService extends AbstractProviderService<LinkProvider>
- implements LinkProviderService {
+ implements LinkProviderService {
InternalLinkProviderService(LinkProvider provider) {
super(provider);
@@ -156,9 +157,9 @@
public void linkDetected(LinkDescription linkDescription) {
checkNotNull(linkDescription, LINK_DESC_NULL);
checkValidity();
- log.info("Link {} detected", linkDescription);
+ log.debug("Link {} detected", linkDescription);
LinkEvent event = store.createOrUpdateLink(provider().id(),
- linkDescription);
+ linkDescription);
post(event);
}
@@ -168,7 +169,7 @@
checkValidity();
log.info("Link {} vanished", linkDescription);
LinkEvent event = store.removeLink(linkDescription.src(),
- linkDescription.dst());
+ linkDescription.dst());
post(event);
}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java
index 41c8adc..7ad2fec 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java
@@ -1,8 +1,12 @@
package org.onlab.onos.of.controller;
+import java.util.Collections;
+
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
public final class DefaultPacketContext implements PacketContext {
@@ -11,7 +15,7 @@
private boolean isBuilt = false;
private final OpenFlowSwitch sw;
private final OFPacketIn pktin;
- private final OFPacketOut pktout = null;
+ private OFPacketOut pktout = null;
private DefaultPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
this.sw = s;
@@ -39,24 +43,41 @@
@Override
public void build(Ethernet ethFrame, OFPort outPort) {
- // TODO Auto-generated method stub
-
+ if (isBuilt) {
+ return;
+ }
+ OFPacketOut.Builder builder = sw.factory().buildPacketOut();
+ OFAction act = sw.factory().actions()
+ .buildOutput()
+ .setPort(OFPort.of(outPort.getPortNumber()))
+ .build();
+ pktout = builder.setXid(pktin.getXid())
+ .setBufferId(OFBufferId.NO_BUFFER)
+ .setActions(Collections.singletonList(act))
+ .setData(ethFrame.serialize())
+ .build();
+ isBuilt = true;
}
@Override
public Ethernet parsed() {
- // TODO Auto-generated method stub
- return null;
+ Ethernet eth = new Ethernet();
+ eth.deserialize(pktin.getData(), 0, pktin.getTotalLen());
+ return eth;
}
@Override
public Dpid dpid() {
- // TODO Auto-generated method stub
- return null;
+ return new Dpid(sw.getId());
}
public static PacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
return new DefaultPacketContext(s, pkt);
}
+ @Override
+ public Integer inPort() {
+ return pktin.getInPort().getPortNumber();
+ }
+
}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
index f7d434d..c4f785e 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
@@ -48,4 +48,10 @@
* @return the dpid of the switch.
*/
public Dpid dpid();
+
+ /**
+ * Provide the port on which the packet arrived.
+ * @return the port
+ */
+ public Integer inPort();
}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OFChannelHandler.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OFChannelHandler.java
index 8af45e1..c85eb21 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OFChannelHandler.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OFChannelHandler.java
@@ -415,12 +415,14 @@
OFDescStatsReply drep = (OFDescStatsReply) m;
// Here is where we differentiate between different kinds of switches
h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
+
h.sw.setOFVersion(h.ofVersion);
h.sw.setFeaturesReply(h.featuresReply);
h.sw.setPortDescReply(h.portDescReply);
h.sw.setConnected(true);
h.sw.setChannel(h.channel);
boolean success = h.sw.connectSwitch();
+
if (!success) {
disconnectDuplicate(h);
return;
@@ -432,10 +434,10 @@
log.info("Switch {} bound to class {}, description {}",
new Object[] {h.sw, h.sw.getClass(), drep });
//Put switch in EQUAL mode until we hear back from the global registry
- log.debug("Setting new switch {} to EQUAL and sending Role request",
- h.sw.getStringId());
- h.sw.activateEqualSwitch();
- h.setSwitchRole(RoleState.EQUAL);
+ //log.debug("Setting new switch {} to EQUAL and sending Role request",
+ // h.sw.getStringId());
+ //h.sw.activateEqualSwitch();
+ //h.setSwitchRole(RoleState.EQUAL);
h.sw.startDriverHandshake();
h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
index 2b1d1da..2a27ba9 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
@@ -1,9 +1,18 @@
package org.onlab.onos.of.controller.impl;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.of.controller.DefaultPacketContext;
import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.OpenFlowController;
import org.onlab.onos.of.controller.OpenFlowSwitch;
@@ -12,18 +21,11 @@
import org.onlab.onos.of.controller.RoleState;
import org.onlab.onos.of.controller.driver.OpenFlowAgent;
import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
@Component(immediate = true)
@Service
public class OpenFlowControllerImpl implements OpenFlowController {
@@ -42,238 +44,244 @@
protected Set<OpenFlowSwitchListener> ofEventListener =
new HashSet<>();
- protected List<PacketListener> ofPacketListener =
- new ArrayList<>();
+ protected List<PacketListener> ofPacketListener =
+ new ArrayList<>();
- private final Controller ctrl = new Controller();
+ private final Controller ctrl = new Controller();
- @Activate
- public void activate() {
- ctrl.start(agent);
- }
+ @Activate
+ public void activate() {
+ ctrl.start(agent);
+ }
- @Deactivate
- public void deactivate() {
- ctrl.stop();
- }
+ @Deactivate
+ public void deactivate() {
+ ctrl.stop();
+ }
- @Override
- public Iterable<OpenFlowSwitch> getSwitches() {
- return connectedSwitches.values();
- }
+ @Override
+ public Iterable<OpenFlowSwitch> getSwitches() {
+ return connectedSwitches.values();
+ }
- @Override
- public Iterable<OpenFlowSwitch> getMasterSwitches() {
- return activeMasterSwitches.values();
- }
+ @Override
+ public Iterable<OpenFlowSwitch> getMasterSwitches() {
+ return activeMasterSwitches.values();
+ }
- @Override
- public Iterable<OpenFlowSwitch> getEqualSwitches() {
- return activeEqualSwitches.values();
- }
+ @Override
+ public Iterable<OpenFlowSwitch> getEqualSwitches() {
+ return activeEqualSwitches.values();
+ }
- @Override
- public OpenFlowSwitch getSwitch(Dpid dpid) {
- return connectedSwitches.get(dpid);
- }
+ @Override
+ public OpenFlowSwitch getSwitch(Dpid dpid) {
+ return connectedSwitches.get(dpid);
+ }
- @Override
- public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
- return activeMasterSwitches.get(dpid);
- }
+ @Override
+ public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
+ return activeMasterSwitches.get(dpid);
+ }
- @Override
- public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
- return activeEqualSwitches.get(dpid);
- }
+ @Override
+ public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
+ return activeEqualSwitches.get(dpid);
+ }
- @Override
- public void addListener(OpenFlowSwitchListener listener) {
- if (!ofEventListener.contains(listener)) {
- this.ofEventListener.add(listener);
- }
- }
+ @Override
+ public void addListener(OpenFlowSwitchListener listener) {
+ if (!ofEventListener.contains(listener)) {
+ this.ofEventListener.add(listener);
+ }
+ }
- @Override
- public void removeListener(OpenFlowSwitchListener listener) {
- this.ofEventListener.remove(listener);
- }
+ @Override
+ public void removeListener(OpenFlowSwitchListener listener) {
+ this.ofEventListener.remove(listener);
+ }
- @Override
- public void addPacketListener(int priority, PacketListener listener) {
- ofPacketListener.add(priority, listener);
- }
+ @Override
+ public void addPacketListener(int priority, PacketListener listener) {
+ ofPacketListener.add(priority, listener);
+ }
- @Override
- public void removePacketListener(PacketListener listener) {
- ofPacketListener.remove(listener);
- }
+ @Override
+ public void removePacketListener(PacketListener listener) {
+ ofPacketListener.remove(listener);
+ }
- @Override
- public void write(Dpid dpid, OFMessage msg) {
- this.getSwitch(dpid).sendMsg(msg);
- }
+ @Override
+ public void write(Dpid dpid, OFMessage msg) {
+ this.getSwitch(dpid).sendMsg(msg);
+ }
- @Override
- public void processPacket(Dpid dpid, OFMessage msg) {
- switch (msg.getType()) {
- case PORT_STATUS:
- for (OpenFlowSwitchListener l : ofEventListener) {
- l.portChanged(dpid, (OFPortStatus) msg);
- }
- break;
- case PACKET_IN:
- for (PacketListener p : ofPacketListener) {
- //TODO fix me!
- p.handlePacket(null);
- }
- break;
- default:
- log.warn("Handling message type {} not yet implemented", msg.getType());
- }
- }
+ @Override
+ public void processPacket(Dpid dpid, OFMessage msg) {
+ switch (msg.getType()) {
+ case PORT_STATUS:
+ for (OpenFlowSwitchListener l : ofEventListener) {
+ l.portChanged(dpid, (OFPortStatus) msg);
+ }
+ break;
+ case PACKET_IN:
+ for (PacketListener p : ofPacketListener) {
+ //TODO fix me!
+ p.handlePacket(DefaultPacketContext
+ .packetContextFromPacketIn(this.getSwitch(dpid),
+ (OFPacketIn) msg));
+ }
+ break;
+ default:
+ log.warn("Handling message type {} not yet implemented {}",
+ msg.getType(), msg);
+ }
+ }
- @Override
- public void setRole(Dpid dpid, RoleState role) {
- getSwitch(dpid).setRole(role);
- }
+ @Override
+ public void setRole(Dpid dpid, RoleState role) {
+ getSwitch(dpid).setRole(role);
+ }
- /**
- * Implementation of an OpenFlow Agent which is responsible for
- * keeping track of connected switches and the state in which
- * they are.
- */
- public class OpenFlowSwitchAgent implements OpenFlowAgent {
+ /**
+ * Implementation of an OpenFlow Agent which is responsible for
+ * keeping track of connected switches and the state in which
+ * they are.
+ */
+ public class OpenFlowSwitchAgent implements OpenFlowAgent {
- private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
- private final Lock switchLock = new ReentrantLock();
+ private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
+ private final Lock switchLock = new ReentrantLock();
- @Override
- public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
- if (connectedSwitches.get(dpid) != null) {
- log.error("Trying to add connectedSwitch but found a previous "
- + "value for dpid: {}", dpid);
- return false;
- } else {
- log.error("Added switch {}", dpid);
- connectedSwitches.put(dpid, sw);
- for (OpenFlowSwitchListener l : ofEventListener) {
- l.switchAdded(dpid);
- }
- return true;
- }
- }
+ @Override
+ public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
+ if (connectedSwitches.get(dpid) != null) {
+ log.error("Trying to add connectedSwitch but found a previous "
+ + "value for dpid: {}", dpid);
+ return false;
+ } else {
+ log.error("Added switch {}", dpid);
+ connectedSwitches.put(dpid, sw);
+ for (OpenFlowSwitchListener l : ofEventListener) {
+ l.switchAdded(dpid);
+ }
+ return true;
+ }
+ }
- @Override
- public boolean validActivation(Dpid dpid) {
- if (connectedSwitches.get(dpid) == null) {
- log.error("Trying to activate switch but is not in "
- + "connected switches: dpid {}. Aborting ..",
- dpid);
- return false;
- }
- if (activeMasterSwitches.get(dpid) != null ||
- activeEqualSwitches.get(dpid) != null) {
- log.error("Trying to activate switch but it is already "
- + "activated: dpid {}. Found in activeMaster: {} "
- + "Found in activeEqual: {}. Aborting ..", new Object[]{
- dpid,
- (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
- (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
- return false;
- }
- return true;
- }
+ @Override
+ public boolean validActivation(Dpid dpid) {
+ if (connectedSwitches.get(dpid) == null) {
+ log.error("Trying to activate switch but is not in "
+ + "connected switches: dpid {}. Aborting ..",
+ dpid);
+ return false;
+ }
+ if (activeMasterSwitches.get(dpid) != null ||
+ activeEqualSwitches.get(dpid) != null) {
+ log.error("Trying to activate switch but it is already "
+ + "activated: dpid {}. Found in activeMaster: {} "
+ + "Found in activeEqual: {}. Aborting ..", new Object[]{
+ dpid,
+ (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
+ (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+ return false;
+ }
+ return true;
+ }
- @Override
- public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
- switchLock.lock();
- try {
- if (!validActivation(dpid)) {
- return false;
- }
- activeMasterSwitches.put(dpid, sw);
- return true;
- } finally {
- switchLock.unlock();
- }
- }
+ @Override
+ public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
+ switchLock.lock();
+ try {
+ if (!validActivation(dpid)) {
+ return false;
+ }
+ activeMasterSwitches.put(dpid, sw);
+ return true;
+ } finally {
+ switchLock.unlock();
+ }
+ }
- @Override
- public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
- switchLock.lock();
- try {
- if (!validActivation(dpid)) {
- return false;
- }
- activeEqualSwitches.put(dpid, sw);
- log.info("Added Activated EQUAL Switch {}", dpid);
- return true;
- } finally {
- switchLock.unlock();
- }
- }
+ @Override
+ public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
+ switchLock.lock();
+ try {
+ if (!validActivation(dpid)) {
+ return false;
+ }
+ activeEqualSwitches.put(dpid, sw);
+ log.info("Added Activated EQUAL Switch {}", dpid);
+ return true;
+ } finally {
+ switchLock.unlock();
+ }
+ }
- @Override
- public void transitionToMasterSwitch(Dpid dpid) {
- switchLock.lock();
- try {
- if (activeMasterSwitches.containsKey(dpid)) {
- return;
- }
- OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
- if (sw == null) {
- log.error("Transition to master called on sw {}, but switch "
- + "was not found in controller-cache", dpid);
- return;
- }
- log.info("Transitioned switch {} to MASTER", dpid);
- activeMasterSwitches.put(dpid, sw);
- } finally {
- switchLock.unlock();
- }
- }
+ @Override
+ public void transitionToMasterSwitch(Dpid dpid) {
+ switchLock.lock();
+ try {
+ if (activeMasterSwitches.containsKey(dpid)) {
+ return;
+ }
+ OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
+ if (sw == null) {
+ sw = getSwitch(dpid);
+ if (sw == null) {
+ log.error("Transition to master called on sw {}, but switch "
+ + "was not found in controller-cache", dpid);
+ return;
+ }
+ }
+ log.info("Transitioned switch {} to MASTER", dpid);
+ activeMasterSwitches.put(dpid, sw);
+ } finally {
+ switchLock.unlock();
+ }
+ }
- @Override
- public void transitionToEqualSwitch(Dpid dpid) {
- switchLock.lock();
- try {
- if (activeEqualSwitches.containsKey(dpid)) {
- return;
- }
- OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
- if (sw == null) {
- log.error("Transition to equal called on sw {}, but switch "
- + "was not found in controller-cache", dpid);
- return;
- }
- log.info("Transitioned switch {} to EQUAL", dpid);
- activeEqualSwitches.put(dpid, sw);
- } finally {
- switchLock.unlock();
- }
+ @Override
+ public void transitionToEqualSwitch(Dpid dpid) {
+ switchLock.lock();
+ try {
+ if (activeEqualSwitches.containsKey(dpid)) {
+ return;
+ }
+ OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+ if (sw == null) {
+ log.error("Transition to equal called on sw {}, but switch "
+ + "was not found in controller-cache", dpid);
+ return;
+ }
+ log.info("Transitioned switch {} to EQUAL", dpid);
+ activeEqualSwitches.put(dpid, sw);
+ } finally {
+ switchLock.unlock();
+ }
- }
+ }
- @Override
- public void removeConnectedSwitch(Dpid dpid) {
- connectedSwitches.remove(dpid);
- OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
- if (sw == null) {
- sw = activeEqualSwitches.remove(dpid);
- }
- for (OpenFlowSwitchListener l : ofEventListener) {
- l.switchRemoved(dpid);
- }
- }
+ @Override
+ public void removeConnectedSwitch(Dpid dpid) {
+ connectedSwitches.remove(dpid);
+ OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+ if (sw == null) {
+ sw = activeEqualSwitches.remove(dpid);
+ }
+ for (OpenFlowSwitchListener l : ofEventListener) {
+ l.switchRemoved(dpid);
+ }
+ }
- @Override
- public void processMessage(Dpid dpid, OFMessage m) {
- processPacket(dpid, m);
- }
- }
+ @Override
+ public void processMessage(Dpid dpid, OFMessage m) {
+ processPacket(dpid, m);
+ }
+ }
}
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/RoleManager.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/RoleManager.java
index f82a46c..f2e9581 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/RoleManager.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/RoleManager.java
@@ -84,7 +84,7 @@
default:
// ensuring that the only two roles sent to 1.0 switches with
// Nicira role support, are MASTER and SLAVE
- roleToSend = OFNiciraControllerRole.ROLE_SLAVE;
+ roleToSend = OFNiciraControllerRole.ROLE_OTHER;
log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
}
int xid = sw.getNextTransactionId();
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/drivers/impl/OFSwitchImplOVS10.java b/of/ctl/src/main/java/org/onlab/onos/of/drivers/impl/OFSwitchImplOVS10.java
index b9ee4c9..0de661b 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/drivers/impl/OFSwitchImplOVS10.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/drivers/impl/OFSwitchImplOVS10.java
@@ -50,8 +50,7 @@
@Override
public void write(OFMessage msg) {
- channel.write(msg);
-
+ channel.write(Collections.singletonList(msg));
}
@Override
diff --git a/pom.xml b/pom.xml
index 25557a1..9fc49c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,6 +61,14 @@
<version>18.0</version>
</dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty</artifactId>
+ <version>3.9.0.Final</version>
+ </dependency>
+
+
+
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-testlib</artifactId>
diff --git a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java
new file mode 100644
index 0000000..9396f91
--- /dev/null
+++ b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.onlab.onos.provider.of.link.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.TimerTask;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.Link.Type;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.link.DefaultLinkDescription;
+import org.onlab.onos.net.link.LinkDescription;
+import org.onlab.onos.net.link.LinkProviderService;
+import org.onlab.onos.of.controller.Dpid;
+import org.onlab.onos.of.controller.OpenFlowController;
+import org.onlab.onos.of.controller.OpenFlowSwitch;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ONLabLddp;
+import org.onlab.packet.ONLabLddp.DPIDandPort;
+import org.onlab.timer.Timer;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.slf4j.Logger;
+
+
+
+/**
+ * Run discovery process from a physical switch. Ports are initially labeled as
+ * slow ports. When an LLDP is successfully received, label the remote port as
+ * fast. Every probeRate milliseconds, loop over all fast ports and send an
+ * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology
+ * discovery implementation.
+ *
+ * TODO: add 'fast discovery' mode: drop LLDPs in destination switch but listen
+ * for flow_removed messages
+ */
+public class LinkDiscovery implements TimerTask {
+
+ private final OpenFlowSwitch sw;
+ // send 1 probe every probeRate milliseconds
+ private final long probeRate;
+ private final Set<Integer> slowPorts;
+ private final Set<Integer> fastPorts;
+ // number of unacknowledged probes per port
+ private final Map<Integer, AtomicInteger> portProbeCount;
+ // number of probes to send before link is removed
+ private static final short MAX_PROBE_COUNT = 3;
+ private Iterator<Integer> slowIterator;
+ private final OFFactory ofFactory;
+ private final Logger log = getLogger(getClass());
+ private final ONLabLddp lldpPacket;
+ private final Ethernet ethPacket;
+ private Ethernet bddpEth;
+ private final boolean useBDDP;
+ private final OpenFlowController ctrl;
+ private final LinkProviderService linkProvider;
+
+ /**
+ * Instantiates discovery manager for the given physical switch. Creates a
+ * generic LLDP packet that will be customized for the port it is sent out on.
+ * Starts the the timer for the discovery process.
+ *
+ * @param sw the physical switch
+ * @param useBDDP flag to also use BDDP for discovery
+ */
+ public LinkDiscovery(final OpenFlowSwitch sw,
+ OpenFlowController ctrl, LinkProviderService providerService, Boolean... useBDDP) {
+ this.sw = sw;
+ this.ofFactory = sw.factory();
+ this.ctrl = ctrl;
+ this.probeRate = 1000;
+ this.linkProvider = providerService;
+ this.slowPorts = Collections.synchronizedSet(new HashSet<Integer>());
+ this.fastPorts = Collections.synchronizedSet(new HashSet<Integer>());
+ this.portProbeCount = new HashMap<Integer, AtomicInteger>();
+ this.lldpPacket = new ONLabLddp();
+ this.lldpPacket.setSwitch(this.sw.getId());
+ this.ethPacket = new Ethernet();
+ this.ethPacket.setEtherType(Ethernet.TYPE_LLDP);
+ this.ethPacket.setDestinationMACAddress(ONLabLddp.LLDP_NICIRA);
+ this.ethPacket.setPayload(this.lldpPacket);
+ this.ethPacket.setPad(true);
+ this.useBDDP = useBDDP.length > 0 ? useBDDP[0] : false;
+ if (this.useBDDP) {
+ this.bddpEth = new Ethernet();
+ this.bddpEth.setPayload(this.lldpPacket);
+ this.bddpEth.setEtherType(Ethernet.TYPE_BSN);
+ this.bddpEth.setDestinationMACAddress(ONLabLddp.BDDP_MULTICAST);
+ this.bddpEth.setPad(true);
+ log.info("Using BDDP to discover network");
+ }
+ for (OFPortDesc port : sw.getPorts()) {
+ if (port.getPortNo() != OFPort.LOCAL) {
+ addPort(port);
+ }
+ }
+ Timer.getTimer().newTimeout(this, this.probeRate,
+ TimeUnit.MILLISECONDS);
+ this.log.debug("Started discovery manager for switch {}",
+ sw.getId());
+
+ }
+
+ /**
+ * Add physical port port to discovery process.
+ * Send out initial LLDP and label it as slow port.
+ *
+ * @param port the port
+ */
+ public void addPort(final OFPortDesc port) {
+ // Ignore ports that are not on this switch, or already booted. */
+
+ synchronized (this) {
+ this.log.debug("sending init probe to port {}",
+ port.getPortNo().getPortNumber());
+ OFPacketOut pkt;
+
+ pkt = this.createLLDPPacketOut(port);
+ this.sw.sendMsg(pkt);
+ if (useBDDP) {
+ OFPacketOut bpkt = this.createBDDPPacketOut(port);
+ this.sw.sendMsg(bpkt);
+ }
+
+ this.slowPorts.add(port.getPortNo().getPortNumber());
+ this.slowIterator = this.slowPorts.iterator();
+ }
+
+ }
+
+ /**
+ * Removes physical port from discovery process.
+ *
+ * @param port the port
+ */
+ public void removePort(final OFPort port) {
+ // Ignore ports that are not on this switch
+
+ int portnum = port.getPortNumber();
+ synchronized (this) {
+ if (this.slowPorts.contains(portnum)) {
+ this.slowPorts.remove(portnum);
+ this.slowIterator = this.slowPorts.iterator();
+
+ } else if (this.fastPorts.contains(portnum)) {
+ this.fastPorts.remove(portnum);
+ this.portProbeCount.remove(portnum);
+ // no iterator to update
+ } else {
+ this.log.warn(
+ "tried to dynamically remove non-existing port {}",
+ portnum);
+ }
+ }
+
+ }
+
+ /**
+ * Method called by remote port to acknowledge receipt of LLDP sent by
+ * this port. If slow port, updates label to fast. If fast port, decrements
+ * number of unacknowledged probes.
+ *
+ * @param port the port
+ */
+ public void ackProbe(final Integer port) {
+ final int portNumber = port;
+ synchronized (this) {
+ if (this.slowPorts.contains(portNumber)) {
+ this.log.debug("Setting slow port to fast: {}:{}",
+ this.sw.getId(), portNumber);
+ this.slowPorts.remove(portNumber);
+ this.slowIterator = this.slowPorts.iterator();
+ this.fastPorts.add(portNumber);
+ this.portProbeCount.put(portNumber, new AtomicInteger(0));
+ } else {
+ if (this.fastPorts.contains(portNumber)) {
+ this.portProbeCount.get(portNumber).set(0);
+ } else {
+ this.log.debug(
+ "Got ackProbe for non-existing port: {}",
+ portNumber);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates packet_out LLDP for specified output port.
+ *
+ * @param port the port
+ * @return Packet_out message with LLDP data
+ * @throws PortMappingException
+ */
+ private OFPacketOut createLLDPPacketOut(final OFPortDesc port) {
+ OFPacketOut.Builder packetOut = this.ofFactory.buildPacketOut();
+ packetOut.setBufferId(OFBufferId.NO_BUFFER);
+ OFAction act = this.ofFactory.actions().buildOutput()
+ .setPort(port.getPortNo()).build();
+ packetOut.setActions(Collections.singletonList(act));
+ this.lldpPacket.setPort(port.getPortNo().getPortNumber());
+ this.ethPacket.setSourceMACAddress(port.getHwAddr().getBytes());
+
+ final byte[] lldp = this.ethPacket.serialize();
+ packetOut.setData(lldp);
+ return packetOut.build();
+ }
+
+ /**
+ * Creates packet_out BDDP for specified output port.
+ *
+ * @param port the port
+ * @return Packet_out message with LLDP data
+ * @throws PortMappingException
+ */
+ private OFPacketOut createBDDPPacketOut(final OFPortDesc port) {
+ OFPacketOut.Builder packetOut = sw.factory().buildPacketOut();
+
+ packetOut.setBufferId(OFBufferId.NO_BUFFER);
+
+ OFActionOutput.Builder act = sw.factory().actions().buildOutput()
+ .setPort(port.getPortNo());
+ OFAction out = act.build();
+ packetOut.setActions(Collections.singletonList(out));
+ this.lldpPacket.setPort(port.getPortNo().getPortNumber());
+ this.bddpEth.setSourceMACAddress(port.getHwAddr().getBytes());
+
+ final byte[] bddp = this.bddpEth.serialize();
+ packetOut.setData(bddp);
+
+ return packetOut.build();
+ }
+
+
+ private void sendMsg(final OFMessage msg) {
+ this.sw.sendMsg(msg);
+ }
+
+ public String getName() {
+ return "LinkDiscovery " + this.sw.getStringId();
+ }
+
+ /*
+ * Handles an incoming LLDP packet. Creates link in topology and sends ACK
+ * to port where LLDP originated.
+ */
+ @SuppressWarnings("rawtypes")
+ public void handleLLDP(final Ethernet eth, Integer inPort) {
+
+ final byte[] pkt = eth.serialize();
+
+ if (ONLabLddp.isOVXLLDP(pkt)) {
+ final Integer dstPort = inPort;
+ final DPIDandPort dp = ONLabLddp.parseLLDP(pkt);
+ final OpenFlowSwitch srcSwitch = ctrl.getSwitch(new Dpid(dp.getDpid()));
+ final Integer srcPort = dp.getPort();
+ if (srcSwitch == null) {
+ return;
+ }
+ this.ackProbe(srcPort);
+ ConnectPoint src = new ConnectPoint(
+ DeviceId.deviceId("of:" + Long.toHexString(srcSwitch.getId())),
+ PortNumber.portNumber(srcPort));
+
+ ConnectPoint dst = new ConnectPoint(
+ DeviceId.deviceId("of:" + Long.toHexString(sw.getId())),
+ PortNumber.portNumber(dstPort));
+ LinkDescription ld;
+ if (eth.getEtherType() == Ethernet.TYPE_BSN) {
+ ld = new DefaultLinkDescription(src, dst, Type.INDIRECT);
+ } else {
+ ld = new DefaultLinkDescription(src, dst, Type.DIRECT);
+ }
+ linkProvider.linkDetected(ld);
+ } else {
+ this.log.debug("Ignoring unknown LLDP");
+ }
+ }
+
+ private OFPortDesc findPort(List<OFPortDesc> ports, Integer inPort) {
+ for (OFPortDesc p : ports) {
+ if (p.getPortNo().getPortNumber() == inPort) {
+ return p;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Execute this method every t milliseconds. Loops over all ports
+ * labeled as fast and sends out an LLDP. Send out an LLDP on a single slow
+ * port.
+ *
+ * @param t timeout
+ * @throws Exception
+ */
+ @Override
+ public void run(final Timeout t) {
+ this.log.debug("sending probes");
+ synchronized (this) {
+ final Iterator<Integer> fastIterator = this.fastPorts.iterator();
+ while (fastIterator.hasNext()) {
+ final Integer portNumber = fastIterator.next();
+ final int probeCount = this.portProbeCount.get(portNumber)
+ .getAndIncrement();
+ OFPortDesc port = findPort(this.sw.getPorts(), portNumber);
+ if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) {
+ this.log.debug("sending fast probe to port");
+
+ OFPacketOut pkt = this.createLLDPPacketOut(port);
+ this.sendMsg(pkt);
+ if (useBDDP) {
+ OFPacketOut bpkt = this.createBDDPPacketOut(port);
+ this.sendMsg(bpkt);
+ }
+ } else {
+ // Update fast and slow ports
+ fastIterator.remove();
+ this.slowPorts.add(portNumber);
+ this.slowIterator = this.slowPorts.iterator();
+ this.portProbeCount.remove(portNumber);
+
+ // Remove link from topology
+ final OFPortDesc srcPort = port;
+
+ ConnectPoint cp = new ConnectPoint(
+ DeviceId.deviceId("of:" + Long.toHexString(sw.getId())),
+ PortNumber.portNumber(srcPort.getPortNo().getPortNumber()));
+ linkProvider.linksVanished(cp);
+ }
+ }
+
+ // send a probe for the next slow port
+ if (this.slowPorts.size() > 0) {
+ if (!this.slowIterator.hasNext()) {
+ this.slowIterator = this.slowPorts.iterator();
+ }
+ if (this.slowIterator.hasNext()) {
+ final int portNumber = this.slowIterator.next();
+ this.log.debug("sending slow probe to port {}", portNumber);
+ OFPortDesc port = findPort(this.sw.getPorts(), portNumber);
+
+ OFPacketOut pkt = this.createLLDPPacketOut(port);
+ this.sendMsg(pkt);
+ if (useBDDP) {
+ OFPacketOut bpkt = this.createBDDPPacketOut(port);
+ this.sendMsg(bpkt);
+ }
+
+ }
+ }
+ }
+
+ // reschedule timer
+ Timer.getTimer().newTimeout(this, this.probeRate,
+ TimeUnit.MILLISECONDS);
+ }
+
+ public void removeAllPorts() {
+ for (OFPortDesc port : sw.getPorts()) {
+ removePort(port.getPortNo());
+ }
+ }
+
+}
diff --git a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
index ed9d970..737ef00 100644
--- a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
+++ b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
@@ -2,19 +2,32 @@
import static org.slf4j.LoggerFactory.getLogger;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.link.LinkProvider;
import org.onlab.onos.net.link.LinkProviderRegistry;
import org.onlab.onos.net.link.LinkProviderService;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.OpenFlowController;
+import org.onlab.onos.of.controller.OpenFlowSwitchListener;
import org.onlab.onos.of.controller.PacketContext;
import org.onlab.onos.of.controller.PacketListener;
+import org.onlab.timer.Timer;
+import org.projectfloodlight.openflow.protocol.OFPortConfig;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortState;
+import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
/**
@@ -34,7 +47,9 @@
private LinkProviderService providerService;
- private final PacketListener listener = new InternalLinkProvider();
+ private final boolean useBDDP = true;
+
+ private final InternalLinkProvider listener = new InternalLinkProvider();
/**
* Creates an OpenFlow link provider.
@@ -46,6 +61,7 @@
@Activate
public void activate() {
providerService = providerRegistry.register(this);
+ controller.addListener(listener);
controller.addPacketListener(0, listener);
log.info("Started");
}
@@ -53,16 +69,64 @@
@Deactivate
public void deactivate() {
providerRegistry.unregister(this);
+ controller.removeListener(listener);
controller.removePacketListener(listener);
providerService = null;
+ Timer.getTimer().stop();
log.info("Stopped");
}
- private class InternalLinkProvider implements PacketListener {
+ private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener {
+
+ private final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
@Override
public void handlePacket(PacketContext pktCtx) {
+ LinkDiscovery ld = discoverers.get(pktCtx.dpid());
+ if (ld == null) {
+ return;
+ }
+ ld.handleLLDP(pktCtx.parsed(),
+ pktCtx.inPort());
+
+ }
+
+ @Override
+ public void switchAdded(Dpid dpid) {
+ discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
+ controller, providerService, useBDDP));
+
+ }
+
+ @Override
+ public void switchRemoved(Dpid dpid) {
+ LinkDiscovery ld = this.discoverers.remove(dpid);
+ if (ld != null) {
+ ld.removeAllPorts();
+ }
+ providerService.linksVanished(
+ DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
+ }
+
+ @Override
+ public void portChanged(Dpid dpid, OFPortStatus status) {
+ LinkDiscovery ld = discoverers.get(dpid);
+ if (ld == null) {
+ return;
+ }
+ final OFPortDesc port = status.getDesc();
+ final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
+ !port.getConfig().contains(OFPortConfig.PORT_DOWN);
+ if (enabled) {
+ ld.addPort(port);
+ } else {
+ ConnectPoint cp = new ConnectPoint(
+ DeviceId.deviceId("of:" + Long.toHexString(dpid.value())),
+ PortNumber.portNumber(port.getPortNo().getPortNumber()));
+ providerService.linksVanished(cp);
+ ld.removePort(port.getPortNo());
+ }
}
diff --git a/utils/misc/pom.xml b/utils/misc/pom.xml
index c39fd32..5b19401 100644
--- a/utils/misc/pom.xml
+++ b/utils/misc/pom.xml
@@ -22,7 +22,10 @@
<artifactId>guava-testlib</artifactId>
<scope>test</scope>
</dependency>
-
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty</artifactId>
+ </dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
diff --git a/utils/misc/src/main/java/org/onlab/packet/OVXLLDP.java b/utils/misc/src/main/java/org/onlab/packet/ONLabLddp.java
similarity index 87%
rename from utils/misc/src/main/java/org/onlab/packet/OVXLLDP.java
rename to utils/misc/src/main/java/org/onlab/packet/ONLabLddp.java
index f1a4b5f..520d670 100644
--- a/utils/misc/src/main/java/org/onlab/packet/OVXLLDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ONLabLddp.java
@@ -21,6 +21,8 @@
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -29,8 +31,9 @@
*
*/
@SuppressWarnings("rawtypes")
-public class OVXLLDP extends LLDP {
+public class ONLabLddp extends LLDP {
+ private static final Logger log = LoggerFactory.getLogger(ONLabLddp.class);
// ON.Lab OUI and OVX name for organizationally specific TLVs
public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
public static final String OVX_NAME = "OpenVirteX";
@@ -50,7 +53,7 @@
private static final byte CHASSIS_TLV_SUBTYPE = 4;
private static final byte PORT_TLV_TYPE = 2;
- private static final byte PORT_TLV_SIZE = 7;
+ private static final byte PORT_TLV_SIZE = 5;
private static final byte PORT_TLV_SUBTYPE = 2;
private static final byte TTL_TLV_TYPE = 3;
@@ -58,9 +61,9 @@
private static final byte NAME_TLV_TYPE = 127;
// 4 = OUI (3) + subtype (1)
- private static final byte NAME_TLV_SIZE = (byte) (4 + OVXLLDP.OVX_NAME.length());
+ private static final byte NAME_TLV_SIZE = (byte) (4 + ONLabLddp.OVX_NAME.length());
private static final byte NAME_TLV_SUBTYPE = 1;
- private static final short NAME_TLV_OFFSET = 32;
+ private static final short NAME_TLV_OFFSET = 34;
private static final short NAME_TLV_HEADER = (short) ((NAME_TLV_TYPE << 9) | NAME_TLV_SIZE);
// Contents of full name TLV
private static final byte[] NAME_TLV = ByteBuffer.allocate(NAME_TLV_SIZE + 2)
@@ -85,7 +88,7 @@
// Default switch, port number and TTL
private static final byte[] DEFAULT_DPID = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 };
- private static final short DEFAULT_PORT = 0;
+ private static final int DEFAULT_PORT = 0;
private static final short DEFAULT_TTL = 120; // in seconds
// Minimum and OVX-generated LLDP packet sizes
@@ -97,7 +100,7 @@
// Field offsets in OVX-generated LLDP
private static final short ETHERTYPE_OFFSET = 12;
private static final short PORT_OFFSET = 26;
- private static final short DPID_OFFSET = 54;
+ private static final short DPID_OFFSET = 56;
// Private member fields
// Byte arrays for TLV information string
@@ -119,7 +122,7 @@
/**
* Instantiates a new OVX LDDP message.
*/
- public OVXLLDP() {
+ public ONLabLddp() {
// Create TLVs
this.chassisTLV = new LLDPTLV();
this.portTLV = new LLDPTLV();
@@ -140,7 +143,7 @@
this.setChassisTLV(DEFAULT_DPID);
this.setPortTLV(DEFAULT_PORT);
this.setTTLTLV(DEFAULT_TTL);
- this.setOUIName(OVXLLDP.OVX_NAME);
+ this.setOUIName(ONLabLddp.OVX_NAME);
this.setOUIDpid(DEFAULT_DPID);
}
@@ -167,10 +170,10 @@
*
* @param portNumber the port number
*/
- private void setPortTLV(final long portNumber) {
+ private void setPortTLV(final int portNumber) {
this.bb = ByteBuffer.wrap(this.portId);
this.bb.put(PORT_TLV_SUBTYPE);
- this.bb.putLong(portNumber);
+ this.bb.putInt(portNumber);
this.portTLV.setLength(PORT_TLV_SIZE);
this.portTLV.setType(PORT_TLV_TYPE);
@@ -198,7 +201,7 @@
*/
private void setOUIName(final String name) {
this.bb = ByteBuffer.wrap(ouiName);
- this.bb.put(OVXLLDP.ONLAB_OUI);
+ this.bb.put(ONLabLddp.ONLAB_OUI);
this.bb.put(NAME_TLV_SUBTYPE);
this.bb.put(name.getBytes());
@@ -214,7 +217,7 @@
*/
private void setOUIDpid(final byte[] dpid) {
this.bb = ByteBuffer.wrap(ouiDpid);
- this.bb.put(OVXLLDP.ONLAB_OUI);
+ this.bb.put(ONLabLddp.ONLAB_OUI);
this.bb.put(DPID_TLV_SUBTYPE);
this.bb.put(dpid);
@@ -240,8 +243,8 @@
*
* @param port the port instance
*/
- public void setPort(long port) {
- long portNumber = port;
+ public void setPort(int port) {
+ int portNumber = port;
this.setPortTLV(portNumber);
}
@@ -272,9 +275,9 @@
final byte[] dst = new byte[6];
bb.get(dst);
- if (!(Arrays.equals(dst, OVXLLDP.LLDP_NICIRA)
- || Arrays.equals(dst, OVXLLDP.LLDP_MULTICAST) || Arrays.equals(
- dst, OVXLLDP.BDDP_MULTICAST))) {
+ if (!(Arrays.equals(dst, ONLabLddp.LLDP_NICIRA)
+ || Arrays.equals(dst, ONLabLddp.LLDP_MULTICAST) || Arrays.equals(
+ dst, ONLabLddp.BDDP_MULTICAST))) {
return false;
}
@@ -335,7 +338,7 @@
* @param packet
* @return Dpid and port
*/
- /* public static long parseLLDP(final byte[] packet) {
+ public static DPIDandPort parseLLDP(final byte[] packet) {
final ByteBuffer bb = ByteBuffer.wrap(packet);
// Extra offset due to VLAN tag
@@ -345,10 +348,30 @@
offset = 4;
}
- final short port = bb.getLong(PORT_OFFSET + offset);
+ final int port = bb.getInt(PORT_OFFSET + offset);
final long dpid = bb.getLong(DPID_OFFSET + offset);
- return dpid
+ return new DPIDandPort(dpid, port);
}
- */
+
+ public static class DPIDandPort {
+
+ private final long dpid;
+ private final int port;
+
+ public DPIDandPort(long dpid, int port) {
+ this.dpid = dpid;
+ this.port = port;
+ }
+
+ public long getDpid() {
+ return this.dpid;
+ }
+
+ public int getPort() {
+ return this.port;
+ }
+
+ }
+
}
diff --git a/utils/misc/src/main/java/org/onlab/timer/Timer.java b/utils/misc/src/main/java/org/onlab/timer/Timer.java
new file mode 100644
index 0000000..1f821a7
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/timer/Timer.java
@@ -0,0 +1,20 @@
+package org.onlab.timer;
+
+import org.jboss.netty.util.HashedWheelTimer;
+
+
+public final class Timer {
+
+ private Timer() {}
+
+ private static HashedWheelTimer timer;
+
+ public static HashedWheelTimer getTimer() {
+ if (Timer.timer == null) {
+ Timer.timer = new HashedWheelTimer();
+ Timer.timer.start();
+ }
+ return Timer.timer;
+ }
+
+}