Merge "Added null check for reason Signed-off-by: Srikar Rajamani <srikar.rajamani...
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / translator / PacketInTranslator.java
index 5a37b40340f1fe3e38bfe26245054ceb4f6d8e02..236ae80e532d82924c4bf461b1d9258efe0ff8fd 100644 (file)
@@ -1,17 +1,15 @@
 package org.opendaylight.openflowplugin.openflow.md.core.translator;
 
 import java.math.BigInteger;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.opendaylight.openflowplugin.openflow.md.core.IMDMessageTranslator;
 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorImpl;
 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.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
 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;
@@ -20,9 +18,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 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.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.NoMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.InvalidTtl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;
 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;
 
@@ -33,7 +33,7 @@ public class PacketInTranslator implements IMDMessageTranslator<OfHeader, List<D
     @Override
     public List<DataObject> translate(SwitchConnectionDistinguisher cookie,
             SessionContext sc, OfHeader msg) {
-        if(msg instanceof PacketInMessage) {
+        if(sc !=null && msg instanceof PacketInMessage) {
             PacketInMessage message = (PacketInMessage)msg;
             List<DataObject> list = new CopyOnWriteArrayList<DataObject>();
             LOG.info("PacketIn: InPort: {} Cookie: {} Match.type: {}",
@@ -47,71 +47,77 @@ public class PacketInTranslator implements IMDMessageTranslator<OfHeader, List<D
 
            // 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());
+           // Make sure we actually have features, some naughty switches start sending packetIn before they send us the FeatureReply
+           if ( features != null) {
+               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();
-           list.add(pktInEvent);
-            return list;
-        } 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));
+    
+               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);
+               }
+               org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match match = 
+                          (org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match)
+                          MatchConvertorImpl.fromOFMatchToSALMatch(message.getMatch(),dpid);
+               pktInBuilder.setMatch((org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received.Match)match);
+               pktInBuilder.setPacketInReason(getPacketInReason(message.getReason()));
+               pktInBuilder.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(message.getTableId().getValue().shortValue()));
+               pktInBuilder.setIngress(InventoryDataServiceUtil.nodeConnectorRefFromDatapathIdPortno(dpid,port));
+               PacketReceived pktInEvent = pktInBuilder.build();
+               list.add(pktInEvent);
+               return list;
+           } 
+        } 
+        return Collections.emptyList();
     }
-
-    public static NodeConnectorId ncIDfromDPIDandPort(BigInteger dpid, Long port){
-        return new NodeConnectorId("openflow:"+dpid.toString()+":"+port.toString());
+    
+    private Class <?extends PacketInReason> getPacketInReason(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason reason) {
+       
+       if (null == reason) {
+               return PacketInReason.class;
+       }
+    
+       if (reason.equals(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason.OFPRNOMATCH)) {
+               return NoMatch.class;
+       }
+       else if (reason.equals(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason.OFPRINVALIDTTL)) {
+               return InvalidTtl.class;
+       }
+       else if (reason.equals(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason.OFPRACTION)) {
+               return SendToController.class;
+       }
+    
+       return PacketInReason.class;
     }
 }