alshabib

link discovery and providers are implemented

......@@ -2,7 +2,7 @@ package org.onlab.onos.net;
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,7 +42,6 @@ public class ConnectPoint {
* @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;
......@@ -77,7 +76,7 @@ public class ConnectPoint {
@Override
public String toString() {
return toStringHelper(this)
return MoreObjects.toStringHelper(this)
.add("elementId", elementId)
.add("portNumber", portNumber)
.toString();
......
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.AbstractProviderRegistry;
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 @@ import static org.slf4j.LoggerFactory.getLogger;
@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";
......@@ -156,7 +157,7 @@ public class SimpleLinkManager
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);
post(event);
......
......@@ -75,4 +75,9 @@ public final class DefaultPacketContext implements PacketContext {
return new DefaultPacketContext(s, pkt);
}
@Override
public Integer inPort() {
return pktin.getInPort().getPortNumber();
}
}
......
......@@ -48,4 +48,10 @@ public interface PacketContext {
* @return the dpid of the switch.
*/
public Dpid dpid();
/**
* Provide the port on which the packet arrived.
* @return the port
*/
public Integer inPort();
}
......
......@@ -415,12 +415,14 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
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 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
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);
......
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.PacketListener;
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 {
......@@ -125,11 +127,14 @@ public class OpenFlowControllerImpl implements OpenFlowController {
case PACKET_IN:
for (PacketListener p : ofPacketListener) {
//TODO fix me!
p.handlePacket(null);
p.handlePacket(DefaultPacketContext
.packetContextFromPacketIn(this.getSwitch(dpid),
(OFPacketIn) msg));
}
break;
default:
log.warn("Handling message type {} not yet implemented", msg.getType());
log.warn("Handling message type {} not yet implemented {}",
msg.getType(), msg);
}
}
......@@ -224,10 +229,13 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
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 {
......
......@@ -84,7 +84,7 @@ class RoleManager implements RoleHandler {
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();
......
......@@ -50,8 +50,7 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
@Override
public void write(OFMessage msg) {
channel.write(msg);
channel.write(Collections.singletonList(msg));
}
@Override
......
......@@ -62,6 +62,14 @@
</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>
<version>18.0</version>
......
......@@ -2,11 +2,17 @@ package org.onlab.onos.provider.of.link.impl;
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;
......@@ -17,6 +23,10 @@ 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;
......@@ -37,6 +47,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
private LinkProviderService providerService;
private final boolean useBDDP = true;
private final InternalLinkProvider listener = new InternalLinkProvider();
/**
......@@ -60,32 +72,61 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
controller.removeListener(listener);
controller.removePacketListener(listener);
providerService = null;
Timer.getTimer().stop();
log.info("Stopped");
}
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) {
// TODO Auto-generated method stub
discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
controller, providerService, useBDDP));
}
@Override
public void switchRemoved(Dpid dpid) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated method stub
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());
}
}
......
......@@ -25,7 +25,10 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.9.0.Final</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
......
......@@ -21,6 +21,8 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
......@@ -31,6 +33,7 @@ import org.apache.commons.lang.ArrayUtils;
@SuppressWarnings("rawtypes")
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 @@ public class ONLabLddp extends LLDP {
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;
......@@ -60,7 +63,7 @@ public class ONLabLddp extends LLDP {
// 4 = OUI (3) + subtype (1)
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 @@ public class ONLabLddp extends LLDP {
// 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 @@ public class ONLabLddp extends LLDP {
// 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
......@@ -167,10 +170,10 @@ public class ONLabLddp extends LLDP {
*
* @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);
......@@ -240,8 +243,8 @@ public class ONLabLddp extends LLDP {
*
* @param port the port instance
*/
public void setPort(long port) {
long portNumber = port;
public void setPort(int port) {
int portNumber = port;
this.setPortTLV(portNumber);
}
......@@ -335,7 +338,7 @@ public class ONLabLddp extends LLDP {
* @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 @@ public class ONLabLddp extends LLDP {
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;
}
}
}
......
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;
}
}