Fix installInHw handling in FlowConfig
[controller.git] / opendaylight / forwardingrulesmanager / api / src / main / java / org / opendaylight / controller / forwardingrulesmanager / FlowConfig.java
index b11b5f3dbc29c1e9ecf9674ae3dc7845ac3e4adf..c57dca2a88c368185c81d8d2c82476e37dc4f968 100644 (file)
@@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import org.opendaylight.controller.forwardingrulesmanager.FlowEntry;
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.action.Controller;
@@ -33,6 +34,7 @@ import org.opendaylight.controller.sal.action.Output;
 import org.opendaylight.controller.sal.action.PopVlan;
 import org.opendaylight.controller.sal.action.SetDlDst;
 import org.opendaylight.controller.sal.action.SetDlSrc;
+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;
@@ -54,6 +56,7 @@ import org.opendaylight.controller.sal.utils.IPProtocols;
 import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Switch;
@@ -64,13 +67,16 @@ import org.slf4j.LoggerFactory;
  * Configuration Java Object which represents a flow configuration information
  * for Forwarding Rules Manager.
  */
-
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.NONE)
 public class FlowConfig implements Serializable {
     private static final long serialVersionUID = 1L;
     private static final Logger log = LoggerFactory.getLogger(FlowConfig.class);
-    private static final String staticFlowsGroup = "**StaticFlows";
+    private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
+    public static final String STATICFLOWGROUP = "__StaticFlows__";
+    public static final String INTERNALSTATICFLOWGROUP = "__InternalStaticFlows__";
+    public static final String INTERNALSTATICFLOWBEGIN = "__";
+    public static final String INTERNALSTATICFLOWEND = "__";
     private boolean dynamic;
     private String status;
 
@@ -124,37 +130,13 @@ public class FlowConfig implements Serializable {
         ANY, V4, V6;
     };
 
-    private enum SetNextHopType {
-        CISCO_EXTENSION("Cisco NextHop Extension"), RESOLVE_L2RW(
-                "Resolve L2 Rewrite");
-
-        private SetNextHopType(String name) {
-            this.name = name;
-        }
-
-        private String name;
-
-        public String toString() {
-            return name;
-        }
-
-        public boolean equals(String type) {
-            if (type.trim().equalsIgnoreCase(name))
-                return true;
-            return false;
-        }
-    }
-
     public FlowConfig() {
     }
 
-    public FlowConfig(String installInHw, String name, Node node,
-            String priority, String cookie, String ingressPort,
-            String portGroup, String vlanId, String vlanPriority,
-            String etherType, String srcMac, String dstMac, String protocol,
-            String tosBits, String srcIP, String dstIP, String tpSrc,
-            String tpDst, String idleTimeout, String hardTimeout,
-            List<String> actions) {
+    public FlowConfig(String installInHw, String name, Node node, String priority, String cookie, String ingressPort,
+            String portGroup, String vlanId, String vlanPriority, String etherType, String srcMac, String dstMac,
+            String protocol, String tosBits, String srcIP, String dstIP, String tpSrc, String tpDst,
+            String idleTimeout, String hardTimeout, List<String> actions) {
         super();
         this.installInHw = installInHw;
         this.name = name;
@@ -207,13 +189,13 @@ public class FlowConfig implements Serializable {
     public boolean installInHw() {
         if (installInHw == null) {
             // backward compatibility
-            installInHw = "true";
+            installInHw = Boolean.toString(true);
         }
-        return installInHw.equals("true");
+        return Boolean.valueOf(installInHw);
     }
 
     public void setInstallInHw(boolean inHw) {
-        installInHw = inHw ? "true" : "false";
+        installInHw = String.valueOf(inHw);
     }
 
     public String getInstallInHw() {
@@ -221,8 +203,9 @@ public class FlowConfig implements Serializable {
     }
 
     public boolean isInternalFlow() {
-        // Controller generated static flows have name starting with "**"
-        return (this.name != null && this.name.startsWith("**"));
+        return (this.name != null &&
+                this.name.startsWith(FlowConfig.INTERNALSTATICFLOWBEGIN) &&
+                this.name.endsWith(FlowConfig.INTERNALSTATICFLOWEND));
     }
 
     public String getName() {
@@ -274,17 +257,13 @@ public class FlowConfig implements Serializable {
 
     @Override
     public String toString() {
-        return "FlowConfig [dynamic=" + dynamic + ", status=" + status
-                + ", installInHw=" + installInHw + ", name=" + name
-                + ", switchId=" + node + ", ingressPort=" + ingressPort
-                + ", portGroup=" + portGroup + ", etherType=" + etherType
-                + ", priority=" + priority + ", vlanId=" + vlanId
-                + ", vlanPriority=" + vlanPriority + ", dlSrc=" + dlSrc
-                + ", dlDst=" + dlDst + ", nwSrc=" + nwSrc + ", nwDst=" + nwDst
-                + ", protocol=" + protocol + ", tosBits=" + tosBits
-                + ", tpSrc=" + tpSrc + ", tpDst=" + tpDst + ", cookie="
-                + cookie + ", idleTimeout=" + idleTimeout + ", hardTimeout="
-                + hardTimeout + ", actions=" + actions + "]";
+        return "FlowConfig [dynamic=" + dynamic + ", status=" + status + ", installInHw=" + installInHw + ", name="
+                + name + ", switchId=" + node + ", ingressPort=" + ingressPort + ", portGroup=" + portGroup
+                + ", etherType=" + etherType + ", priority=" + priority + ", vlanId=" + vlanId + ", vlanPriority="
+                + vlanPriority + ", dlSrc=" + dlSrc + ", dlDst=" + dlDst + ", nwSrc=" + nwSrc + ", nwDst=" + nwDst
+                + ", protocol=" + protocol + ", tosBits=" + tosBits + ", tpSrc=" + tpSrc + ", tpDst=" + tpDst
+                + ", cookie=" + cookie + ", idleTimeout=" + idleTimeout + ", hardTimeout=" + hardTimeout + ", actions="
+                + actions + "]";
     }
 
     public void setPortGroup(String portGroup) {
@@ -396,11 +375,7 @@ public class FlowConfig implements Serializable {
     }
 
     public boolean isIPv6() {
-        if (NetUtils.isIPv6AddressValid(this.getSrcIp())
-                || NetUtils.isIPv6AddressValid(this.getDstIp())) {
-            return true;
-        }
-        return false;
+        return NetUtils.isIPv6AddressValid(this.getSrcIp()) || NetUtils.isIPv6AddressValid(this.getDstIp());
     }
 
     public List<String> getActions() {
@@ -444,191 +419,181 @@ public class FlowConfig implements Serializable {
         result = prime * result + ((dlDst == null) ? 0 : dlDst.hashCode());
         result = prime * result + ((dlSrc == null) ? 0 : dlSrc.hashCode());
         result = prime * result + (dynamic ? 1231 : 1237);
-        result = prime * result
-                + ((etherType == null) ? 0 : etherType.hashCode());
-        result = prime * result
-                + ((ingressPort == null) ? 0 : ingressPort.hashCode());
+        result = prime * result + ((etherType == null) ? 0 : etherType.hashCode());
+        result = prime * result + ((ingressPort == null) ? 0 : ingressPort.hashCode());
         result = prime * result + ((name == null) ? 0 : name.hashCode());
         result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
         result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
-        result = prime * result
-                + ((portGroup == null) ? 0 : portGroup.hashCode());
-        result = prime * result
-                + ((priority == null) ? 0 : priority.hashCode());
-        result = prime * result
-                + ((protocol == null) ? 0 : protocol.hashCode());
+        result = prime * result + ((portGroup == null) ? 0 : portGroup.hashCode());
+        result = prime * result + ((priority == null) ? 0 : priority.hashCode());
+        result = prime * result + ((protocol == null) ? 0 : protocol.hashCode());
         result = prime * result + ((node == null) ? 0 : node.hashCode());
         result = prime * result + ((tosBits == null) ? 0 : tosBits.hashCode());
         result = prime * result + ((tpDst == null) ? 0 : tpDst.hashCode());
         result = prime * result + ((tpSrc == null) ? 0 : tpSrc.hashCode());
         result = prime * result + ((vlanId == null) ? 0 : vlanId.hashCode());
-        result = prime * result
-                + ((vlanPriority == null) ? 0 : vlanPriority.hashCode());
-        result = prime * result
-                + ((idleTimeout == null) ? 0 : idleTimeout.hashCode());
-        result = prime * result
-                + ((hardTimeout == null) ? 0 : hardTimeout.hashCode());
+        result = prime * result + ((vlanPriority == null) ? 0 : vlanPriority.hashCode());
+        result = prime * result + ((idleTimeout == null) ? 0 : idleTimeout.hashCode());
+        result = prime * result + ((hardTimeout == null) ? 0 : hardTimeout.hashCode());
         return result;
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         FlowConfig other = (FlowConfig) obj;
         if (actions == null) {
-            if (other.actions != null)
+            if (other.actions != null) {
                 return false;
-        } else if (!actions.equals(other.actions))
+            }
+        } else if (!actions.equals(other.actions)) {
             return false;
+        }
         if (cookie == null) {
-            if (other.cookie != null)
+            if (other.cookie != null) {
                 return false;
-        } else if (!cookie.equals(other.cookie))
+            }
+        } else if (!cookie.equals(other.cookie)) {
             return false;
+        }
         if (dlDst == null) {
-            if (other.dlDst != null)
+            if (other.dlDst != null) {
                 return false;
-        } else if (!dlDst.equals(other.dlDst))
+            }
+        } else if (!dlDst.equals(other.dlDst)) {
             return false;
+        }
         if (dlSrc == null) {
-            if (other.dlSrc != null)
+            if (other.dlSrc != null) {
                 return false;
-        } else if (!dlSrc.equals(other.dlSrc))
+            }
+        } else if (!dlSrc.equals(other.dlSrc)) {
             return false;
-        if (dynamic != other.dynamic)
+        }
+        if (dynamic != other.dynamic) {
             return false;
+        }
         if (etherType == null) {
-            if (other.etherType != null)
+            if (other.etherType != null) {
                 return false;
-        } else if (!etherType.equals(other.etherType))
+            }
+        } else if (!etherType.equals(other.etherType)) {
             return false;
+        }
         if (ingressPort == null) {
-            if (other.ingressPort != null)
+            if (other.ingressPort != null) {
                 return false;
-        } else if (!ingressPort.equals(other.ingressPort))
+            }
+        } else if (!ingressPort.equals(other.ingressPort)) {
             return false;
+        }
         if (name == null) {
-            if (other.name != null)
+            if (other.name != null) {
                 return false;
-        } else if (!name.equals(other.name))
+            }
+        } else if (!name.equals(other.name)) {
             return false;
+        }
         if (nwDst == null) {
-            if (other.nwDst != null)
+            if (other.nwDst != null) {
                 return false;
-        } else if (!nwDst.equals(other.nwDst))
+            }
+        } else if (!nwDst.equals(other.nwDst)) {
             return false;
+        }
         if (nwSrc == null) {
-            if (other.nwSrc != null)
+            if (other.nwSrc != null) {
                 return false;
-        } else if (!nwSrc.equals(other.nwSrc))
+            }
+        } else if (!nwSrc.equals(other.nwSrc)) {
             return false;
+        }
         if (portGroup == null) {
-            if (other.portGroup != null)
+            if (other.portGroup != null) {
                 return false;
-        } else if (!portGroup.equals(other.portGroup))
+            }
+        } else if (!portGroup.equals(other.portGroup)) {
             return false;
+        }
         if (priority == null) {
-            if (other.priority != null)
+            if (other.priority != null) {
                 return false;
-        } else if (!priority.equals(other.priority))
+            }
+        } else if (!priority.equals(other.priority)) {
             return false;
+        }
         if (protocol == null) {
-            if (other.protocol != null)
+            if (other.protocol != null) {
                 return false;
-        } else if (!protocol.equals(other.protocol))
+            }
+        } else if (!protocol.equals(other.protocol)) {
             return false;
+        }
         if (node == null) {
-            if (other.node != null)
+            if (other.node != null) {
                 return false;
-        } else if (!node.equals(other.node))
+            }
+        } else if (!node.equals(other.node)) {
             return false;
+        }
         if (tosBits == null) {
-            if (other.tosBits != null)
+            if (other.tosBits != null) {
                 return false;
-        } else if (!tosBits.equals(other.tosBits))
+            }
+        } else if (!tosBits.equals(other.tosBits)) {
             return false;
+        }
         if (tpDst == null) {
-            if (other.tpDst != null)
+            if (other.tpDst != null) {
                 return false;
-        } else if (!tpDst.equals(other.tpDst))
+            }
+        } else if (!tpDst.equals(other.tpDst)) {
             return false;
+        }
         if (tpSrc == null) {
-            if (other.tpSrc != null)
+            if (other.tpSrc != null) {
                 return false;
-        } else if (!tpSrc.equals(other.tpSrc))
+            }
+        } else if (!tpSrc.equals(other.tpSrc)) {
             return false;
+        }
         if (vlanId == null) {
-            if (other.vlanId != null)
+            if (other.vlanId != null) {
                 return false;
-        } else if (!vlanId.equals(other.vlanId))
+            }
+        } else if (!vlanId.equals(other.vlanId)) {
             return false;
+        }
         if (vlanPriority == null) {
-            if (other.vlanPriority != null)
+            if (other.vlanPriority != null) {
                 return false;
-        } else if (!vlanPriority.equals(other.vlanPriority))
+            }
+        } else if (!vlanPriority.equals(other.vlanPriority)) {
             return false;
+        }
         if (idleTimeout == null) {
-            if (other.idleTimeout != null)
+            if (other.idleTimeout != null) {
                 return false;
-        } else if (!idleTimeout.equals(other.idleTimeout))
+            }
+        } else if (!idleTimeout.equals(other.idleTimeout)) {
             return false;
+        }
         if (hardTimeout == null) {
-            if (other.hardTimeout != null)
+            if (other.hardTimeout != null) {
                 return false;
-        } else if (!hardTimeout.equals(other.hardTimeout))
-            return false;
-        return true;
-    }
-
-    public InetAddress getNextHopAddressForL2RWAction() {
-        if (actions != null) {
-            Matcher sstr;
-            for (String actiongrp : actions) {
-                sstr = Pattern.compile("SET_NEXT_HOP=(.*)").matcher(actiongrp);
-                if (sstr.matches()) {
-                    SetNextHopType setNHType = SetNextHopType.CISCO_EXTENSION;
-                    String nextHopInfo = sstr.group(1);
-                    String values[] = nextHopInfo.split("//");
-                    String address = values[0].trim();
-                    String type = null;
-                    if (values.length > 1) {
-                        type = values[1].trim();
-                    }
-
-                    if (type != null) {
-                        for (SetNextHopType nh : SetNextHopType.values()) {
-                            if (nh.equals(type))
-                                setNHType = nh;
-                        }
-                    }
-
-                    log.debug("Get Nexthop address = " + address + " Type = "
-                            + setNHType.toString());
-                    if (setNHType == SetNextHopType.RESOLVE_L2RW) {
-                        try {
-                            return InetAddress.getByName(address);
-                        } catch (Exception e) {
-                            log.debug("Exception during nextHopAddress resolution : "
-                                    + e.getMessage());
-                        }
-                    }
-                }
             }
+        } else if (!hardTimeout.equals(other.hardTimeout)) {
+            return false;
         }
-        return null;
-    }
-
-    public String getNextHopL2RWUsageError() {
-        return "Could not resolve NextHop IP Address for the selected Switch.<br>"
-                + "Please Check the following configurations.<br>"
-                + "1. Is the NextHop IP address directly connected to the Selected Switch<br>"
-                + "2. If appropriate Subnet Configurations are done in the Switch Manager<br>"
-                + "3. If the Nexthop IP-Address is Correct";
+        return true;
     }
 
     public boolean isL2AddressValid(String mac) {
@@ -636,13 +601,10 @@ public class FlowConfig implements Serializable {
             return false;
         }
 
-        Pattern macPattern = Pattern
-                .compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
+        Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
         Matcher mm = macPattern.matcher(mac);
         if (!mm.matches()) {
-            log.debug(
-                    "Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f",
-                    mac);
+            log.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
             return false;
         }
         return true;
@@ -686,7 +648,7 @@ public class FlowConfig implements Serializable {
 
     public boolean isTpPortValid(String tpPort) {
         int port = Integer.decode(tpPort);
-        return ((port > 0) && (port <= 0xffff));
+        return ((port >= 0) && (port <= 0xffff));
     }
 
     public boolean isTimeoutValid(String timeout) {
@@ -694,17 +656,21 @@ public class FlowConfig implements Serializable {
         return ((to >= 0) && (to <= 0xffff));
     }
 
-    private boolean conflictWithContainerFlow(IContainer container,
-            StringBuffer resultStr) {
+    public boolean isProtocolValid(String protocol) {
+        IPProtocols proto = IPProtocols.fromString(protocol);
+        return (proto != null);
+    }
+
+    private Status conflictWithContainerFlow(IContainer container) {
         // Return true if it's default container
         if (container.getName().equals(GlobalConstants.DEFAULT.toString())) {
-            return false;
+            return new Status(StatusCode.SUCCESS);
         }
 
         // No container flow = no conflict
         List<ContainerFlow> cFlowList = container.getContainerFlows();
         if (((cFlowList == null)) || cFlowList.isEmpty()) {
-            return false;
+            return new Status(StatusCode.SUCCESS);
         }
 
         // Check against each container's flow
@@ -715,36 +681,34 @@ public class FlowConfig implements Serializable {
         for (ContainerFlow cFlow : cFlowList) {
             if (cFlow.allowsFlow(flow)) {
                 log.trace("Config is congruent with at least one container flow");
-                return false;
+                return new Status(StatusCode.SUCCESS);
             }
         }
         String msg = "Flow Config conflicts with all existing container flows";
-        resultStr.append(msg);
         log.trace(msg);
 
-        return true;
+        return new Status(StatusCode.BADREQUEST, msg);
     }
 
-    public boolean isValid(IContainer container, StringBuffer resultStr) {
+    public Status validate(IContainer container) {
         EtherIPType etype = EtherIPType.ANY;
         EtherIPType ipsrctype = EtherIPType.ANY;
         EtherIPType ipdsttype = EtherIPType.ANY;
 
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container.getName();
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container.getName();
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
 
         Switch sw = null;
         try {
-            if (name == null) {
-                resultStr.append(String.format("Name is null"));
-                return false;
+            if (name == null || name.trim().isEmpty() || !name.matches(FlowConfig.NAMEREGEX)) {
+                return new Status(StatusCode.BADREQUEST, "Invalid name");
             }
+
             if (node == null) {
-                resultStr.append(String.format("Node is null"));
-                return false;
+                return new Status(StatusCode.BADREQUEST, "Node is null");
             }
+
             if (switchManager != null) {
                 for (Switch device : switchManager.getNetworkDevices()) {
                     if (device.getNode().equals(node)) {
@@ -753,102 +717,83 @@ public class FlowConfig implements Serializable {
                     }
                 }
                 if (sw == null) {
-                    resultStr.append(String.format("Node %s not found", node));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("Node %s not found", node));
                 }
             } else {
                 log.debug("switchmanager is not set yet");
             }
 
             if (priority != null) {
-                if (Integer.decode(priority) < 0
-                        || (Integer.decode(priority) > 65535)) {
-                    resultStr.append(String.format(
-                            "priority %s is not in the range 0 - 65535",
+                if (Integer.decode(priority) < 0 || (Integer.decode(priority) > 65535)) {
+                    return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535",
                             priority));
-                    return false;
                 }
             }
 
             // make sure it's a valid number
-            if (cookie != null)
+            if (cookie != null) {
                 Long.decode(cookie);
+            }
 
             if (ingressPort != null) {
                 Short port = Short.decode(ingressPort);
                 if (isPortValid(sw, port) == false) {
-                    resultStr
-                            .append(String
-                                    .format("Ingress port %d is not valid for the Switch",
-                                            port));
-                    if ((container != null)
-                            && !container.getName().equals(
-                                    GlobalConstants.DEFAULT.toString())) {
-                        resultStr
-                                .append(" in Container " + container.getName());
+                    String msg = String.format("Ingress port %d is not valid for the Switch", port);
+                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                        msg += " in Container " + containerName;
                     }
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, msg);
                 }
             }
 
             if ((vlanId != null) && !isVlanIdValid(vlanId)) {
-                resultStr.append(String.format(
-                        "Vlan ID %s is not in the range 0 - 4095", vlanId));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("Vlan ID %s is not in the range 0 - 4095",
+                        vlanId));
             }
 
             if ((vlanPriority != null) && !isVlanPriorityValid(vlanPriority)) {
-                resultStr.append(String.format(
-                        "Vlan priority %s is not in the range 0 - 7",
+                return new Status(StatusCode.BADREQUEST, String.format("Vlan priority %s is not in the range 0 - 7",
                         vlanPriority));
-                return false;
             }
-
             if (etherType != null) {
                 int type = Integer.decode(etherType);
                 if ((type < 0) || (type > 0xffff)) {
-                    resultStr.append(String.format(
-                            "Ethernet type %s is not valid", etherType));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("Ethernet type %s is not valid", etherType));
                 } else {
-                    if (type == 0x800)
+                    if (type == 0x800) {
                         etype = EtherIPType.V4;
-                    else if (type == 0x86dd)
+                    } else if (type == 0x86dd) {
                         etype = EtherIPType.V6;
+                    }
                 }
             }
 
+            if ((protocol != null) && !isProtocolValid(protocol)) {
+                return new Status(StatusCode.BADREQUEST, String.format("Protocol %s is not valid", protocol));
+            }
+
             if ((tosBits != null) && !isTOSBitsValid(tosBits)) {
-                resultStr.append(String.format(
-                        "IP ToS bits %s is not in the range 0 - 63", tosBits));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("IP ToS bits %s is not in the range 0 - 63",
+                        tosBits));
             }
 
             if ((tpSrc != null) && !isTpPortValid(tpSrc)) {
-                resultStr.append(String.format(
-                        "Transport source port %s is not valid", tpSrc));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("Transport source port %s is not valid", tpSrc));
             }
+
             if ((tpDst != null) && !isTpPortValid(tpDst)) {
-                resultStr.append(String.format(
-                        "Transport destination port %s is not valid", tpDst));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("Transport destination port %s is not valid",
+                        tpDst));
             }
 
             if ((dlSrc != null) && !isL2AddressValid(dlSrc)) {
-                resultStr
-                        .append(String
-                                .format("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
-                                        dlSrc));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format(
+                        "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f", dlSrc));
             }
 
             if ((dlDst != null) && !isL2AddressValid(dlDst)) {
-                resultStr
-                        .append(String
-                                .format("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
-                                        dlDst));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format(
+                        "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f", dlDst));
             }
 
             if (nwSrc != null) {
@@ -857,9 +802,7 @@ public class FlowConfig implements Serializable {
                 } else if (NetUtils.isIPv6AddressValid(nwSrc)) {
                     ipsrctype = EtherIPType.V6;
                 } else {
-                    resultStr.append(String.format(
-                            "IP source address %s is not valid", nwSrc));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid", nwSrc));
                 }
             }
 
@@ -869,316 +812,236 @@ public class FlowConfig implements Serializable {
                 } else if (NetUtils.isIPv6AddressValid(nwDst)) {
                     ipdsttype = EtherIPType.V6;
                 } else {
-                    resultStr.append(String.format(
-                            "IP destination address %s is not valid", nwDst));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("IP destination address %s is not valid",
+                            nwDst));
                 }
             }
 
             if (etype != EtherIPType.ANY) {
                 if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
-                    resultStr.append(String
-                            .format("Type mismatch between Ethernet & Src IP"));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Src IP"));
                 }
                 if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
-                    resultStr.append(String
-                            .format("Type mismatch between Ethernet & Dst IP"));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Dst IP"));
                 }
             }
             if (ipsrctype != ipdsttype) {
                 if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
-                    resultStr
-                            .append(String.format("IP Src Dest Type mismatch"));
-                    return false;
+                    return new Status(StatusCode.BADREQUEST, String.format("IP Src Dest Type mismatch"));
                 }
             }
 
             if ((idleTimeout != null) && !isTimeoutValid(idleTimeout)) {
-                resultStr.append(String.format(
-                        "Idle Timeout value %s is not valid", idleTimeout));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("Idle Timeout value %s is not valid",
+                        idleTimeout));
             }
 
             if ((hardTimeout != null) && !isTimeoutValid(hardTimeout)) {
-                resultStr.append(String.format(
-                        "Hard Timeout value %s is not valid", hardTimeout));
-                return false;
+                return new Status(StatusCode.BADREQUEST, String.format("Hard Timeout value %s is not valid",
+                        hardTimeout));
             }
 
             Matcher sstr;
