alshabib

avoid other OF listeners overwriting the priority of another listener

......@@ -13,12 +13,13 @@ public final class PortNumber {
private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
public static final PortNumber FLOOD = new PortNumber(-1);
public static final PortNumber IN_PORT = new PortNumber(-2);
public static final PortNumber TABLE = new PortNumber(-3);
public static final PortNumber NORMAL = new PortNumber(-4);
public static final PortNumber IN_PORT = new PortNumber(-8);
public static final PortNumber TABLE = new PortNumber(-7);
public static final PortNumber NORMAL = new PortNumber(-6);
public static final PortNumber FLOOD = new PortNumber(-5);
public static final PortNumber ALL = new PortNumber(-4);
public static final PortNumber LOCAL = new PortNumber(-5);
public static final PortNumber LOCAL = new PortNumber(-2);
private final long number;
......
package org.onlab.onos.net.packet;
import java.util.concurrent.atomic.AtomicBoolean;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment.Builder;
......@@ -12,7 +14,7 @@ public abstract class DefaultPacketContext implements PacketContext {
private final OutboundPacket outPkt;
private final TrafficTreatment.Builder builder;
private boolean block = false;
private final AtomicBoolean block;
protected DefaultPacketContext(long time, InboundPacket inPkt,
......@@ -21,7 +23,7 @@ public abstract class DefaultPacketContext implements PacketContext {
this.time = time;
this.inPkt = inPkt;
this.outPkt = outPkt;
this.block = block;
this.block = new AtomicBoolean(block);
this.builder = new DefaultTrafficTreatment.Builder();
}
......@@ -49,13 +51,12 @@ public abstract class DefaultPacketContext implements PacketContext {
public abstract void send();
@Override
public void block() {
this.block = true;
public boolean blocked() {
return this.block.getAndSet(true);
}
@Override
public boolean isHandled() {
return this.block;
return this.block.get();
}
}
......
......@@ -43,14 +43,13 @@ public interface PacketContext {
/**
* Blocks the outbound packet from being sent from this point onward.
* @return whether the outbound packet is blocked.
*/
void block();
boolean blocked();
/**
* Indicates whether the packet has already been handled, i.e. sent or
* blocked.
*
* @return true if sent or blocked
* Check whether the outbound packet is blocked.
* @return
*/
boolean isHandled();
......
package org.onlab.onos.net.device;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DeviceId.deviceId;
import org.junit.Test;
import org.onlab.onos.event.AbstractEventTest;
import org.onlab.onos.net.DefaultDevice;
......@@ -9,9 +12,6 @@ import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.DeviceId.deviceId;
/**
* Tests of the device event.
*/
......@@ -19,23 +19,25 @@ public class DeviceEventTest extends AbstractEventTest {
private Device createDevice() {
return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"),
Device.Type.SWITCH, "box", "hw", "sw", "sn");
Device.Type.SWITCH, "box", "hw", "sw", "sn");
}
@Override
@Test
public void withTime() {
Device device = createDevice();
Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
Port port = new DefaultPort(device, PortNumber.portNumber(123), true);
DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
device, port, 123L);
device, port, 123L);
validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L);
assertEquals("incorrect port", port, event.port());
}
@Override
@Test
public void withoutTime() {
Device device = createDevice();
Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
Port port = new DefaultPort(device, PortNumber.portNumber(123), true);
long before = System.currentTimeMillis();
DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
long after = System.currentTimeMillis();
......
......@@ -3,6 +3,7 @@ package org.onlab.onos.of.controller;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
......@@ -18,7 +19,7 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
private final Logger log = getLogger(getClass());
private boolean free = true;
private final AtomicBoolean free = new AtomicBoolean(true);
private boolean isBuilt = false;
private final OpenFlowSwitch sw;
private final OFPacketIn pktin;
......@@ -30,14 +31,8 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
}
@Override
public void block() {
free = false;
}
@Override
public void send() {
if (free && isBuilt) {
block();
if (blocked() && isBuilt) {
sw.sendMsg(pktout);
}
}
......@@ -111,4 +106,9 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
return act;
}
@Override
public boolean blocked() {
return free.getAndSet(false);
}
}
......
......@@ -16,7 +16,7 @@ public interface OpenFlowPacketContext {
* Blocks further responses (ie. send() calls) on this
* packet in event.
*/
public void block();
public boolean blocked();
/**
* Provided build has been called send the packet
......
package org.onlab.onos.of.controller.impl;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
......@@ -27,6 +25,9 @@ import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
@Component(immediate = true)
@Service
public class OpenFlowControllerImpl implements OpenFlowController {
......@@ -44,7 +45,9 @@ public class OpenFlowControllerImpl implements OpenFlowController {
protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
protected Set<OpenFlowSwitchListener> ofEventListener = new HashSet<>();
protected Map<Integer, PacketListener> ofPacketListener = new TreeMap<>();
protected Multimap<Integer, PacketListener> ofPacketListener =
ArrayListMultimap.create();
private final Controller ctrl = new Controller();
......
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;
......@@ -13,9 +18,9 @@ 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.OpenFlowPacketContext;
import org.onlab.onos.of.controller.OpenFlowSwitch;
import org.onlab.onos.of.controller.OpenFlowSwitchListener;
import org.onlab.onos.of.controller.OpenFlowPacketContext;
import org.onlab.onos.of.controller.PacketListener;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
......@@ -23,11 +28,6 @@ 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.
......@@ -93,7 +93,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
return;
}
if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
pktCtx.block();
pktCtx.blocked();
}
}
......@@ -101,7 +101,7 @@ 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));
}
......
......@@ -2,6 +2,11 @@ package org.onlab.onos.provider.of.packet.impl;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.List;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.Instruction;
import org.onlab.onos.net.flow.Instruction.Type;
import org.onlab.onos.net.packet.DefaultPacketContext;
import org.onlab.onos.net.packet.InboundPacket;
import org.onlab.onos.net.packet.OutboundPacket;
......@@ -24,18 +29,36 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext {
@Override
public void send() {
if (!this.isHandled()) {
block();
if (!this.blocked()) {
if (outPacket() == null) {
ofPktCtx.build(OFPort.FLOOD);
sendBufferedPacket();
} else {
Ethernet eth = new Ethernet();
eth.deserialize(outPacket().data().array(), 0,
outPacket().data().array().length);
ofPktCtx.build(eth, OFPort.FLOOD);
}
ofPktCtx.send();
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void sendBufferedPacket() {
List<Instruction> ins = treatmentBuilder().build().instructions();
OFPort p = null;
//TODO: support arbitrary list of treatments
for (Instruction i : ins) {
if (i.type() == Type.OUTPUT) {
p = buildPort(((Instruction<PortNumber>) i).instruction());
break; //for now...
}
}
ofPktCtx.build(p);
ofPktCtx.send();
}
private OFPort buildPort(PortNumber port) {
return OFPort.of((int) port.toLong());
}
}
......