Fixed a bug that failed specifying the value 0 on VLAN ID field for a match condition...
[controller.git] / opendaylight / protocol_plugins / openflow / src / main / java / org / opendaylight / controller / protocol_plugin / openflow / internal / FlowConverter.java
index 407535f5cea3cbef03dcbb85121a14c4d553175d..2b8f6553d61cb6202f0576b92b4b5890bc30e7f5 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -17,29 +16,6 @@ import java.util.List;
 
 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod;
 import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFVendor;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
-import org.openflow.protocol.action.OFActionDataLayerSource;
-import org.openflow.protocol.action.OFActionNetworkLayerAddress;
-import org.openflow.protocol.action.OFActionNetworkLayerDestination;
-import org.openflow.protocol.action.OFActionNetworkLayerSource;
-import org.openflow.protocol.action.OFActionNetworkTypeOfService;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.protocol.action.OFActionTransportLayer;
-import org.openflow.protocol.action.OFActionTransportLayerDestination;
-import org.openflow.protocol.action.OFActionTransportLayerSource;
-import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
-import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
-import org.openflow.util.U16;
-import org.openflow.util.U32;
-
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.Controller;
@@ -68,14 +44,45 @@ import org.opendaylight.controller.sal.match.MatchField;
 import org.opendaylight.controller.sal.match.MatchType;
 import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
