tom

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Conflicts:
	providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
package org.onlab.onos.of.drivers.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
......@@ -11,7 +13,14 @@ import org.onlab.onos.of.controller.driver.SwitchDriverSubHandshakeNotStarted;
import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMatchV3;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFOxmList;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -29,6 +38,9 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
private OFFactory factory;
private long barrierXidToWaitFor = -1;
private static final short MIN_PRIORITY = 0x0;
private static final int OFPCML_NO_BUFFER = 0xffff;
public OFSwitchImplOVS13(Dpid dpid, OFDescStatsReply desc) {
super(dpid);
driverHandshakeComplete = new AtomicBoolean(false);
......@@ -112,6 +124,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
private void configureSwitch() {
populateTableMissEntry(0, true, false, false, 0);
sendBarrier(true);
}
......@@ -135,7 +148,7 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
@Override
public void write(OFMessage msg) {
channel.write(msg);
channel.write(Collections.singletonList(msg));
}
......@@ -143,4 +156,78 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
public void write(List<OFMessage> msgs) {
channel.write(msgs);
}
/**
* By default if none of the booleans in the call are set, then the
* table-miss entry is added with no instructions, which means that pipeline
* execution will stop, and the action set associated with the packet will
* be executed.
*
* @param tableToAdd
* @param toControllerNow as an APPLY_ACTION instruction
* @param toControllerWrite as a WRITE_ACITION instruction
* @param toTable as a GOTO_TABLE instruction
* @param tableToSend
*/
@SuppressWarnings("unchecked")
private void populateTableMissEntry(int tableToAdd, boolean toControllerNow,
boolean toControllerWrite,
boolean toTable, int tableToSend) {
OFOxmList oxmList = OFOxmList.EMPTY;
OFMatchV3 match = factory.buildMatchV3()
.setOxmList(oxmList)
.build();
OFAction outc = factory.actions()
.buildOutput()
.setPort(OFPort.CONTROLLER)
.setMaxLen(OFPCML_NO_BUFFER)
.build();
List<OFInstruction> instructions = new ArrayList<OFInstruction>();
if (toControllerNow) {
// table-miss instruction to send to controller immediately
OFInstruction instr = factory.instructions()
.buildApplyActions()
.setActions(Collections.singletonList(outc))
.build();
instructions.add(instr);
}
if (toControllerWrite) {
// table-miss instruction to write-action to send to controller
// this will be executed whenever the action-set gets executed
OFInstruction instr = factory.instructions()
.buildWriteActions()
.setActions(Collections.singletonList(outc))
.build();
instructions.add(instr);
}
if (toTable) {
// table-miss instruction to goto-table x
OFInstruction instr = factory.instructions()
.gotoTable(TableId.of(tableToSend));
instructions.add(instr);
}
if (!toControllerNow && !toControllerWrite && !toTable) {
// table-miss has no instruction - at which point action-set will be
// executed - if there is an action to output/group in the action
// set
// the packet will be sent there, otherwise it will be dropped.
instructions = Collections.EMPTY_LIST;
}
OFMessage tableMissEntry = factory.buildFlowAdd()
.setTableId(TableId.of(tableToAdd))
.setMatch(match) // match everything
.setInstructions(instructions)
.setPriority(MIN_PRIORITY)
.setBufferId(OFBufferId.NO_BUFFER)
.setIdleTimeout(0)
.setHardTimeout(0)
.setXid(getNextTransactionId())
.build();
sendMsg(tableMissEntry);
}
}
......
......@@ -14,6 +14,7 @@ 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.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.device.DefaultDeviceDescription;
......@@ -66,14 +67,22 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
public void activate() {
providerService = providerRegistry.register(this);
controller.addListener(listener);
for (OpenFlowSwitch sw : controller.getSwitches()) {
listener.switchAdded(new Dpid(sw.getId()));
}
LOG.info("Started");
}
@Deactivate
public void deactivate() {
for (OpenFlowSwitch sw : controller.getSwitches()) {
providerService.deviceDisconnected(DeviceId.deviceId("of:"
+ Long.toHexString(sw.getId())));
}
providerRegistry.unregister(this);
controller.removeListener(listener);
providerService = null;
LOG.info("Stopped");
}
......
......@@ -86,6 +86,7 @@ public class LinkDiscovery implements TimerTask {
private final OpenFlowController ctrl;
private final LinkProviderService linkProvider;
private final Map<Integer, OFPortDesc> ports;
private Timeout timeout;
/**
* Instantiates discovery manager for the given physical switch. Creates a
......@@ -127,7 +128,7 @@ public class LinkDiscovery implements TimerTask {
addPort(port);
}
}
Timer.getTimer().newTimeout(this, this.probeRate,
timeout = Timer.getTimer().newTimeout(this, this.probeRate,
TimeUnit.MILLISECONDS);
this.log.debug("Started discovery manager for switch {}",
sw.getId());
......@@ -186,6 +187,10 @@ public class LinkDiscovery implements TimerTask {
portnum);
}
}
ConnectPoint cp = new ConnectPoint(
DeviceId.deviceId("of:" + Long.toHexString(sw.getId())),
PortNumber.portNumber(port.getPortNo().getPortNumber()));
linkProvider.linksVanished(cp);
}
......@@ -380,14 +385,19 @@ public class LinkDiscovery implements TimerTask {
}
// reschedule timer
Timer.getTimer().newTimeout(this, this.probeRate,
timeout = Timer.getTimer().newTimeout(this, this.probeRate,
TimeUnit.MILLISECONDS);
}
public void removeAllPorts() {
for (OFPortDesc port : sw.getPorts()) {
for (OFPortDesc port : ports.values()) {
removePort(port);
}
}
public void stop() {
removeAllPorts();
timeout.cancel();
}
}
......
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;
......@@ -20,16 +13,21 @@ 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.OpenFlowSwitch;
import org.onlab.onos.of.controller.OpenFlowSwitchListener;
import org.onlab.onos.of.controller.PacketContext;
import org.onlab.onos.of.controller.PacketListener;
import org.onlab.util.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;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Provider which uses an OpenFlow controller to detect network
* infrastructure links.
......@@ -51,6 +49,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
private final InternalLinkProvider listener = new InternalLinkProvider();
private final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
/**
* Creates an OpenFlow link provider.
*/
......@@ -63,23 +63,28 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
providerService = providerRegistry.register(this);
controller.addListener(listener);
controller.addPacketListener(0, listener);
for (OpenFlowSwitch sw : controller.getSwitches()) {
listener.switchAdded(new Dpid(sw.getId()));
}
log.info("Started");
}
@Deactivate
public void deactivate() {
for (LinkDiscovery ld : discoverers.values()) {
ld.stop();
}
providerRegistry.unregister(this);
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) {
......@@ -96,13 +101,13 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
@Override
public void switchAdded(Dpid dpid) {
discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
controller, providerService, useBDDP));
controller, providerService, useBDDP));
}
@Override
public void switchRemoved(Dpid dpid) {
LinkDiscovery ld = this.discoverers.remove(dpid);
LinkDiscovery ld = discoverers.remove(dpid);
if (ld != null) {
ld.removeAllPorts();
}
......@@ -122,10 +127,9 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
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);
/*
* remove port calls linkVanished
*/
ld.removePort(port);
}
......
......@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
*/
public class ONLabLddp extends LLDP {
private static final Logger log = LoggerFactory.getLogger(ONLabLddp.class);
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";
......