Merge "Removing the Container Aware dependency from Clustering Services."
authorGiovanni Meo <gmeo@cisco.com>
Sun, 22 Sep 2013 13:38:07 +0000 (13:38 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 22 Sep 2013 13:38:07 +0000 (13:38 +0000)
opendaylight/containermanager/implementation/src/main/java/org/opendaylight/controller/containermanager/internal/ContainerManager.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/FromSalConversionsUtils.java [new file with mode: 0644]

index c897e9a954d13cdcd8e086212e7a46d0b8edce78..c9190af03a587a76cd581591c59a33cc7036baee 100644 (file)
@@ -291,10 +291,10 @@ public class ContainerManager extends Authorization<String> implements IContaine
             for (Match match : conf.getMatches()) {
                 ContainerFlow cFlow = new ContainerFlow(match);
                 if (delete) {
-                    logger.trace("Removing Flow Spec %s from Container {}", conf.getName(), containerName);
+                    logger.trace("Removing Flow Spec {} from Container {}", conf.getName(), containerName);
                     container.deleteFlowSpec(cFlow);
                 } else {
-                    logger.trace("Adding Flow Spec %s to Container {}", conf.getName(), containerName);
+                    logger.trace("Adding Flow Spec {} to Container {}", conf.getName(), containerName);
                     container.addFlowSpec(cFlow);
 
                 }
index fc18079b0afb4537bb7a38a5da3d01fe3736b07d..e9a56d6113c1502447d5956b5bd6236e185ac26b 100644 (file)
@@ -57,6 +57,7 @@ import org.opendaylight.controller.sal.action.Controller;
 import org.opendaylight.controller.sal.action.Flood;
 import org.opendaylight.controller.sal.action.Output;
 import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.core.Config;
 import org.opendaylight.controller.sal.core.ContainerFlow;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.IContainerListener;
@@ -102,7 +103,7 @@ public class ForwardingRulesManager implements
         IConfigurationContainerAware,
         IInventoryListener,
         IObjectReader,
-        ICacheUpdateAware,
+        ICacheUpdateAware<Object,Object>,
         CommandProvider,
         IFlowProgrammerListener {
     private static final String NODEDOWN = "Node is Down";
@@ -1312,7 +1313,6 @@ public class ForwardingRulesManager implements
         retrieveCaches();
     }
 
-    @SuppressWarnings("deprecation")
     private void allocateCaches() {
         if (this.clusterContainerService == null) {
             log.warn("Un-initialized clusterContainerService, can't create cache");
@@ -1368,7 +1368,7 @@ public class ForwardingRulesManager implements
         }
     }
 
-    @SuppressWarnings({ "unchecked", "deprecation" })
+    @SuppressWarnings({ "unchecked" })
     private void retrieveCaches() {
         ConcurrentMap<?, ?> map;
 
@@ -2174,7 +2174,99 @@ public class ForwardingRulesManager implements
 
     @Override
     public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) {
+        boolean updateStaticFlowCluster = false;
+
+        switch (type) {
+        case ADDED:
+            break;
+        case CHANGED:
+            Config config = (propMap == null) ? null : (Config) propMap.get(Config.ConfigPropName);
+            if (config != null) {
+                switch (config.getValue()) {
+                case Config.ADMIN_DOWN:
+                    log.trace("Port {} is administratively down: uninstalling interested flows", nodeConnector);
+                    updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nodeConnector);
+                    break;
+                case Config.ADMIN_UP:
+                    log.trace("Port {} is administratively up: installing interested flows", nodeConnector);
+                    updateStaticFlowCluster = installFlowsOnNodeConnectorUp(nodeConnector);
+                    break;
+                case Config.ADMIN_UNDEF:
+                    break;
+                default:
+                }
+            }
+            break;
+        case REMOVED:
+            // This is the case where a switch port is removed from the SDN agent space
+            log.trace("Port {} was removed from our control: uninstalling interested flows", nodeConnector);
+            updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nodeConnector);
+            break;
+        default:
+
+        }
+
+        if (updateStaticFlowCluster) {
+            refreshClusterStaticFlowsStatus(nodeConnector.getNode());
+        }
+    }
+
+    /*
+     * It goes through the static flows configuration, it identifies the ones
+     * which have the specified node connector as input or output port and
+     * install them on the network node if they are marked to be installed in
+     * hardware and their status shows they were not installed yet
+     */
+    private boolean installFlowsOnNodeConnectorUp(NodeConnector nodeConnector) {
+        boolean updated = false;
+        List<FlowConfig> flowConfigForNode = getStaticFlows(nodeConnector.getNode());
+        for (FlowConfig flowConfig : flowConfigForNode) {
+            if (doesFlowContainNodeConnector(flowConfig.getFlow(), nodeConnector)) {
+                if (flowConfig.installInHw() && !flowConfig.getStatus().equals(SUCCESS)) {
+                    Status status = this.installFlowEntry(flowConfig.getFlowEntry());
+                    if (!status.isSuccess()) {
+                        flowConfig.setStatus(status.getDescription());
+                    } else {
+                        flowConfig.setStatus(SUCCESS);
+                    }
+                    updated = true;
+                }
+            }
+        }
+        return updated;
+    }
 
