Splitting Flow writing and packet dispatch(reactive flood). 42/10042/1
authorAmit Mandke <ammandke@cisco.com>
Mon, 18 Aug 2014 19:21:15 +0000 (12:21 -0700)
committerAmit Mandke <ammandke@cisco.com>
Mon, 18 Aug 2014 19:21:15 +0000 (12:21 -0700)
This would allow either to be enabled or disabled easily based on need.

Change-Id: I271a1f58ff8df916413aa1e20154c60fa2860784
Signed-off-by: Amit Mandke <ammandke@cisco.com>
l2switch-main/src/main/java/org/opendaylight/l2switch/L2SwitchProvider.java
l2switch-main/src/main/java/org/opendaylight/l2switch/flow/ReactiveFlowWriter.java [new file with mode: 0644]
l2switch-main/src/main/java/org/opendaylight/l2switch/packet/PacketDispatcher.java

index 4de284c438c7b528671189741a05f1520a767c38..157eae995aed68bacc7b5e43924dd72b9a91b7fc 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.controller.sal.binding.api.NotificationService;
 import org.opendaylight.l2switch.flow.FlowWriterService;
 import org.opendaylight.l2switch.flow.FlowWriterServiceImpl;
 import org.opendaylight.l2switch.flow.InitialFlowWriter;
+import org.opendaylight.l2switch.flow.ReactiveFlowWriter;
 import org.opendaylight.l2switch.inventory.InventoryReader;
 import org.opendaylight.l2switch.packet.ArpPacketHandler;
 import org.opendaylight.l2switch.packet.PacketDispatcher;