+import org.openflow.protocol.OFVendor;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionDataLayer;
+import org.openflow.protocol.action.OFActionDataLayerDestination;
+import org.openflow.protocol.action.OFActionDataLayerSource;
+import org.openflow.protocol.action.OFActionNetworkLayerAddress;
+import org.openflow.protocol.action.OFActionNetworkLayerDestination;
+import org.openflow.protocol.action.OFActionNetworkLayerSource;
+import org.openflow.protocol.action.OFActionNetworkTypeOfService;
+import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.protocol.action.OFActionStripVirtualLan;
+import org.openflow.protocol.action.OFActionTransportLayer;
+import org.openflow.protocol.action.OFActionTransportLayerDestination;
+import org.openflow.protocol.action.OFActionTransportLayerSource;
+import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
+import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
+import org.openflow.util.U16;
+import org.openflow.util.U32;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Utility class for converting a SAL Flow into the OF flow and vice-versa
- *
- *
- *
  */
 public class FlowConverter {
+    protected static final Logger logger = LoggerFactory
+            .getLogger(FlowConverter.class);
+
+    /*
+     * The value 0xffff (OFP_VLAN_NONE) is used to indicate
+     * that no VLAN ID is set for OF Flow.
+     */
+    private static final short OFP_VLAN_NONE = (short) 0xffff;
+
     private Flow flow; // SAL Flow
     private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match
     private List<OFAction> actionsList; // OF 1.0 actions
@@ -99,7 +106,8 @@ public class FlowConverter {
     }
 
     /**
-     * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions form (V6Match)
+     * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
+     * form (V6Match)
      *
      * @return
      */
@@ -142,6 +150,9 @@ public class FlowConverter {
             if (match.isPresent(MatchType.DL_VLAN)) {
                 short vlan = (Short) match.getField(MatchType.DL_VLAN)
                         .getValue();
+                if (vlan == MatchType.DL_VLAN_NONE) {
+                    vlan = OFP_VLAN_NONE;
+                }
                 if (!isIPv6) {
                     ofMatch.setDataLayerVirtualLan(vlan);
                     wildcards &= ~OFMatch.OFPFW_DL_VLAN;
@@ -172,12 +183,17 @@ public class FlowConverter {
                 }
             }
             if (match.isPresent(MatchType.NW_TOS)) {
+                /*
+                 * OF 1.0 switch expects the TOS as the 6 msb in the byte. it is
+                 * actually the DSCP field followed by a zero ECN
+                 */
                 byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue();
+                byte dscp = (byte) (tos << 2);
                 if (!isIPv6) {
-                    ofMatch.setNetworkTypeOfService(tos);
+                    ofMatch.setNetworkTypeOfService(dscp);
                     wildcards &= ~OFMatch.OFPFW_NW_TOS;
                 } else {
-                    ((V6Match) ofMatch).setNetworkTypeOfService(tos, (byte) 0);
+                    ((V6Match) ofMatch).setNetworkTypeOfService(dscp, (byte) 0);
                 }
             }
             if (match.isPresent(MatchType.NW_PROTO)) {
@@ -191,35 +207,23 @@ public class FlowConverter {
                 }
             }
             if (match.isPresent(MatchType.NW_SRC)) {
-                InetAddress address = (InetAddress) match.getField(
-                        MatchType.NW_SRC).getValue();
-                InetAddress mask = (InetAddress) match.getField(
-                        MatchType.NW_SRC).getMask();
+                InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
+                InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
                 if (!isIPv6) {
-                    ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
-                            .getAddress()));
-                    int maskLength = NetUtils
-                            .getSubnetMaskLength((mask == null) ? null : mask
-                                    .getAddress());
-                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
-                            | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
+                    ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
+                    int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
                 } else {
                     ((V6Match) ofMatch).setNetworkSource(address, mask);
                 }
             }
             if (match.isPresent(MatchType.NW_DST)) {
-                InetAddress address = (InetAddress) match.getField(
-                        MatchType.NW_DST).getValue();
-                InetAddress mask = (InetAddress) match.getField(
-                        MatchType.NW_DST).getMask();
+                InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
+                InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
                 if (!isIPv6) {
-                    ofMatch.setNetworkDestination(NetUtils
-                            .byteArray4ToInt(address.getAddress()));
-                    int maskLength = NetUtils
-                            .getSubnetMaskLength((mask == null) ? null : mask
-                                    .getAddress());
-                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
-                            | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
+                    ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
+                    int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
                 } else {
                     ((V6Match) ofMatch).setNetworkDestination(address, mask);
                 }
@@ -250,12 +254,14 @@ public class FlowConverter {
                 ofMatch.setWildcards(U32.t(Long.valueOf(wildcards)));
             }
         }
-
+        logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(),
+                ofMatch);
         return ofMatch;
     }
 
     /**
      * Returns the list of actions in OF 1.0 form
+     *
      * @return
      */
     public List<OFAction> getOFActions() {
@@ -298,7 +304,8 @@ public class FlowConverter {
                 if (action.getType() == ActionType.CONTROLLER) {
                     OFActionOutput ofAction = new OFActionOutput();
                     ofAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
-                    // We want the whole frame hitting the match be sent to the controller
+                    // We want the whole frame hitting the match be sent to the
+                    // controller
                     ofAction.setMaxLength((short) 0xffff);
                     actionsList.add(ofAction);
                     actionsLength += OFActionOutput.MINIMUM_LENGTH;
@@ -346,7 +353,7 @@ public class FlowConverter {
                     OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
                     ofAction.setDataLayerAddress(a.getDlAddress());
                     actionsList.add(ofAction);
-                    actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
+                    actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
                     continue;
                 }
                 if (action.getType() == ActionType.SET_DL_DST) {
@@ -354,7 +361,7 @@ public class FlowConverter {
                     OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
                     ofAction.setDataLayerAddress(a.getDlAddress());
                     actionsList.add(ofAction);
-                    actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
+                    actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
                     continue;
                 }
                 if (action.getType() == ActionType.SET_NW_SRC) {
@@ -403,24 +410,26 @@ public class FlowConverter {
                     continue;
                 }
                 if (action.getType() == ActionType.SET_NEXT_HOP) {
-                    //TODO
+                    logger.info("Unsupported action: {}", action);
                     continue;
                 }
             }
         }
+        logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(),
+                actionsList);
         return actionsList;
     }
 
     /**
-     * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or
-     * to an OF 1.0 + IPv6 extension (V6FlowMod) Flow modifier Message
+     * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 +
+     * IPv6 extension (V6FlowMod) Flow modifier Message
      *
      * @param sw
      * @param command
      * @param port
      * @return
      */
-    public OFMessage getOFFlowMod(/*ISwitch sw, */short command, OFPort port) {
+    public OFMessage getOFFlowMod(short command, OFPort port) {
         OFMessage fm = (isIPv6) ? new V6FlowMod() : new OFFlowMod();
         if (this.ofMatch == null) {
             getOFMatch();
@@ -442,6 +451,14 @@ public class FlowConverter {
             if (port != null) {
                 ((OFFlowMod) fm).setOutPort(port);
             }
+            if (command == OFFlowMod.OFPFC_ADD
+                    || command == OFFlowMod.OFPFC_MODIFY
+                    || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
+                if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
+                    // Instruct switch to let controller know when flow expires
+                    ((OFFlowMod) fm).setFlags((short) 1);
+                }
+            }
         } else {
             ((V6FlowMod) fm).setVendor();
             ((V6FlowMod) fm).setMatch((V6Match) ofMatch);
@@ -458,7 +475,18 @@ public class FlowConverter {
             if (port != null) {
                 ((V6FlowMod) fm).setOutPort(port);
             }
+            if (command == OFFlowMod.OFPFC_ADD
+                    || command == OFFlowMod.OFPFC_MODIFY
+                    || command == OFFlowMod.OFPFC_MODIFY_STRICT) {
+                if (flow.getIdleTimeout() != 0 || flow.getHardTimeout() != 0) {
+                    // Instruct switch to let controller know when flow expires
+                    ((V6FlowMod) fm).setFlags((short) 1);
+                }
+            }
         }
+        logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
+                actionsList);
+        logger.trace("Openflow Mod Message: {}", fm);
         return fm;
     }
 
@@ -467,16 +495,16 @@ public class FlowConverter {
             Match salMatch = new Match();
 
             /*
-             * Installed flow may not have a Match defined
-             * like in case of a drop all flow
+             * Installed flow may not have a Match defined like in case of a
+             * drop all flow
              */
             if (ofMatch != null) {
                 if (!isIPv6) {
                     // Compute OF1.0 Match
-                    if (ofMatch.getInputPort() != 0) {
+                    if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createNodeConnector(
-                                        (Short) ofMatch.getInputPort(), node)));
+                                        ofMatch.getInputPort(), node)));
                     }
                     if (ofMatch.getDataLayerSource() != null
                             && !NetUtils
@@ -496,9 +524,13 @@ public class FlowConverter {
                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
                                 ofMatch.getDataLayerType()));
                     }
