alshabib

very basic broken reactive forwarding; nit yet using treatments, but rather defa…

…ulting to flood for everything

generates a ton of duplicates for now
package org.onlab.onos.net.flow;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.onlab.onos.net.PortNumber;
import org.slf4j.Logger;
@SuppressWarnings("rawtypes")
public class DefaultTrafficTreatment implements TrafficTreatment {
private final List<Instruction> instructions;
public DefaultTrafficTreatment(List<Instruction> instructions) {
this.instructions = Collections.unmodifiableList(instructions);
}
@Override
public List<Instruction> instructions() {
return instructions;
}
/**
* Builds a list of treatments following the following order.
* Modifications -> Group -> Output (including drop)
*
*/
public static class Builder implements TrafficTreatment.Builder {
private final Logger log = getLogger(getClass());
List<Instruction<PortNumber>> outputs = new LinkedList<>();
// TODO: should be a list of instructions based on group objects
List<Instruction<Object>> groups = new LinkedList<>();
// TODO: should be a list of instructions based on modification objects
List<Instruction<Object>> modifications = new LinkedList<>();
@SuppressWarnings("unchecked")
@Override
public Builder add(Instruction instruction) {
switch (instruction.type()) {
case OUTPUT:
case DROP:
// TODO: should check that there is only one drop instruction.
outputs.add(instruction);
break;
case MODIFICATION:
// TODO: enforce modification order if any
modifications.add(instruction);
case GROUP:
groups.add(instruction);
default:
log.warn("Unknown instruction type {}", instruction.type());
}
return this;
}
@Override
public TrafficTreatment build() {
List<Instruction> instructions = new LinkedList<Instruction>();
instructions.addAll(modifications);
instructions.addAll(groups);
instructions.addAll(outputs);
return new DefaultTrafficTreatment(instructions);
}
}
}
......@@ -2,8 +2,9 @@ package org.onlab.onos.net.flow;
/**
* Abstraction of a single traffic treatment step.
* @param <T> the type parameter for the instruction
*/
public interface Instruction {
public interface Instruction<T> {
/**
* Represents the type of traffic treatment.
......@@ -33,4 +34,17 @@ public interface Instruction {
// TODO: Create factory class 'Instructions' that will have various factory
// to create specific instructions.
/**
* Returns the type of instruction not to be confused
* with the instruction's java type.
* @return type of instruction
*/
public Type type();
/**
* Returns the actual value of the instruction.
* @return the value for this instruction
*/
public T instruction();
}
......
......@@ -8,8 +8,7 @@ import org.onlab.onos.net.PortNumber;
public final class Instructions {
// Ban construction
private Instructions() {
}
private Instructions() {}
/**
* Creates an output instruction using the specified port number. This can
......@@ -18,8 +17,20 @@ public final class Instructions {
* @param number port number
* @return output instruction
*/
public static Instruction createOutput(PortNumber number) {
return null;
public static Instruction<PortNumber> createOutput(final PortNumber number) {
return new Instruction<PortNumber>() {
@Override
public Instruction.Type type() {
return Type.OUTPUT;
}
@Override
public PortNumber instruction() {
return number;
}
};
}
// TODO: add create methods
......
package org.onlab.onos.net.packet;
import com.google.common.base.MoreObjects;
import java.nio.ByteBuffer;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.TrafficTreatment;
import java.nio.ByteBuffer;
import com.google.common.base.MoreObjects;
/**
* Default implementation of an immutable outbound packet.
......@@ -22,7 +23,7 @@ public class DefaultOutboundPacket implements OutboundPacket {
* @param data raw packet data
*/
public DefaultOutboundPacket(DeviceId sendThrough,
TrafficTreatment treatment, ByteBuffer data) {
TrafficTreatment treatment, ByteBuffer data) {
this.sendThrough = sendThrough;
this.treatment = treatment;
this.data = data;
......
package org.onlab.onos.net.packet;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment.Builder;
public abstract class DefaultPacketContext implements PacketContext {
private final long time;
private final InboundPacket inPkt;
private final OutboundPacket outPkt;
private final TrafficTreatment.Builder builder;
private boolean block = false;
protected DefaultPacketContext(long time, InboundPacket inPkt,
OutboundPacket outPkt, boolean block) {
super();
......@@ -15,6 +22,7 @@ public abstract class DefaultPacketContext implements PacketContext {
this.inPkt = inPkt;
this.outPkt = outPkt;
this.block = block;
this.builder = new DefaultTrafficTreatment.Builder();
}
@Override
......@@ -33,6 +41,11 @@ public abstract class DefaultPacketContext implements PacketContext {
}
@Override
public Builder treatmentBuilder() {
return builder;
}
@Override
public abstract void send();
@Override
......
......@@ -2,6 +2,8 @@ package org.onlab.onos.net.trivial.packet.impl;
import static org.slf4j.LoggerFactory.getLogger;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.Instructions;
import org.onlab.onos.net.packet.PacketContext;
import org.onlab.onos.net.packet.PacketProcessor;
import org.slf4j.Logger;
......@@ -12,7 +14,8 @@ public class ReactivePacketProcessor implements PacketProcessor {
@Override
public void process(PacketContext context) {
log.info("Packet reveived {}", context.inPacket());
context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD));
context.send();
}
}
......
package org.onlab.onos.of.controller;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import org.onlab.packet.Ethernet;
......@@ -10,9 +12,12 @@ import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.slf4j.Logger;
public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
private final Logger log = getLogger(getClass());
private boolean free = true;
private boolean isBuilt = false;
private final OpenFlowSwitch sw;
......@@ -32,8 +37,8 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
@Override
public void send() {
if (free && isBuilt) {
sw.sendMsg(pktout);
block();
sw.sendMsg(pktout);
}
}
......
......@@ -15,6 +15,7 @@ import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.of.controller.DefaultOpenFlowPacketContext;
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.PacketListener;
......@@ -106,7 +107,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
@Override
public void removePacketListener(PacketListener listener) {
ofPacketListener.remove(listener);
ofPacketListener.values().remove(listener);
}
@Override
......@@ -123,10 +124,11 @@ public class OpenFlowControllerImpl implements OpenFlowController {
}
break;
case PACKET_IN:
OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext
.packetContextFromPacketIn(this.getSwitch(dpid),
(OFPacketIn) msg);
for (PacketListener p : ofPacketListener.values()) {
p.handlePacket(DefaultOpenFlowPacketContext
.packetContextFromPacketIn(this.getSwitch(dpid),
(OFPacketIn) msg));
p.handlePacket(pktCtx);
}
break;
default:
......
package org.onlab.onos.provider.of.packet.impl;
import static org.slf4j.LoggerFactory.getLogger;
import org.onlab.onos.net.packet.DefaultPacketContext;
import org.onlab.onos.net.packet.InboundPacket;
import org.onlab.onos.net.packet.OutboundPacket;
import org.onlab.onos.of.controller.OpenFlowPacketContext;
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.types.OFPort;
import org.slf4j.Logger;
public class OpenFlowCorePacketContext extends DefaultPacketContext {
private final Logger log = getLogger(getClass());
private final OpenFlowPacketContext ofPktCtx;
protected OpenFlowCorePacketContext(long time, InboundPacket inPkt,
OutboundPacket outPkt, boolean block, OpenFlowPacketContext ofPktCtx) {
super(time, inPkt, outPkt, block);
this.ofPktCtx = ofPktCtx;
}
@Override
public void send() {
if (!this.isHandled()) {
block();
if (outPacket() == null) {
ofPktCtx.build(OFPort.FLOOD);
} else {
Ethernet eth = new Ethernet();
eth.deserialize(outPacket().data().array(), 0,
outPacket().data().array().length);
ofPktCtx.build(eth, OFPort.FLOOD);
}
ofPktCtx.send();
}
}
}
......@@ -78,7 +78,6 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
*/
private class InternalPacketProvider implements PacketListener {
@Override
public void handlePacket(OpenFlowPacketContext pktCtx) {
DeviceId id = DeviceId.deviceId(Dpid.uri(pktCtx.dpid().value()));
......@@ -88,8 +87,7 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
pktCtx.parsed(), ByteBuffer.wrap(pktCtx.unparsed()));
OpenFlowCorePacketContext corePktCtx =
new OpenFlowCorePacketContext(0, inPkt, null, false, pktCtx,
controller.getSwitch(pktCtx.dpid()));
new OpenFlowCorePacketContext(0, inPkt, null, false, pktCtx);
providerService.processPacket(corePktCtx);
}
......