-            if (actions != null && !actions.isEmpty()) {
-                for (String actiongrp : actions) {
-                    // check output ports
-                    sstr = Pattern.compile("OUTPUT=(.*)").matcher(actiongrp);
-                    if (sstr.matches()) {
-                        for (String t : sstr.group(1).split(",")) {
-                            Matcher n = Pattern.compile("(?:(\\d+))")
-                                    .matcher(t);
-                            if (n.matches()) {
-                                if (n.group(1) != null) {
-                                    Short port = Short.parseShort(n.group(1));
-                                    if (isPortValid(sw, port) == false) {
-                                        resultStr
-                                                .append(String
-                                                        .format("Output port %d is not valid for this switch",
-                                                                port));
-                                        if ((container != null)
-                                                && !container.getName().equals(
-                                                        GlobalConstants.DEFAULT
-                                                                .toString())) {
-                                            resultStr.append(" in Container "
-                                                    + container.getName());
-                                        }
-                                        return false;
+            if (actions == null || actions.isEmpty()) {
+                return new Status(StatusCode.BADREQUEST, "Actions value is null or empty");
+            }
+            for (String actiongrp : actions) {
+                // check output ports
+                sstr = Pattern.compile("OUTPUT=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    for (String t : sstr.group(1).split(",")) {
+                        Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
+                        if (n.matches()) {
+                            if (n.group(1) != null) {
+                                Short port = Short.parseShort(n.group(1));
+                                if (isPortValid(sw, port) == false) {
+                                    String msg = String.format("Output port %d is not valid for this switch", port);
+                                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                                        msg += " in Container " + containerName;
                                     }
+                                    return new Status(StatusCode.BADREQUEST, msg);
                                 }
                             }
                         }
-                        continue;
                     }
-                    // Check src IP
-                    sstr = Pattern.compile(ActionType.FLOOD.toString())
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if (container != null) {
-                            resultStr.append(String.format(
-                                    "flood is not allowed in container %s",
-                                    container.getName()));
-                            return false;
-                        }
-                        continue;
+                    continue;
+                }
+                // Check src IP
+                sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "flood is not allowed in container %s", containerName));
                     }
-                    // Check src IP
-                    sstr = Pattern.compile(
-                            ActionType.SET_NW_SRC.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
-                            resultStr.append(String.format(
-                                    "IP source address %s is not valid",
-                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                    continue;
+                }
+                // Check src IP
+                sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid",
+                                sstr.group(1)));
                     }
-                    // Check dst IP
-                    sstr = Pattern.compile(
-                            ActionType.SET_NW_DST.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
-                            resultStr.append(String.format(
-                                    "IP destination address %s is not valid",
-                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                    continue;
+                }
+                // Check dst IP
+                sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "IP destination address %s is not valid", sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_VLAN_ID.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isVlanIdValid(sstr.group(1))) {
-                            resultStr.append(String.format(
-                                    "Vlan ID %s is not in the range 0 - 4095",
-                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isVlanIdValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Vlan ID %s is not in the range 0 - 4095", sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_VLAN_PCP.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isVlanPriorityValid(sstr.group(1))) {
-                            resultStr
-                                    .append(String
-                                            .format("Vlan priority %s is not in the range 0 - 7",
-                                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isVlanPriorityValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Vlan priority %s is not in the range 0 - 7", sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_DL_SRC.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isL2AddressValid(sstr.group(1))) {
-                            resultStr
-                                    .append(String
-                                            .format("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
-                                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
+                                sstr.group(1)));
                     }
-
-                    sstr = Pattern.compile(
-                            ActionType.SET_DL_DST.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isL2AddressValid(sstr.group(1))) {
-                            resultStr
-                                    .append(String
-                                            .format("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
-                                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                    continue;
+                }
+                sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
+                                sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_NW_TOS.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isTOSBitsValid(sstr.group(1))) {
-                            resultStr
-                                    .append(String
-                                            .format("IP ToS bits %s is not in the range 0 - 63",
-                                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isTOSBitsValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "IP ToS bits %s is not in the range 0 - 63", sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_TP_SRC.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isTpPortValid(sstr.group(1))) {
-                            resultStr.append(String.format(
-                                    "Transport source port %s is not valid",
-                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Transport source port %s is not valid", sstr.group(1)));
                     }
+                    continue;
+                }
 
-                    sstr = Pattern.compile(
-                            ActionType.SET_TP_DST.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        if ((sstr.group(1) != null)
-                                && !isTpPortValid(sstr.group(1))) {
-                            resultStr
-                                    .append(String
-                                            .format("Transport destination port %s is not valid",
-                                                    sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "Transport destination port %s is not valid", sstr.group(1)));
                     }
-                    sstr = Pattern.compile(
-                            ActionType.SET_NEXT_HOP.toString() + "=(.*)")
-                            .matcher(actiongrp);
-                    if (sstr.matches()) {
-                        String nextHopInfo = sstr.group(1);
-                        String values[] = nextHopInfo.split("//");
-                        String address = values[0].trim();
-
-                        if ((address == null) || !isOutputNextHopValid(address)) {
-                            resultStr.append(String.format(
-                                    "next hop %s is not valid", sstr.group(1)));
-                            return false;
-                        }
-                        continue;
+                    continue;
+                }
+                sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
+                if (sstr.matches()) {
+                    if (!NetUtils.isIPAddressValid(sstr.group(1))) {
+                        return new Status(StatusCode.BADREQUEST, String.format(
+                                "IP destination address %s is not valid", sstr.group(1)));
                     }
+                    continue;
                 }
             }
             // Check against the container flow
-            if ((container != null)
-                    && conflictWithContainerFlow(container, resultStr)) {
-                return false;
+            Status status;
+            if (!containerName.equals(GlobalConstants.DEFAULT.toString()) && !(status = conflictWithContainerFlow(container)).isSuccess()) {
+                return status;
             }
         } catch (NumberFormatException e) {
-            resultStr.append(String.format("Invalid number format %s",
-                    e.getMessage()));
-            return false;
+            return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
         }
 
-        return true;
+        return new Status(StatusCode.SUCCESS);
     }
 
     public FlowEntry getFlowEntry() {
-        return new FlowEntry(FlowConfig.staticFlowsGroup, this.name,
-                this.getFlow(), this.getNode());
+        String group = this.isInternalFlow() ? FlowConfig.INTERNALSTATICFLOWGROUP : FlowConfig.STATICFLOWGROUP;
+        return new FlowEntry(group, this.name, this.getFlow(), this.getNode());
     }
 
     public Flow getFlow() {
         Match match = new Match();
 
         if (this.ingressPort != null) {
-            match.setField(
-                    MatchType.IN_PORT,
-                    NodeConnectorCreator.createOFNodeConnector(
-                            Short.parseShort(ingressPort), getNode()));
+            match.setField(MatchType.IN_PORT,
+                    NodeConnectorCreator.createOFNodeConnector(Short.parseShort(ingressPort), getNode()));
         }
         if (this.dlSrc != null) {
-            match.setField(MatchType.DL_SRC,
-                    HexEncode.bytesFromHexString(this.dlSrc));
+            match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
         }
         if (this.dlDst != null) {
-            match.setField(MatchType.DL_DST,
-                    HexEncode.bytesFromHexString(this.dlDst));
+            match.setField(MatchType.DL_DST, HexEncode.bytesFromHexString(this.dlDst));
         }
         if (this.etherType != null) {
-            match.setField(MatchType.DL_TYPE, Integer.decode(etherType)
-                    .shortValue());
+            match.setField(MatchType.DL_TYPE, Integer.decode(etherType).shortValue());
         }
         if (this.vlanId != null) {
             match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
         }
         if (this.vlanPriority != null) {
-            match.setField(MatchType.DL_VLAN_PR,
-                    Byte.parseByte(this.vlanPriority));
+            match.setField(MatchType.DL_VLAN_PR, Byte.parseByte(this.vlanPriority));
         }
         if (this.nwSrc != null) {
             String parts[] = this.nwSrc.split("/");
             InetAddress ip = NetUtils.parseInetAddress(parts[0]);
             InetAddress mask = null;
+            int maskLen = 0;
             if (parts.length > 1) {
-                int maskLen = Integer.parseInt(parts[1]);
-                mask = NetUtils.getInetNetworkMask(maskLen,
-                        ip instanceof Inet6Address);
+                maskLen = Integer.parseInt(parts[1]);
+            } else {
+                maskLen = (ip instanceof Inet6Address) ? 128 : 32;
             }
+            mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
             match.setField(MatchType.NW_SRC, ip, mask);
         }
         if (this.nwDst != null) {
             String parts[] = this.nwDst.split("/");
             InetAddress ip = NetUtils.parseInetAddress(parts[0]);
             InetAddress mask = null;
+            int maskLen = 0;
             if (parts.length > 1) {
-                int maskLen = Integer.parseInt(parts[1]);
-                mask = NetUtils.getInetNetworkMask(maskLen,
-                        ip instanceof Inet6Address);
+                maskLen = Integer.parseInt(parts[1]);
+            } else {
+                maskLen = (ip instanceof Inet6Address) ? 128 : 32;
             }
+            mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
             match.setField(MatchType.NW_DST, ip, mask);
         }
-        if (this.protocol != null) {
-            match.setField(MatchType.NW_PROTO,
-                    IPProtocols.getProtocolNumberByte(this.protocol));
+        if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
+            match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
         }
         if (this.tosBits != null) {
             match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
         }
         if (this.tpSrc != null) {
-            match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc)
-                    .shortValue());
+            match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc).shortValue());
         }
         if (this.tpDst != null) {
-            match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst)
-                    .shortValue());
+            match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst).shortValue());
         }
 
         Flow flow = new Flow(match, getActionList());
@@ -1197,17 +1060,6 @@ public class FlowConfig implements Serializable {
         return flow;
     }
 
-    public boolean isOutputNextHopValid(String onh) {
-        if (onh == null) {
-            return false;
-        }
-        /*
-         * For now, only takes IPv4 or IPv6 address
-         */
-        return (NetUtils.isIPv4AddressValid(onh) || NetUtils
-                .isIPv6AddressValid(onh));
-    }
-
     public boolean isByNameAndNodeIdEqual(FlowConfig that) {
         return (this.name.equals(that.name) && this.node.equals(that.node));
     }
@@ -1220,17 +1072,8 @@ public class FlowConfig implements Serializable {
         return this.node.equals(node);
     }
 
-    public static List<String> getSupportedNextHopTypes() {
-        List<String> s = new ArrayList<String>();
-        for (SetNextHopType nh : SetNextHopType.values()) {
-            s.add(nh.toString());
-        }
-        return s;
-    }
-
-    public void toggleStatus() {
-        installInHw = (installInHw == null) ? "true" : (installInHw
-                .equals("true")) ? "false" : "true";
+    public void toggleInstallation() {
+        installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw));
     }
 
     /*
@@ -1244,155 +1087,118 @@ public class FlowConfig implements Serializable {
         if (actions != null) {
             Matcher sstr;
             for (String actiongrp : actions) {
-                sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
                     for (String t : sstr.group(1).split(",")) {
                         Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
                         if (n.matches()) {
                             if (n.group(1) != null) {
                                 short ofPort = Short.parseShort(n.group(1));
-                                actionList.add(new Output(NodeConnectorCreator
-                                        .createOFNodeConnector(ofPort,
-                                                this.getNode())));
+                                actionList.add(new Output(NodeConnectorCreator.createOFNodeConnector(ofPort,
+                                        this.getNode())));
                             }
                         }
                     }
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.DROP.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new Drop());
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new Loopback());
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new Flood());
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new SwPath());
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new HwPath());
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.CONTROLLER.toString())
-                        .matcher(actiongrp);
+                sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new Controller());
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList.add(new SetVlanId(
-                            Short.parseShort(sstr.group(1))));
+                    actionList.add(new SetVlanId(Short.parseShort(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList
-                            .add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
+                    actionList.add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new PopVlan());
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList.add(new SetDlSrc(HexEncode
-                            .bytesFromHexString(sstr.group(1))));
+                    actionList.add(new SetDlSrc(HexEncode.bytesFromHexString(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_DL_DST.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList.add(new SetDlDst(HexEncode
-                            .bytesFromHexString(sstr.group(1))));
+                    actionList.add(new SetDlDst(HexEncode.bytesFromHexString(sstr.group(1))));
                     continue;
                 }
-                sstr = Pattern.compile(
-                        ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr
-                            .group(1))));
+                    actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr.group(1))));
                     continue;
                 }
-                sstr = Pattern.compile(
-                        ActionType.SET_NW_DST.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr
-                            .group(1))));
+                    actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList
-                            .add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
+                    actionList.add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_TP_DST.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    actionList
-                            .add(new SetTpDst(Integer.valueOf(sstr.group(1))));
+                    actionList.add(new SetTpDst(Integer.valueOf(sstr.group(1))));
                     continue;
                 }
 
-                sstr = Pattern.compile(
-                        ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(
-                        actiongrp);
+                sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
-                    log.warn("We do not handle next hop action yet....");
+                    actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr.group(1))));
                     continue;
                 }
             }