-                    if (ofMatch.getDataLayerVirtualLan() != 0) {
+                    short vlan = ofMatch.getDataLayerVirtualLan();
+                    if (vlan != 0) {
+                        if (vlan == OFP_VLAN_NONE) {
+                            vlan = MatchType.DL_VLAN_NONE;
+                        }
                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
-                                ofMatch.getDataLayerVirtualLan()));
+                                vlan));
                     }
                     if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) {
                         salMatch.setField(MatchType.DL_VLAN_PR, ofMatch
@@ -507,45 +539,44 @@ public class FlowConverter {
                     if (ofMatch.getNetworkSource() != 0) {
                         salMatch.setField(MatchType.NW_SRC, NetUtils
                                 .getInetAddress(ofMatch.getNetworkSource()),
-                                NetUtils.getInetNetworkMask(ofMatch
-                                        .getNetworkSourceMaskLen(), false));
+                                NetUtils.getInetNetworkMask(
+                                        ofMatch.getNetworkSourceMaskLen(),
+                                        false));
                     }
                     if (ofMatch.getNetworkDestination() != 0) {
-                        salMatch
-                                .setField(
-                                        MatchType.NW_DST,
-                                        NetUtils.getInetAddress(ofMatch
-                                                .getNetworkDestination()),
-                                        NetUtils
-                                                .getInetNetworkMask(
-                                                        ofMatch
-                                                                .getNetworkDestinationMaskLen(),
-                                                        false));
+                        salMatch.setField(MatchType.NW_DST,
+                                NetUtils.getInetAddress(ofMatch
+                                        .getNetworkDestination()),
+                                NetUtils.getInetNetworkMask(
+                                        ofMatch.getNetworkDestinationMaskLen(),
+                                        false));
                     }
                     if (ofMatch.getNetworkTypeOfService() != 0) {
-                        salMatch.setField(MatchType.NW_TOS, ofMatch
+                        int dscp = NetUtils.getUnsignedByte(ofMatch
                                 .getNetworkTypeOfService());
+                        byte tos = (byte) (dscp >> 2);
+                        salMatch.setField(MatchType.NW_TOS, tos);
                     }
                     if (ofMatch.getNetworkProtocol() != 0) {
-                        salMatch.setField(MatchType.NW_PROTO, ofMatch
-                                .getNetworkProtocol());
+                        salMatch.setField(MatchType.NW_PROTO,
+                                ofMatch.getNetworkProtocol());
                     }
                     if (ofMatch.getTransportSource() != 0) {
-                        salMatch.setField(MatchType.TP_SRC, ((Short) ofMatch
-                                .getTransportSource()));
+                        salMatch.setField(MatchType.TP_SRC,
+                                ofMatch.getTransportSource());
                     }
                     if (ofMatch.getTransportDestination() != 0) {
-                        salMatch.setField(MatchType.TP_DST, ((Short) ofMatch
-                                .getTransportDestination()));
+                        salMatch.setField(MatchType.TP_DST,
+                                ofMatch.getTransportDestination());
                     }
                 } else {
                     // Compute OF1.0 + IPv6 extensions Match
                     V6Match v6Match = (V6Match) ofMatch;
-                    if (v6Match.getInputPort() != 0) {
+                    if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
                         // Mask on input port is not defined
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createOFNodeConnector(
-                                        (Short) v6Match.getInputPort(), node)));
+                                        v6Match.getInputPort(), node)));
                     }
                     if (v6Match.getDataLayerSource() != null
                             && !NetUtils
@@ -565,39 +596,60 @@ public class FlowConverter {
                         salMatch.setField(new MatchField(MatchType.DL_TYPE,
                                 v6Match.getDataLayerType()));
                     }
-                    if (v6Match.getDataLayerVirtualLan() != 0) {
+                    short vlan = v6Match.getDataLayerVirtualLan();
+                    if (vlan != 0) {
+                        if (vlan == OFP_VLAN_NONE) {
+                            vlan = MatchType.DL_VLAN_NONE;
+                        }
                         salMatch.setField(new MatchField(MatchType.DL_VLAN,
-                                v6Match.getDataLayerVirtualLan()));
+                                vlan));
                     }
                     if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
                         salMatch.setField(MatchType.DL_VLAN_PR, v6Match
                                 .getDataLayerVirtualLanPriorityCodePoint());
                     }
