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;
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;
@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: {}",
// 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;
}
}