+    /*
+     * Remove from the network node all the flows which have the specified node
+     * connector as input or output port. If any of the flow entry is a static
+     * flow, it updates the correspondent configuration.
+     */
+    private boolean removeFlowsOnNodeConnectorDown(NodeConnector nodeConnector) {
+        boolean updated = false;
+        List<FlowEntryInstall> nodeFlowEntries = nodeFlows.get(nodeConnector.getNode());
+        if (nodeFlowEntries == null) {
+            return updated;
+        }
+        for (FlowEntryInstall fei : new ArrayList<FlowEntryInstall>(nodeFlowEntries)) {
+            if (doesFlowContainNodeConnector(fei.getInstall().getFlow(), nodeConnector)) {
+                Status status = this.removeEntryInternal(fei, true);
+                if (!status.isSuccess()) {
+                    continue;
+                }
+                /*
+                 * If the flow entry is a static flow, then update its
+                 * configuration
+                 */
+                if (fei.getGroupName().equals(FlowConfig.STATICFLOWGROUP)) {
+                    FlowConfig flowConfig = getStaticFlow(fei.getFlowName(), fei.getNode());
+                    if (flowConfig != null) {
+                        flowConfig.setStatus(PORTREMOVED);
+                        updated = true;
+                    }
+                }
+            }
+        }
+        return updated;
     }
 
     private FlowConfig getDerivedFlowConfig(FlowConfig original, String configName, Short port) {
@@ -2582,57 +2674,22 @@ public class ForwardingRulesManager implements
 
         switch (t) {
         case REMOVED:
-
-            List<FlowEntryInstall> nodeFlowEntries = nodeFlows.get(nc.getNode());
-            if (nodeFlowEntries == null) {
-                return;
-            }
-            for (FlowEntryInstall fei : new ArrayList<FlowEntryInstall>(nodeFlowEntries)) {
-                if (doesFlowContainNodeConnector(fei.getInstall().getFlow(), nc)) {
-                    Status status = this.removeEntryInternal(fei, true);
-                    if (!status.isSuccess()) {
-                        continue;
-                    }
-                    /*
-                     * If the flow entry is a static flow, then update its
-                     * configuration
-                     */
-                    if (fei.getGroupName().equals(FlowConfig.STATICFLOWGROUP)) {
-                        FlowConfig flowConfig = getStaticFlow(fei.getFlowName(), fei.getNode());
-                        if (flowConfig != null) {
-                            flowConfig.setStatus(PORTREMOVED);
-                            updateStaticFlowCluster = true;
-                        }
-                    }
-                }
-            }
-            if (updateStaticFlowCluster) {
-                refreshClusterStaticFlowsStatus(nc.getNode());
-            }
+            log.trace("Port {} was removed from container: uninstalling interested flows", nc);
+            updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nc);
             break;
         case ADDED:
-            List<FlowConfig> flowConfigForNode = getStaticFlows(nc.getNode());
-            for (FlowConfig flowConfig : flowConfigForNode) {
-                if (doesFlowContainNodeConnector(flowConfig.getFlow(), nc)) {
-                    if (flowConfig.installInHw()) {
-                        Status status = this.installFlowEntry(flowConfig.getFlowEntry());
-                        if (!status.isSuccess()) {
-                            flowConfig.setStatus(status.getDescription());
-                        } else {
-                            flowConfig.setStatus(SUCCESS);
-                        }
-                        updateStaticFlowCluster = true;
-                    }
-                }
-            }
-            if (updateStaticFlowCluster) {
-                refreshClusterStaticFlowsStatus(nc.getNode());
-            }
+            log.trace("Port {} was added to container: reinstall interested flows", nc);
+            updateStaticFlowCluster = installFlowsOnNodeConnectorUp(nc);
+
             break;
         case CHANGED:
             break;
         default:
         }
