flowrules are pushed: we still have an intermittent hang though
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 b9ae4c4..ce85938 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;
@@ -9,6 +13,14 @@
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultTrafficSelector;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.FlowRule;
+import org.onlab.onos.net.flow.FlowRuleService;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.flow.criteria.Criteria;
import org.onlab.onos.net.flow.instructions.Instructions;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.packet.InboundPacket;
@@ -16,12 +28,9 @@
import org.onlab.onos.net.packet.PacketProcessor;
import org.onlab.onos.net.packet.PacketService;
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.
*/
@@ -39,6 +48,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowRuleService flowRuleService;
+
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
@Activate
@@ -62,6 +74,9 @@
@Override
public void process(PacketContext context) {
+ if (context.isHandled()) {
+ return;
+ }
InboundPacket pkt = context.inPacket();
HostId id = HostId.hostId(pkt.parsed().getDestinationMAC());
@@ -75,15 +90,16 @@
// Are we on an edge switch that our destination is on? If so,
// simply forward out to the destination and bail.
if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) {
- forward(context, dst.location().port());
+ installRule(context, dst.location().port());
return;
}
// Otherwise, get a set of paths that lead from here to the
// destination edge switch.
+
Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(),
- context.inPacket().receivedFrom().deviceId(),
- dst.location().deviceId());
+ context.inPacket().receivedFrom().deviceId(),
+ dst.location().deviceId());
if (paths.isEmpty()) {
// If there are no paths, flood and bail.
flood(context);
@@ -100,7 +116,7 @@
}
// Otherwise forward and be done with it.
- forward(context, path.src().port());
+ installRule(context, path.src().port());
}
}
@@ -118,18 +134,43 @@
// Floods the specified packet.
private void flood(PacketContext context) {
boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(),
- context.inPacket().receivedFrom());
+ context.inPacket().receivedFrom());
if (canBcast) {
- forward(context, PortNumber.FLOOD);
+ packetOutFlood(context);
} else {
context.block();
}
}
- // Forwards the packet to the specified port.
- private void forward(PacketContext context, PortNumber portNumber) {
+ //Floods a packet out
+ private void packetOutFlood(PacketContext context) {
+ context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD));
+ context.send();
+ }
+
+ // Install a rule forwarding the packet to the specified port.
+ private void installRule(PacketContext context, PortNumber portNumber) {
+ // we don't yet support bufferids in the flowservice so packet out and
+ // then install a flowmod.
context.treatmentBuilder().add(Instructions.createOutput(portNumber));
context.send();
+
+
+ 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()));
+
+ TrafficTreatment.Builder treat = new DefaultTrafficTreatment.Builder();
+ treat.add(Instructions.createOutput(portNumber));
+
+ FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
+ builder.build(), treat.build());
+
+ flowRuleService.applyFlowRules(f);
+
}
}