Worked Colin Dixon's PktIn into the Translator Framework 33/2833/2
authorEd Warnicke <eaw@cisco.com>
Mon, 18 Nov 2013 16:05:52 +0000 (10:05 -0600)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 18 Nov 2013 18:14:46 +0000 (18:14 +0000)
Change-Id: Iadd1b847abb2bdce0336f1b55f9f9735fd0272e9
Signed-off-by: Ed Warnicke <eaw@cisco.com>
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/MDController.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/PacketInTranslator.java [new file with mode: 0644]

index 0a9fcfe12b39ab8114a55e3d2ca34022801c6e74..1bb550f4e5d7110ca63f051fed798539dac1e33d 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.openflowplugin.openflow.md.core;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -25,13 +24,14 @@ import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHan
 import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider;
 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
 import org.opendaylight.openflowplugin.openflow.md.core.translator.ErrorTranslator;
+import org.opendaylight.openflowplugin.openflow.md.core.translator.PacketInTranslator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 
 /**
@@ -46,6 +46,9 @@ public class MDController implements IMDController {
 
     private ConcurrentMap<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, DataObject>>> messageTranslators;
 
+    final private int OF10 = 1;
+    final private int OF13 = 4;
+
     /**
      * @return translator mapping
      */
@@ -59,9 +62,10 @@ public class MDController implements IMDController {
     public void init() {
         LOG.debug("Initializing!");
         messageTranslators = new ConcurrentHashMap<>();
-        addMessageTranslator(ErrorMessage.class, 4, new ErrorTranslator());
-        addMessageTranslator(ErrorMessage.class, 1, new ErrorTranslator());
-        
+        addMessageTranslator(ErrorMessage.class, OF10, new ErrorTranslator());
+        addMessageTranslator(ErrorMessage.class, OF13, new ErrorTranslator());
+        addMessageTranslator(PacketInMessage.class,OF10, new PacketInTranslator());
+        addMessageTranslator(PacketInMessage.class,OF13, new PacketInTranslator());
         // Push the updated Listeners to Session Manager which will be then picked up by ConnectionConductor eventually
         OFSessionUtil.getSessionManager().setTranslatorMapping(messageTranslators);
     }
@@ -138,7 +142,7 @@ public class MDController implements IMDController {
     @Override
     public void addMessageTranslator(Class<? extends DataObject> messageType, int version, IMDMessageTranslator<OfHeader, DataObject> translator) {
         TranslatorKey tKey = new TranslatorKey(version, messageType.getName());
-        
+
         Collection<IMDMessageTranslator<OfHeader, DataObject>> existingValues = messageTranslators.get(tKey);
         if (existingValues == null) {
             existingValues = new ArrayList<>();
diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/PacketInTranslator.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/translator/PacketInTranslator.java
new file mode 100644 (file)
index 0000000..e0944c3
--- /dev/null
@@ -0,0 +1,114 @@
+package org.opendaylight.openflowplugin.openflow.md.core.translator;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
+import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.Cookie;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceivedBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PacketInTranslator implements IMDMessageTranslator<OfHeader, DataObject> {
+
+    protected static final Logger LOG = LoggerFactory
+            .getLogger(PacketInTranslator.class);
+    @Override
+    public PacketReceived translate(SwitchConnectionDistinguisher cookie,
+            SessionContext sc, OfHeader msg) {
+        if(msg instanceof PacketInMessage) {
+            PacketInMessage message = (PacketInMessage)msg;
+            LOG.info("PacketIn: InPort: {} Cookie: {} Match.type: {}",
+                    message.getInPort(), message.getCookie(),
+                    message.getMatch() != null ? message.getMatch().getType()
+                                              : message.getMatch());
+
+           // create a packet received event builder
+           PacketReceivedBuilder pktInBuilder = new PacketReceivedBuilder();
+           pktInBuilder.setPayload(message.getData());
+
+           // get the DPID
+           GetFeaturesOutput features = sc.getFeatures();
+           BigInteger dpid = features.getDatapathId();
+
+           // get the Cookie if it exists
+           if(message.getCookie() != null) {
+               pktInBuilder.setCookie(new Cookie(message.getCookie().longValue()));
+           }
+
+           // extract the port number
+           Long port = null;
+
+           if (message.getInPort() != null) {
+               // this doesn't work--at least for OF1.3
+               port = message.getInPort().longValue();
+           }
+
+           // this should work for OF1.3
+           if (message.getMatch() != null && message.getMatch().getMatchEntries() != null) {
+               List<MatchEntries> entries = message.getMatch().getMatchEntries();
+               for (MatchEntries entry : entries) {
+                   PortNumberMatchEntry tmp = entry.getAugmentation(PortNumberMatchEntry.class);
+                   if (tmp != null) {
+                       if (port == null) {
+                           port = tmp.getPortNumber().getValue();
+                       } else {
+                           LOG.warn("Multiple input ports (at least {} and {})",
+                                    port, tmp.getPortNumber().getValue());
+                       }
+                   }
+               }
+           }
+
+           if (port == null) {
+               // no incoming port, so drop the event
+               LOG.warn("Received packet_in, but couldn't find an input port");
+               return null;
+           }else{
+               LOG.info("Receive packet_in from {} on port {}", dpid, port);
+           }
+
+           //TODO: need to get the NodeConnectorRef, but NodeConnectors aren't there yet
+           InstanceIdentifier<NodeConnector> nci = ncIndentifierFromDPIDandPort(dpid, port);
+           NodeConnectorRef ncr = new NodeConnectorRef(nci);
+           PacketReceived pktInEvent = pktInBuilder.build();
+            return pktInEvent;
+        } else {
+            return null;
+        }
+    }
+
+    public static InstanceIdentifier<NodeConnector> ncIndentifierFromDPIDandPort(BigInteger dpid, Long port) {
+        InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder().node(Node.class);
+
+        // TODO: this doesn't work yet, needs to actaully get the ref for the real NodeConnector
+        //       but that doesn't exist yet
+        NodeConnectorKey ncKey = ncKeyFromDPIDandPort(dpid, port);
+        return builder.node(NodeConnector.class, ncKey).toInstance();
+    }
+
+
+    public static NodeConnectorKey ncKeyFromDPIDandPort(BigInteger dpid, Long port){
+        return new NodeConnectorKey(ncIDfromDPIDandPort(dpid, port));
+    }
+
+    public static NodeConnectorId ncIDfromDPIDandPort(BigInteger dpid, Long port){
+        return new NodeConnectorId("openflow:"+dpid.toString()+":"+port.toString());
+    }
+}