@@ -30,7 +31,7 @@ public class L2SwitchProvider extends AbstractBindingAwareConsumer
     implements AutoCloseable {
 
   private final static Logger _logger = LoggerFactory.getLogger(L2SwitchProvider.class);
-  private Registration listenerRegistration,invListenerReg;
+  private Registration listenerRegistration = null, invListenerReg = null, reactFlowWriterReg = null;
 
   /**
    * Setup the L2Switch.
@@ -42,7 +43,7 @@ public class L2SwitchProvider extends AbstractBindingAwareConsumer
     // Setup FlowWriterService
     DataBroker dataService = consumerContext.<DataBroker>getSALService(DataBroker.class);
     NotificationService notificationService = consumerContext.<NotificationService>getSALService(NotificationService.class);
-    SalFlowService  salFlowService = consumerContext.getRpcService(SalFlowService.class);
+    SalFlowService salFlowService = consumerContext.getRpcService(SalFlowService.class);
 
 
     FlowWriterService flowWriterService = new FlowWriterServiceImpl(salFlowService);
@@ -56,15 +57,17 @@ public class L2SwitchProvider extends AbstractBindingAwareConsumer
     PacketDispatcher packetDispatcher = new PacketDispatcher();
     packetDispatcher.setInventoryReader(inventoryReader);
     packetDispatcher.setPacketProcessingService(packetProcessingService);
-    packetDispatcher.setFlowWriterService(flowWriterService);
 
     // Setup ArpPacketHandler
     ArpPacketHandler arpPacketHandler = new ArpPacketHandler(packetDispatcher);
 
-
     // Register ArpPacketHandler
     this.listenerRegistration = notificationService.registerNotificationListener(arpPacketHandler);
 
+    //Setup reactive flow writer
+    ReactiveFlowWriter reactiveFlowWriter = new ReactiveFlowWriter(inventoryReader, flowWriterService);
+    reactFlowWriterReg = notificationService.registerNotificationListener(reactiveFlowWriter);
+
     //Write initial flows
     InitialFlowWriter initialFlowWriter = new InitialFlowWriter(salFlowService);
     //initialFlowWriter.registerAsNodeDataListener(dataService);
@@ -79,8 +82,11 @@ public class L2SwitchProvider extends AbstractBindingAwareConsumer
     if(listenerRegistration != null) {
       listenerRegistration.close();
     }
-    if(invListenerReg!=null) {
+    if(invListenerReg != null) {
       invListenerReg.close();
     }
+    if(reactFlowWriterReg != null) {
+      reactFlowWriterReg.close();
+    }
   }
 }
diff --git a/l2switch-main/src/main/java/org/opendaylight/l2switch/flow/ReactiveFlowWriter.java b/l2switch-main/src/main/java/org/opendaylight/l2switch/flow/ReactiveFlowWriter.java
new file mode 100644 (file)
index 0000000..33e5ba5
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opendaylight.l2switch.flow;
+
+import org.opendaylight.l2switch.inventory.InventoryReader;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.received.packet.chain.packet.ArpPacket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.packet.chain.packet.RawPacket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.received.packet.chain.packet.EthernetPacket;
+
+/**
+ * This class listens to certain type of packets and writes
+ * a mac to mac flows.
+ */
+public class ReactiveFlowWriter implements ArpPacketListener{
+  InventoryReader inventoryReader;
+  FlowWriterService flowWriterService;
+  public ReactiveFlowWriter(InventoryReader inventoryReader, FlowWriterService flowWriterService) {
+    this.inventoryReader = inventoryReader;
+    this.flowWriterService = flowWriterService;
+  }
+  @Override
+  public void onArpPacketReceived(ArpPacketReceived packetReceived) {
+    if(packetReceived==null || packetReceived.getPacketChain()==null) {
+      return;
+    }
+
+    RawPacket rawPacket = null;
+    EthernetPacket ethernetPacket = null;
+    ArpPacket arpPacket = null;
+    for (PacketChain packetChain : packetReceived.getPacketChain()) {
+      if (packetChain.getPacket() instanceof RawPacket) {
+        rawPacket = (RawPacket)packetChain.getPacket();
+      }
+      else if (packetChain.getPacket() instanceof EthernetPacket) {
+        ethernetPacket = (EthernetPacket)packetChain.getPacket();
+      }
+      else if (packetChain.getPacket() instanceof ArpPacket) {
+        arpPacket = (ArpPacket)packetChain.getPacket();
+      }
+    }
+    if (rawPacket==null || ethernetPacket==null || arpPacket==null) {
+      return;
+    }
+
+    writeFlows(packetReceived.getPayload(),
+        rawPacket.getIngress(),
+        ethernetPacket.getSourceMac(),
+        ethernetPacket.getDestinationMac());
+  }
+  /**
+   * Invokes flow writer service to write  bidirectional mac-mac flows on a switch.
+   * @param payload The payload to be sent.
+   * @param ingress The NodeConnector where the payload came from.
+   * @param srcMac The source MacAddress of the packet.
+   * @param destMac The destination MacAddress of the packet.
+   */
+  public void writeFlows(byte[] payload, NodeConnectorRef ingress, MacAddress srcMac, MacAddress destMac) {
+    inventoryReader.readInventory();
+
+    NodeConnectorRef destNodeConnector = inventoryReader.getNodeConnector(ingress.getValue().firstIdentifierOf(Node.class), destMac);
+    if (destNodeConnector != null) {
+      flowWriterService.addBidirectionalMacToMacFlows(srcMac, ingress, destMac, destNodeConnector);
+    }
+  }
+
+}
index d3e13eeecdc395f52f5f7e44380ba41466d9710f..4569898d80d1ac33810ed7dad416ebcee7570f00 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.l2switch.packet;
 
-import org.opendaylight.l2switch.flow.FlowWriterService;
 import org.opendaylight.l2switch.inventory.InventoryReader;
 import org.opendaylight.l2switch.util.InstanceIdentifierUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
@@ -35,16 +34,11 @@ public class PacketDispatcher  {
   private final static Logger _logger = LoggerFactory.getLogger(PacketDispatcher.class);
   private InventoryReader inventoryReader;
   private PacketProcessingService packetProcessingService;
-  private FlowWriterService flowWriterService;
 
   public void setPacketProcessingService(PacketProcessingService packetProcessingService) {
     this.packetProcessingService = packetProcessingService;
   }
 
-  public void setFlowWriterService(FlowWriterService flowWriterService) {
-    this.flowWriterService = flowWriterService;
-  }
-
   public void setInventoryReader(InventoryReader inventoryReader) {
     this.inventoryReader = inventoryReader;
   }
@@ -67,9 +61,6 @@ public class PacketDispatcher  {
       srcConnectorRef = inventoryReader.getControllerSwitchConnectors().get(nodeId);
     }
     NodeConnectorRef destNodeConnector = inventoryReader.getNodeConnector(ingress.getValue().firstIdentifierOf(Node.class), destMac);
-    if (destNodeConnector != null) {
-      flowWriterService.addBidirectionalMacToMacFlows(srcMac, ingress, destMac, destNodeConnector);
-    }
     if(srcConnectorRef!=null) {
       if(destNodeConnector != null) {
         sendPacketOut(payload, srcConnectorRef, destNodeConnector);