diff --git a/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java b/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java index 6856e1aff9..abbba9960f 100644 --- a/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java +++ b/apps/fwd/src/main/java/org/onlab/onos/fwd/ReactiveForwarding.java @@ -1,5 +1,9 @@ package org.onlab.onos.fwd; +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; @@ -27,10 +31,6 @@ import org.onlab.onos.net.topology.TopologyService; import org.onlab.packet.Ethernet; import org.slf4j.Logger; -import java.util.Set; - -import static org.slf4j.LoggerFactory.getLogger; - /** * Sample reactive forwarding application. */ @@ -101,8 +101,8 @@ public class ReactiveForwarding { // Otherwise, get a set of paths that lead from here to the // destination edge switch. Set paths = topologyService.getPaths(topologyService.currentTopology(), - pkt.receivedFrom().deviceId(), - dst.location().deviceId()); + pkt.receivedFrom().deviceId(), + dst.location().deviceId()); if (paths.isEmpty()) { // If there are no paths, flood and bail. flood(context); @@ -114,8 +114,8 @@ public class ReactiveForwarding { Path path = pickForwardPath(paths, pkt.receivedFrom().port()); if (path == null) { log.warn("Doh... don't know where to go... {} -> {} received on {}", - ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(), - pkt.receivedFrom().port()); + ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(), + pkt.receivedFrom()); flood(context); return; } @@ -139,7 +139,7 @@ public class ReactiveForwarding { // Floods the specified packet if permissible. private void flood(PacketContext context) { if (topologyService.isBroadcastPoint(topologyService.currentTopology(), - context.inPacket().receivedFrom())) { + context.inPacket().receivedFrom())) { packetOut(context, PortNumber.FLOOD); } else { context.block(); @@ -161,15 +161,15 @@ public class ReactiveForwarding { Ethernet inPkt = context.inPacket().parsed(); TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder(); builder.add(Criteria.matchEthType(inPkt.getEtherType())) - .add(Criteria.matchEthSrc(inPkt.getSourceMAC())) - .add(Criteria.matchEthDst(inPkt.getDestinationMAC())) - .add(Criteria.matchInPort(context.inPacket().receivedFrom().port())); + .add(Criteria.matchEthSrc(inPkt.getSourceMAC())) + .add(Criteria.matchEthDst(inPkt.getDestinationMAC())) + .add(Criteria.matchInPort(context.inPacket().receivedFrom().port())); TrafficTreatment.Builder treat = new DefaultTrafficTreatment.Builder(); treat.add(Instructions.createOutput(portNumber)); FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), - builder.build(), treat.build(), 0); + builder.build(), treat.build(), 0); flowRuleService.applyFlowRules(f); } diff --git a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java index f419d24ffa..4cd29c4455 100644 --- a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java +++ b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java @@ -25,9 +25,12 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext private final OFPacketIn pktin; private OFPacketOut pktout = null; + private final boolean isBuffered; + private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) { this.sw = s; this.pktin = pkt; + this.isBuffered = pktin.getBufferId() != OFBufferId.NO_BUFFER; } @Override @@ -117,4 +120,9 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext return !free.get(); } + @Override + public boolean isBuffered() { + return isBuffered; + } + } diff --git a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/OpenFlowPacketContext.java b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/OpenFlowPacketContext.java index 85ea70a95b..0a20794423 100644 --- a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/OpenFlowPacketContext.java +++ b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/OpenFlowPacketContext.java @@ -67,4 +67,10 @@ public interface OpenFlowPacketContext { * @return the port */ public Integer inPort(); + + /** + * Indicates that this packet is buffered at the switch. + * @return buffer indication + */ + boolean isBuffered(); } diff --git a/providers/openflow/host/src/test/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProviderTest.java b/providers/openflow/host/src/test/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProviderTest.java index 78c2e414e1..cb37b1cc97 100644 --- a/providers/openflow/host/src/test/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProviderTest.java +++ b/providers/openflow/host/src/test/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProviderTest.java @@ -225,5 +225,10 @@ public class OpenFlowHostProviderTest { return false; } + @Override + public boolean isBuffered() { + return false; + } + } } diff --git a/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java b/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java index 248e17d51f..e7c4443249 100644 --- a/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java +++ b/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java @@ -32,18 +32,19 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { public void send() { if (!this.block()) { if (outPacket() == null) { - sendBufferedPacket(); + sendPacket(null); } else { Ethernet eth = new Ethernet(); eth.deserialize(outPacket().data().array(), 0, outPacket().data().array().length); - ofPktCtx.build(eth, OFPort.FLOOD); + sendPacket(eth); + } } } - private void sendBufferedPacket() { + private void sendPacket(Ethernet eth) { List ins = treatmentBuilder().build().instructions(); OFPort p = null; //TODO: support arbitrary list of treatments must be supported in ofPacketContext @@ -53,10 +54,13 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { break; //for now... } } - ofPktCtx.build(p); + if (eth == null) { + ofPktCtx.build(p); + } else { + ofPktCtx.build(eth, p); + } ofPktCtx.send(); } - private OFPort buildPort(PortNumber port) { return OFPort.of((int) port.toLong()); } diff --git a/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java b/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java index 8ce94b5683..feedd886e1 100644 --- a/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java +++ b/providers/openflow/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java @@ -1,5 +1,6 @@ package org.onlab.onos.provider.of.packet.impl; +import static org.onlab.onos.openflow.controller.RoleState.SLAVE; import static org.slf4j.LoggerFactory.getLogger; import java.nio.ByteBuffer; @@ -16,6 +17,7 @@ import org.onlab.onos.net.PortNumber; import org.onlab.onos.net.flow.instructions.Instruction; import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction; import org.onlab.onos.net.packet.DefaultInboundPacket; +import org.onlab.onos.net.packet.DefaultOutboundPacket; import org.onlab.onos.net.packet.OutboundPacket; import org.onlab.onos.net.packet.PacketProvider; import org.onlab.onos.net.packet.PacketProviderRegistry; @@ -36,8 +38,6 @@ import org.projectfloodlight.openflow.types.OFBufferId; import org.projectfloodlight.openflow.types.OFPort; import org.slf4j.Logger; -import static org.onlab.onos.openflow.controller.RoleState.*; - /** * Provider which uses an OpenFlow controller to detect network @@ -152,9 +152,15 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr new ConnectPoint(id, PortNumber.portNumber(pktCtx.inPort())), pktCtx.parsed(), ByteBuffer.wrap(pktCtx.unparsed())); + DefaultOutboundPacket outPkt = null; + if (!pktCtx.isBuffered()) { + outPkt = new DefaultOutboundPacket(id, null, + ByteBuffer.wrap(pktCtx.unparsed())); + } + OpenFlowCorePacketContext corePktCtx = new OpenFlowCorePacketContext(System.currentTimeMillis(), - inPkt, null, pktCtx.isHandled(), pktCtx); + inPkt, outPkt, pktCtx.isHandled(), pktCtx); providerService.processPacket(corePktCtx); }