+
+        if (updateStaticFlowCluster) {
+            refreshClusterStaticFlowsStatus(nc.getNode());
+        }
     }
 
     @Override
diff --git a/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/FromSalConversionsUtils.java b/opendaylight/md-sal/sal-compability/src/main/java/org/opendaylight/controller/sal/compability/FromSalConversionsUtils.java
new file mode 100644 (file)
index 0000000..e77375f
--- /dev/null
@@ -0,0 +1,426 @@
+package org.opendaylight.controller.sal.compability;
+
+import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
+import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
+
+import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Drop;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
+import org.opendaylight.controller.sal.action.HwPath;
+import org.opendaylight.controller.sal.action.Loopback;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.PushVlan;
+import org.opendaylight.controller.sal.action.SetDlDst;
+import org.opendaylight.controller.sal.action.SetDlSrc;
+import org.opendaylight.controller.sal.action.SetDlType;
+import org.opendaylight.controller.sal.action.SetNextHop;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.action.SetNwTos;
+import org.opendaylight.controller.sal.action.SetTpDst;
+import org.opendaylight.controller.sal.action.SetTpSrc;
+import org.opendaylight.controller.sal.action.SetVlanCfi;
+import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.action.SetVlanPcp;
+import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchField;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.flow.service.rev130819.FlowAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.ControllerActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.OutputActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.arp.match.fields.ArpSourceHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.arp.match.fields.ArpTargetHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.IpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.IpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer3Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.VlanMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.SctpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.TcpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.UdpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.vlan.match.fields.VlanIdBuilder;
+
+public class FromSalConversionsUtils {
+
+    // source: http://en.wikipedia.org/wiki/Ethertype
+    private static final Short ETHERNET_ARP = new Short((short) 0x0806);
+
+    // source: http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
+    private static final short TCP = (short) 0x06;
+    private static final short UDP = (short) 0x11;
+    private static final short SCTP = (short) 0x84;
+
+    private FromSalConversionsUtils() {
+
+    }
+
+    public static FlowAdded flowFrom(Flow sourceFlow) {
+        if (sourceFlow != null) {
+            final FlowAddedBuilder targetFlow = new FlowAddedBuilder();
+
+            targetFlow.setHardTimeout(new Integer(sourceFlow.getHardTimeout()));
+            targetFlow.setIdleTimeout(new Integer(sourceFlow.getIdleTimeout()));
+            targetFlow.setPriority(new Integer(sourceFlow.getPriority()));
+            targetFlow.setCookie(new BigInteger(String.valueOf(sourceFlow.getId())));
+
+            List<org.opendaylight.controller.sal.action.Action> sourceActions = sourceFlow.getActions();
+            List<Action> targetActions = new ArrayList<>();
+            for (org.opendaylight.controller.sal.action.Action sourceAction : sourceActions) {
+                targetActions.add(actionFrom(sourceAction));
+            }
+            targetFlow.setAction(targetActions);
+
+            targetFlow.setMatch(matchFrom(sourceFlow.getMatch()));
+
+            return targetFlow.build();
+        }
+        return null;
+    }
+
+    private static Action actionFrom(org.opendaylight.controller.sal.action.Action sourceAction) {
+
+        ActionBuilder targetActionBuilder = new ActionBuilder();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.Action targetAction = null;
+
+        if (sourceAction instanceof Controller) {
+            targetAction = new ControllerActionBuilder().build();
+        } else if (sourceAction instanceof Drop) {
+            // TODO: define maping
+        } else if (sourceAction instanceof Flood) {
+            // TODO: define maping
+        } else if (sourceAction instanceof FloodAll) {
+            // TODO: define maping
+        } else if (sourceAction instanceof HwPath) {
+            // TODO: define maping
+        } else if (sourceAction instanceof Loopback) {
+            // TODO: define maping
+        } else if (sourceAction instanceof Output) {
+            NodeConnector nodeConnector = ((Output) sourceAction).getPort();
+
+            OutputActionBuilder outputActionBuilder = new OutputActionBuilder();
+            outputActionBuilder.setOutputNodeConnector(nodeConnectorToUri(nodeConnector));
+            targetAction = outputActionBuilder.build();
+
+        } else if (sourceAction instanceof PopVlan) {
+            // TODO: define maping
+        } else if (sourceAction instanceof PushVlan) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetDlDst) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetDlSrc) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetDlType) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetNextHop) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetNwDst) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetNwSrc) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetNwTos) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetTpDst) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetTpSrc) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetVlanCfi) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetVlanId) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SetVlanPcp) {
+            // TODO: define maping
+        } else if (sourceAction instanceof SwPath) {
+            // TODO: define maping
+        }
+
+        targetActionBuilder.setAction(targetAction);
+
+        return targetActionBuilder.build();
+    }
+
+    private static List<Uri> nodeConnectorToUri(NodeConnector nodeConnector) {
+        // TODO Define mapping
+        return null;
+    }
+
+    private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Match matchFrom(
+            Match sourceMatch) {
+        if (sourceMatch != null) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.MatchBuilder targetBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.MatchBuilder();
+
+            targetBuilder.setEthernetMatch(ethernetMatchFrom(sourceMatch));
+            targetBuilder.setIpMatch(ipMatchFrom(sourceMatch));
+            targetBuilder.setVlanMatch(vlanMatchFrom(sourceMatch));
+            targetBuilder.setLayer3Match(layer3Match(sourceMatch));
+            targetBuilder.setLayer4Match(layer4Match(sourceMatch));
+
+            return targetBuilder.build();
+        }
+        return null;
+
+    }
+
+    private static Layer4Match layer4Match(final Match sourceMatch) {
+        MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
+        Short nwProtocolSource = null;
+        if (nwProto != null && nwProto.getValue() != null) {
+            nwProtocolSource = (Short) (nwProto.getValue());
+        }
+
+        switch (nwProtocolSource) {
+        case TCP:
+            return Layer4MatchAsTcp(sourceMatch);
+        case UDP:
+            return Layer4MatchAsUdp(sourceMatch);
+        case SCTP:
+            return Layer4MatchAsSctp(sourceMatch);
+        }
+        return null;
+    }
+
+    private static Layer4Match Layer4MatchAsSctp(final Match sourceMatch) {
+        SctpMatchBuilder sctpMatchBuilder = new SctpMatchBuilder();
+
+        Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+        Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+        if (sourcePort != null) {
+            sctpMatchBuilder.setSctpSourcePort(new PortNumber(sourcePort));
+        }
+        if (destinationPort != null) {
+            sctpMatchBuilder.setSctpDestinationPort(new PortNumber(destinationPort));
+        }
+
+        return sctpMatchBuilder.build();
+    }
+
+    private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
+        UdpMatchBuilder udpMatchBuilder = new UdpMatchBuilder();
+
+        Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+        Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+        if (sourcePort != null) {
+            udpMatchBuilder.setUdpSourcePort(new PortNumber(sourcePort));
+        }
+
+        if (destinationPort != null) {
+            udpMatchBuilder.setUdpDestinationPort(new PortNumber(destinationPort));
+        }
+
+        return udpMatchBuilder.build();
+    }
+
+    private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
+        TcpMatchBuilder tcpMatchBuilder = new TcpMatchBuilder();
+
+        Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+        Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+        if (sourcePort != null) {
+            tcpMatchBuilder.setTcpSourcePort(new PortNumber(sourcePort));
+        }
+        if (destinationPort != null) {
+            tcpMatchBuilder.setTcpDestinationPort(new PortNumber(destinationPort));
+        }
+
+        return tcpMatchBuilder.build();
+    }
+
+    private static Integer transportPortFrom(final Match sourceMatch, final MatchType matchType) {
+        MatchField transportPort = sourceMatch.getField(matchType);
+        if (transportPort != null && transportPort.getValue() != null) {
+            return (Integer) (transportPort.getValue());
+        }
+        return null;
+    }
+
+    private static VlanMatch vlanMatchFrom(final Match sourceMatch) {
+        VlanMatchBuilder vlanMatchBuild = new VlanMatchBuilder();
+
+        MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
+        if (vlan != null && vlan.getValue() != null) {
+            VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
+            vlanIDBuilder.setVlanId(new VlanId((Integer) (vlan.getValue())));
+            vlanMatchBuild.setVlanId(vlanIDBuilder.build());
+        }
+
+        MatchField vlanPriority = sourceMatch.getField(MatchType.DL_VLAN_PR);
+        if (vlanPriority != null && vlanPriority.getValue() != null) {
+            vlanMatchBuild.setVlanPcp(new VlanPcp((Short) (vlanPriority.getValue())));
+        }
+
+        return vlanMatchBuild.build();
+    }
+
+    private static IpMatch ipMatchFrom(final Match sourceMatch) {
+        IpMatchBuilder targetIpMatchBuild = new IpMatchBuilder();
+        MatchField networkTos = sourceMatch.getField(MatchType.NW_TOS);
+        if (networkTos != null && networkTos.getValue() != null) {
+            Dscp dscp = new Dscp((Short) (networkTos.getValue()));
+            targetIpMatchBuild.setIpDscp(dscp);
+        }
+
+        MatchField protocol = sourceMatch.getField(MatchType.NW_PROTO);
+        if (protocol != null && protocol.getValue() != null) {
+            targetIpMatchBuild.setIpProtocol((Short) (protocol.getValue()));
+        }
+
+        return targetIpMatchBuild.build();
+
+    }
+
+    private static EthernetMatch ethernetMatchFrom(final Match sourceMatch) {
+        final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
+
+        EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
+                .setAddress(ethernetSourceAddressFrom(sourceMatch));
+        targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
+
+        final MatchField dataLinkDest = sourceMatch.getField(DL_DST);
+        if (dataLinkDest != null && dataLinkDest.getValue() != null) {
+            final MacAddress macDestAddress;
+            macDestAddress = new MacAddress((String) (dataLinkDest.getValue()));
+            EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder().setAddress(macDestAddress);
+            targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+        }
+
+        final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
+        if (dataLinkType != null && dataLinkType.getValue() != null) {
+            EtherType etherType = new EtherType((Long) (dataLinkType.getValue()));
+            EthernetTypeBuilder ethType = new EthernetTypeBuilder().setType(etherType);
+            targetEthMatchBuild.setEthernetType(ethType.build());
+        }
+        return targetEthMatchBuild.build();
+    }
+
+    private static MacAddress ethernetSourceAddressFrom(final Match sourceMatch) {
+        final MatchField dataLinkSource = sourceMatch.getField(DL_SRC);
+        if (dataLinkSource != null && dataLinkSource.getValue() != null) {
+            return new MacAddress(new MacAddress((String) (dataLinkSource.getValue())));
+        }
+        return null;
+
+    }
+
+    private static Layer3Match layer3Match(final Match sourceMatch) {
+        InetAddress inetSourceAddress = null;
+        MatchField netSource = sourceMatch.getField(MatchType.NW_SRC);
+        if (netSource != null && netSource.getValue() != null) {
+            inetSourceAddress = (InetAddress) (netSource.getValue());
+        }
+
+        InetAddress inetDestAddress = null;
+        MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
+        if (netSource != null && netSource.getValue() != null) {
+            inetDestAddress = (InetAddress) (netDest.getValue());
+        }
+
+        if ((inetSourceAddress instanceof Inet4Address) && (inetDestAddress instanceof Inet4Address)) {
+            MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
+            Short dLType = null;
+            if (dataLinkType != null && dataLinkType.getValue() != null) {
+                dLType = (Short) (dataLinkType.getValue());
+            }
+            if (dLType.equals(ETHERNET_ARP)) {
+                return setLayer3MatchAsArp(sourceMatch, (Inet4Address) inetSourceAddress,
+                        (Inet4Address) inetDestAddress);
+            } else {
+                return setLayer3MatchAsIpv4((Inet4Address) inetSourceAddress, (Inet4Address) inetDestAddress);
+            }
+        } else if ((inetSourceAddress instanceof Inet6Address) && (inetDestAddress instanceof Inet6Address)) {
+            return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress, (Inet6Address) inetDestAddress);
+        }
+
+        return null;
+
+    }
+
+    private static Layer3Match setLayer3MatchAsArp(final Match sourceMatch, final Inet4Address inetSourceAddress,
+            final Inet4Address inetDestAddress) {
+        byte[] inetSourceAddressValue = inetSourceAddress.getAddress();
+        Ipv4Prefix ipv4SourcePrefix = new Ipv4Prefix(Arrays.toString(inetSourceAddressValue));
+
+        byte[] inetDestAddressValue = inetDestAddress.getAddress();
+        Ipv4Prefix ipv4DestPrefix = new Ipv4Prefix(Arrays.toString(inetDestAddressValue));
+
+        ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder();
+
+        arpMatchBuilder.setArpSourceTransportAddress(ipv4SourcePrefix);
+        arpMatchBuilder.setArpSourceTransportAddress(ipv4DestPrefix);
+
+        ArpSourceHardwareAddressBuilder arpSourceHardwareAddressBuilder = new ArpSourceHardwareAddressBuilder();
+        arpSourceHardwareAddressBuilder.setAddress(ethernetSourceAddressFrom(sourceMatch));
+        arpMatchBuilder.setArpSourceHardwareAddress(arpSourceHardwareAddressBuilder.build());
+
+        ArpTargetHardwareAddressBuilder arpTargetHardwareAddressBuilder = new ArpTargetHardwareAddressBuilder();
+        arpTargetHardwareAddressBuilder.setAddress(ethernetDestAddressFrom(sourceMatch));
+        arpMatchBuilder.setArpTargetHardwareAddress(arpTargetHardwareAddressBuilder.build());
+
+        return arpMatchBuilder.build();
+
+    }
+
+    private static MacAddress ethernetDestAddressFrom(final Match sourceMatch) {
+        final MatchField dataLinkDest = sourceMatch.getField(DL_DST);
+        if (dataLinkDest != null && dataLinkDest.getValue() != null) {
+            return new MacAddress((String) (dataLinkDest.getValue()));
+        }
+        return null;
+    }
+
+    private static Layer3Match setLayer3MatchAsIpv4(final Inet4Address inetSourceAddress,
+            final Inet4Address inetDestAddress) {
+        byte[] inetAddressValue = inetSourceAddress.getAddress();
+
+        Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
+        layer4MatchBuild.setIpv4Source(new Ipv4Prefix(Arrays.toString(inetAddressValue)));
+        return layer4MatchBuild.build();
+
+    }
+
+    private static Layer3Match setLayer3MatchAsIpv6(final Inet6Address inetSourceAddress,
+            final Inet6Address inetDestAddress) {
+        byte[] inetAddressValue = inetSourceAddress.getAddress();
+        Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
+
+        layer6MatchBuild.setIpv6Source(new Ipv6Prefix(Arrays.toString(inetAddressValue)));
+        return layer6MatchBuild.build();
+    }
+
+}