+                    // V6Match may carry IPv4 address
                     if (v6Match.getNetworkSrc() != null) {
-                        salMatch.setField(MatchType.NW_SRC, v6Match
-                                .getNetworkSrc(), v6Match
-                                .getNetworkSourceMask());
+                        salMatch.setField(MatchType.NW_SRC,
+                                v6Match.getNetworkSrc(),
+                                v6Match.getNetworkSourceMask());
+                    } else if (v6Match.getNetworkSource() != 0) {
+                        salMatch.setField(MatchType.NW_SRC, NetUtils
+                                .getInetAddress(v6Match.getNetworkSource()),
+                                NetUtils.getInetNetworkMask(
+                                        v6Match.getNetworkSourceMaskLen(),
+                                        false));
                     }
+                    // V6Match may carry IPv4 address
                     if (v6Match.getNetworkDest() != null) {
-                        salMatch.setField(MatchType.NW_DST, v6Match
-                                .getNetworkDest(), v6Match
-                                .getNetworkDestinationMask());
+                        salMatch.setField(MatchType.NW_DST,
+                                v6Match.getNetworkDest(),
+                                v6Match.getNetworkDestinationMask());
+                    } else if (v6Match.getNetworkDestination() != 0) {
+                        salMatch.setField(MatchType.NW_DST,
+                                NetUtils.getInetAddress(v6Match
+                                        .getNetworkDestination()),
+                                NetUtils.getInetNetworkMask(
+                                        v6Match.getNetworkDestinationMaskLen(),
+                                        false));
                     }
                     if (v6Match.getNetworkTypeOfService() != 0) {
-                        salMatch.setField(MatchType.NW_TOS, v6Match
+                        int dscp = NetUtils.getUnsignedByte(v6Match
                                 .getNetworkTypeOfService());
+                        byte tos = (byte) (dscp >> 2);
+                        salMatch.setField(MatchType.NW_TOS, tos);
                     }
                     if (v6Match.getNetworkProtocol() != 0) {
-                        salMatch.setField(MatchType.NW_PROTO, v6Match
-                                .getNetworkProtocol());
+                        salMatch.setField(MatchType.NW_PROTO,
+                                v6Match.getNetworkProtocol());
                     }
                     if (v6Match.getTransportSource() != 0) {
-                        salMatch.setField(MatchType.TP_SRC, ((Short) v6Match
-                                .getTransportSource()));
+                        salMatch.setField(MatchType.TP_SRC,
+                                (v6Match.getTransportSource()));
                     }
                     if (v6Match.getTransportDestination() != 0) {
-                        salMatch.setField(MatchType.TP_DST, ((Short) v6Match
-                                .getTransportDestination()));
+                        salMatch.setField(MatchType.TP_DST,
+                                (v6Match.getTransportDestination()));
                     }
                 }
             }
