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);
+
     }
 
 }