@@ -626,10 +678,12 @@ public class FlowConverter {
                         } else if (ofPort == OFPort.OFPP_NORMAL.getValue()) {
                             salAction = new HwPath();
                         } else if (ofPort == OFPort.OFPP_TABLE.getValue()) {
-                            salAction = new HwPath(); //TODO: we do not handle table in sal for now
+                            salAction = new HwPath(); // TODO: we do not handle
+                                                      // table in sal for now
                         } else {
-                            salAction = new Output(NodeConnectorCreator
-                                    .createOFNodeConnector(ofPort, node));
+                            salAction = new Output(
+                                    NodeConnectorCreator.createOFNodeConnector(
+                                            ofPort, node));
                         }
                     } else if (ofAction instanceof OFActionVirtualLanIdentifier) {
                         salAction = new SetVlanId(
@@ -657,7 +711,7 @@ public class FlowConverter {
                         try {
                             ip = InetAddress.getByAddress(addr);
                         } catch (UnknownHostException e) {
-                            e.printStackTrace();
+                            logger.error("", e);
                         }
                         salAction = new SetNwSrc(ip);
                     } else if (ofAction instanceof OFActionNetworkLayerDestination) {
@@ -668,7 +722,7 @@ public class FlowConverter {
                         try {
                             ip = InetAddress.getByAddress(addr);
                         } catch (UnknownHostException e) {
-                            e.printStackTrace();
+                            logger.error("", e);
                         }
                         salAction = new SetNwDst(ip);
                     } else if (ofAction instanceof OFActionNetworkTypeOfService) {
@@ -678,14 +732,12 @@ public class FlowConverter {
                     } else if (ofAction instanceof OFActionTransportLayerSource) {
                         Short port = ((OFActionTransportLayerSource) ofAction)
                                 .getTransportPort();
-                        int intPort = (port < 0) ? (port.intValue() & 0x7FFF | 0x8000)
-                                : port;
+                        int intPort = NetUtils.getUnsignedShort(port);
                         salAction = new SetTpSrc(intPort);
                     } else if (ofAction instanceof OFActionTransportLayerDestination) {
                         Short port = ((OFActionTransportLayerDestination) ofAction)
                                 .getTransportPort();
-                        int intPort = (port < 0) ? (port.intValue() & 0x7FFF | 0x8000)
-                                : port;
+                        int intPort = NetUtils.getUnsignedShort(port);
                         salAction = new SetTpDst(intPort);
                     }
                     salActionList.add(salAction);
@@ -694,6 +746,10 @@ public class FlowConverter {
             // Create Flow
             flow = new Flow(salMatch, salActionList);
         }
+        logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch,
+                actionsList);
+        logger.trace("SAL Flow: {}", flow);
         return flow;
     }
-}
\ No newline at end of file
+
+}