Move adsal into its own subdirectory.
[controller.git] / opendaylight / adsal / containermanager / api / src / main / java / org / opendaylight / controller / containermanager / ContainerFlowConfig.java
diff --git a/opendaylight/adsal/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java b/opendaylight/adsal/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java
new file mode 100644 (file)
index 0000000..6abd1ac
--- /dev/null
@@ -0,0 +1,819 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.containermanager;
+
+import java.io.Serializable;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.configuration.ConfigurationObject;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.packet.BitBufferHelper;
+import org.opendaylight.controller.sal.utils.IPProtocols;
+import org.opendaylight.controller.sal.utils.NetUtils;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Flow Specification Java Object for Container Manager
+ * Represents a container flow configuration information for Container Manager.
+ *
+ * Objects of this class are serialized to and de-serialized from binary files through
+ * java serialization API when saving to/reading from Container manager startup
+ * configuration file.
+ */
+@XmlRootElement (name = "flow-spec-config")
+@XmlAccessorType(XmlAccessType.NONE)
+public class ContainerFlowConfig extends ConfigurationObject implements Serializable {
+    private static Logger log = LoggerFactory.getLogger(ContainerFlowConfig.class);
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1L;
+
+    /** Flow Spec name. */
+    @XmlElement
+    private String name;
+
+    /** The vlan. */
+    @XmlElement
+    private String dlVlan;
+
+    /** The network Source. */
+    @XmlElement
+    private String nwSrc;
+
+    /** The network Destination */
+    @XmlElement
+    private String nwDst;
+
+    /** The protocol. */
+    @XmlElement
+    private String protocol;
+
+    /** The transport source */
+    @XmlElement
+    private String tpSrc;
+
+    /** The transport destination */
+    @XmlElement
+    private String tpDst;
+
+    /* unidirectional flag
+    do not include this flag in equality check
+    @XmlElement */
+    private static boolean unidirectional = false;
+
+
+    /**
+     * Instantiates a new container flow config.
+     */
+    public ContainerFlowConfig() {
+    }
+
+    /**
+     * Instantiates a new container flow config.
+     *
+     * @param name Flow Spec configuration name
+     * @param container Container Name
+     * @param srcIP Source IP Address
+     * @param dstIP Destination IP Address
+     * @param proto Protocol
+     * @param srcPort Source Layer4 Port
+     * @param dstPort Destination Layer4 Port
+     */
+    public ContainerFlowConfig(String name, String srcIP, String dstIP, String proto, String srcPort,
+            String dstPort) {
+        this.name = name;
+        this.dlVlan = null;
+        this.nwSrc = srcIP;
+        this.nwDst = dstIP;
+        this.protocol = proto;
+        this.tpSrc = srcPort;
+        this.tpDst = dstPort;
+        //this.unidirectional = false;
+    }
+
+    public ContainerFlowConfig(String name, String dlVlan, String srcIP, String dstIP, String proto, String srcPort,
+            String dstPort) {
+        this.name = name;
+        this.dlVlan = dlVlan;
+        this.nwSrc = srcIP;
+        this.nwDst = dstIP;
+        this.protocol = proto;
+        this.tpSrc = srcPort;
+        this.tpDst = dstPort;
+    }
+
+
+    public ContainerFlowConfig(ContainerFlowConfig containerFlowConfig) {
+        this.name = containerFlowConfig.name;
+        this.dlVlan = containerFlowConfig.dlVlan;
+        this.nwSrc = containerFlowConfig.nwSrc;
+        this.nwDst = containerFlowConfig.nwDst;
+        this.protocol = containerFlowConfig.protocol;
+        this.tpSrc = containerFlowConfig.tpSrc;
+        this.tpDst = containerFlowConfig.tpDst;
+        //this.unidirectional = containerFlowConfig.unidirectional;
+    }
+
+    /**
+     * Returns the name of this Flow Specification
+     *
+     * @return the name of the Flow Specification
+     */
+    public String getName() {
+        // mandatory field
+        return name;
+    }
+
+    /**
+     * Returns the vlan id.
+     *
+     * @return the Vlan Id
+     */
+    public String getVlan() {
+        return (dlVlan == null || dlVlan.isEmpty()) ? null : dlVlan;
+    }
+
+    /**
+     * Returns the Source IP Address.
+     *
+     * @return the Source IP Address
+     */
+    public String getSrcIP() {
+        return (nwSrc == null || nwSrc.isEmpty()) ? null : nwSrc;
+    }
+
+    /**
+     * Returns the Destination IP Address.
+     *
+     * @return the Destination IP Address
+     */
+    public String getDstIP() {
+        return (nwDst == null || nwDst.isEmpty()) ? null : nwDst;
+    }
+
+    /**
+     * Returns the protocol.
+     *
+     * @return the protocol
+     */
+    public String getProtocol() {
+        return protocol;
+    }
+
+    /**
+     * Returns Source Layer4 Port.
+     *
+     * @return Source Layer4 Port
+     */
+    public String getSrcPort() {
+        return (tpSrc == null || tpSrc.isEmpty()) ? null : tpSrc;
+    }
+
+    /**
+     * Returns Destination Layer4 Port.
+     *
+     * @return Destination Layer4 Port
+     */
+    public String getDstPort() {
+        return (tpDst == null || tpDst.isEmpty()) ? null : tpDst;
+    }
+
+    /*
+     * @return the unidirectional flag
+     */
+    public boolean isUnidirectional() {
+        return unidirectional;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((protocol == null) ? 0 : protocol.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((dlVlan == null) ? 0 : dlVlan.hashCode());
+        result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
+        result = prime * result + ((tpDst == null) ? 0 : tpDst.hashCode());
+        result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
+        result = prime * result + ((tpSrc == null) ? 0 : tpSrc.hashCode());
+        return result;
+    }
+
+    /*
+     * For comparison, consider that container flow can have empty fields
+     */
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        /*
+         * Configuration will be stored in collection only if it is valid
+         * Hence we don't check here for uninitialized fields
+         */
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ContainerFlowConfig other = (ContainerFlowConfig) obj;
+        if (matchName(other) && matchDlVlan(other) && matchSrcIP(other)
+                && matchDstIP(other) && matchProtocol(other)
+                && matchSrcPort(other) && matchDstPort(other)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Equals by Flow Spec name.
+     *
+     * @param name flow spec name for comparison
+     * @return true, if successful
+     */
+    public boolean equalsByName(String name) {
+        return this.name.equals(name);
+    }
+
+    /**
+     * equalsByMatch
+     *
+     * @param that ContainerFlowConfig for comparison
+     * @return true, if any match is equal
+     */
+    public boolean equalsByMatch(ContainerFlowConfig that) {
+        // get both matches
+        // the match is equal if any of the match is equal
+        List<Match> thisMatch = this.getMatches();
+        List<Match> otherMatch = that.getMatches();
+        // both the lists cannot be null
+        for(Match m1 : thisMatch) {
+            for(Match m2 : otherMatch) {
+                  if(m1.equals(m2)) {
+                    return true;
+                }
+            }
+        }
+        // if you have reached here without a match
+        // being found
+        // return false
+        return false;
+    }
+
+    /**
+     * Matches the name of this flow spec with that of ContainerFlowConfig parameter's flow spec.
+     *
+     * @param o the ContainerFlowConfig parameter
+     * @return true, if successful
+     */
+    private boolean matchName(ContainerFlowConfig flowSpec) {
+        if (name == flowSpec.name) {
+            return true;
+        }
+        if (name == null || flowSpec.name == null) {
+            return false;
+        }
+        return name.equals(flowSpec.name);
+    }
+
+    /**
+     * Match the set of these vlans with that of flowSpec's vlans.
+     *
+     * @param flowSpec
+     *            Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchDlVlan(ContainerFlowConfig flowSpec) {
+        if (dlVlan == flowSpec.dlVlan) {
+            return true;
+        }
+        if (dlVlan == null || flowSpec.dlVlan == null) {
+            return false;
+        }
+
+        return this.getVlanList().equals(flowSpec.getVlanList());
+    }
+
+    /**
+     * Match Source IP Address.
+     *
+     * @param flowSpec Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchSrcIP(ContainerFlowConfig flowSpec) {
+        if (nwSrc == flowSpec.nwSrc) {
+            return true;
+        }
+        if (nwSrc == null || flowSpec.nwSrc == null) {
+            return false;
+        }
+        return nwSrc.equals(flowSpec.nwSrc);
+    }
+
+    /**
+     * Match Destination IP Address.
+     *
+     * @param flowSpec Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchDstIP(ContainerFlowConfig flowSpec) {
+        if (nwDst == flowSpec.nwDst) {
+            return true;
+        }
+        if (nwDst == null || flowSpec.nwDst == null) {
+            return false;
+        }
+        return this.nwDst.equals(flowSpec.nwDst);
+    }
+
+    /**
+     * Match protocol.
+     *
+     * @param flowSpec Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchProtocol(ContainerFlowConfig flowSpec) {
+        if (protocol == flowSpec.protocol) {
+            return true;
+        }
+        if (protocol == null || flowSpec.protocol == null) {
+            return false;
+        }
+        return this.protocol.equals(flowSpec.protocol);
+    }
+
+    /**
+     * Match Source Layer4 Port.
+     *
+     * @param flowSpec Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchSrcPort(ContainerFlowConfig flowSpec) {
+        if (tpSrc == flowSpec.tpSrc) {
+            return true;
+        }
+        if (tpSrc == null || flowSpec.tpSrc == null) {
+            return false;
+        }
+        return tpSrc.equals(flowSpec.tpSrc);
+    }
+
+    /**
+     * Match Destination Layer4 Port.
+     *
+     * @param flowSpec Flow Specification
+     * @return true, if successful
+     */
+    private boolean matchDstPort(ContainerFlowConfig flowSpec) {
+        if (tpDst == flowSpec.tpDst) {
+            return true;
+        }
+        if (tpDst == null || flowSpec.tpDst == null) {
+            return false;
+        }
+        return this.tpDst.equals(flowSpec.tpDst);
+    }
+
+    /**
+     * Returns the vlan id number for all vlans specified
+     *
+     * @return the vlan id number for all vlans specified
+     */
+    public Set<Short> getVlanList() {
+        /*
+         * example: Vlan = "1,3,5-12"
+         * elemArray = ["1" "3" "5-12"]
+         * elem[2] = "5-12" --> limits = ["5" "12"]
+         * vlanList = [1 3 5 6 7 8 9 10 11 12]
+         */
+        Set<Short> vlanList = new HashSet<Short>();
+        try {
+            String[] elemArray = dlVlan.split(",");
+            for (String elem : elemArray) {
+                if (elem.contains("-")) {
+                    String[] limits = elem.split("-");
+                    for (short j = Short.valueOf(limits[0]); j <= Short.valueOf(limits[1]); j++) {
+                        vlanList.add(Short.valueOf(j));
+                    }
+                } else {
+                    vlanList.add(Short.valueOf(elem));
+                }
+            }
+        } catch (NumberFormatException e) {
+
+        }
+        return vlanList;
+    }
+
+    /**
+     * Returns the Source IP Address mask length.
+     *
+     * @return the Source IP Address mask length
+     */
+    public Short getSrcIPMaskLen() {
+        Short maskLen = 0;
+
+        if (nwSrc != null && !nwSrc.isEmpty()) {
+            String[] s = nwSrc.split("/");
+            if (s.length == 2) {
+                try {
+                    maskLen = Short.valueOf(s[1]);
+                } catch (Exception e) {
+                    // no mask or bad mask
+                }
+            } else {
+                InetAddress ip = this.getSrcIPNum();
+                maskLen = (short) ((ip instanceof Inet4Address) ? 32 : 128);
+            }
+        }
+        return maskLen;
+    }
+
+    /**
+     * Returns the Destination IP Address mask length.
+     *
+     * @return the Destination IP Address mask length
+     */
+    public Short getDstIPMaskLen() {
+        Short maskLen = 0;
+        if (nwDst != null && !nwDst.isEmpty()) {
+            String[] s = nwDst.split("/");
+            if (s.length == 2) {
+                try {
+                    maskLen = Short.valueOf(s[1]);
+                } catch (Exception e) {
+                    // no mask or bad mask
+                }
+            } else {
+                InetAddress ip = this.getDstIPNum();
+                maskLen = (short) ((ip instanceof Inet4Address) ? 32 : 128);
+            }
+        }
+        return maskLen;
+    }
+
+    /**
+     * Returns the Source IP Address.
+     *
+     * @return the Source IP Address
+     */
+    public InetAddress getSrcIPNum() {
+        InetAddress ip = null;
+        if (nwSrc == null || nwSrc.isEmpty()) {
+            try {
+                ip = InetAddress.getByAddress(new byte[16]);
+                return ip;
+            } catch (UnknownHostException e) {
+                log.error("", e);
+                return null;
+            }
+        }
+        try {
+            ip = InetAddress.getByName(nwSrc.split("/")[0]);
+        } catch (UnknownHostException e1) {
+            log.error("", e1);
+            return null;
+        }
+        return ip;
+    }
+
+    /**
+     * Returns the Destination IP Address.
+     *
+     * @return the Destination IP Address
+     */
+    public InetAddress getDstIPNum() {
+        InetAddress ip = null;
+        if (nwDst == null || nwDst.isEmpty()) {
+            try {
+                ip = InetAddress.getByAddress(new byte[16]);
+                return ip;
+            } catch (UnknownHostException e) {
+                log.error("",e);
+                return null;
+            }
+        }
+        try {
+            ip = InetAddress.getByName(nwDst.split("/")[0]);
+        } catch (UnknownHostException e1) {
+            log.error("", e1);
+            return null;
+        }
+        return ip;
+    }
+
+    /**
+     * Returns Source Layer4 Port number.
+     *
+     * @return Source Layer4 Port number
+     */
+    public Short getSrcPortNum() {
+        return (tpSrc == null || tpSrc.isEmpty()) ? Short.valueOf((short) 0)
+                : Short.valueOf(tpSrc);
+    }
+
+    /**
+     * Returns Destination Layer4 Port number.
+     *
+     * @return Destination Layer4 Port number
+     */
+    public Short getDstPortNum() {
+        return (tpDst == null || tpDst.isEmpty()) ? Short.valueOf((short) 0)
+                : Short.valueOf(tpDst);
+    }
+
+    /**
+     * Get the IP protocol value
+     *
+     * @return the protocol
+     */
+    public Short getProtoNum() {
+        return protocol == null ? null : IPProtocols.getProtocolNumberShort(protocol);
+    }
+
+    /**
+     * Returns whether this container flow overlap with the passed one This is
+     * true when any two of the resulting matches for the two container flow
+     * configurations intersect.
+     *
+     * @param other
+     *            the other container flow config with which checking the
+     *            overlap
+     * @return true if the two configurations overlap, false otherwise
+     */
+    public boolean overlap(ContainerFlowConfig other) {
+        if (other == null) {
+            return false;
+        }
+        List<Match> myMathes = this.getMatches();
+        List<Match> hisMatches = other.getMatches();
+        for (Match mine : myMathes) {
+            for (Match his : hisMatches) {
+                if (mine.intersetcs(his)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if this flow specification configuration is valid.
+     *
+     * @return true, if is valid
+     */
+    public Status validate() {
+        if (!isValidResourceName(name)) {
+            return new Status(StatusCode.BADREQUEST, "Invalid name");
+        }
+        Status status = validateVlan();
+        if (!status.isSuccess()) {
+            return status;
+        }
+        status = validateIPs();
+        if (!status.isSuccess()) {
+            return status;
+        }
+        if(!hasValidProtocol()) {
+            return new Status(StatusCode.BADREQUEST, "Invalid IP protocol");
+        }
+        if (!hasValidPorts()) {
+            return new Status(StatusCode.BADREQUEST, "Invalid Source or Destination Port");
+        }
+        if (this.getMatches().get(0).getMatches() == 0) {
+            return new Status(StatusCode.BADREQUEST, "Flow Spec is empty");
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    /**
+     * Validates the vlan number
+     *
+     * @return the result of the check as Status object
+     */
+    private Status validateVlan() {
+        if (dlVlan != null) {
+            short vlanId = 0;
+            try {
+                String[] elemArray = dlVlan.split(",");
+                for (String elem : elemArray) {
+                    if (elem.contains("-")) {
+                        String[] limits = elem.split("-");
+                        if (Short.parseShort(limits[0]) < 0
+                                || Short.parseShort(limits[0]) >= Short.parseShort(limits[1])
+                                || Short.parseShort(limits[1]) > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    } else {
+                        vlanId = Short.parseShort(elem);
+                        if (vlanId < 0 || vlanId > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    }
+                }
+            } catch (NumberFormatException e) {
+                return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+            }
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    /**
+     * Validates the network addresses, checks syntax and semantic
+     *
+     * @return the result of the check as Status object, if successful
+     */
+    private Status validateIPs() {
+        if (nwSrc != null) {
+            if (!NetUtils.isIPAddressValid(nwSrc)) {
+                return new Status(StatusCode.BADREQUEST, "Invalid network source address");
+            }
+            byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getSrcIPNum(), this.getSrcIPMaskLen()).getAddress();
+            long prefix = BitBufferHelper.getLong(bytePrefix);
+            if (prefix == 0) {
+                return new Status(StatusCode.BADREQUEST, "Invalid network source address: subnet zero");
+            }
+        }
+        if (nwDst != null) {
+            if (!NetUtils.isIPAddressValid(nwDst)) {
+                return new Status(StatusCode.BADREQUEST, "Invalid network destination address");
+            }
+            byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getDstIPNum(), this.getDstIPMaskLen()).getAddress();
+            long prefix = BitBufferHelper.getLong(bytePrefix);
+            if (prefix == 0) {
+                return new Status(StatusCode.BADREQUEST, "Invalid network destination address: subnet zero");
+            }
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    /**
+     * Validate the protocol field. Either it can be a enum defined in IPProtocols.java
+     * or a valid IP proto value between 0 and 255, see:
+     * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
+     * for more details.
+     *
+     * @return true if a valid protocol value
+     */
+    private boolean hasValidProtocol() {
+        IPProtocols p = IPProtocols.fromString(protocol);
+        return p != null;
+    }
+
+    /**
+     *
+     * @param tpPort
+     *               String representing the transport protocol port number
+     * @return true if tpPort contains a decimal value between 0 and 65535
+     */
+    private boolean hasValidPort(String tpPort) {
+        try {
+            int port = Integer.decode(tpPort);
+            return ((port >= 0) && (port <= 0xffff));
+        } catch (NumberFormatException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Validate the transport protocol source and destination ports as
+     * entered by users.
+     *
+     * @return true if ports are defined and are in valid range
+     */
+    private boolean hasValidPorts() {
+        if (tpSrc !=null && !tpSrc.isEmpty()) {
+            if (!hasValidPort(tpSrc)) {
+                return false;
+            }
+        }
+
+        if (tpDst !=null && !tpDst.isEmpty()) {
+            return hasValidPort(tpDst);
+        }
+        return true;
+    }
+
+    /**
+     * Returns the matches.
+     * If unidirectional flag is set, there will be only one match per vlan in the list
+     * If unidirectional flag is unset there will be two matches per vlan in the list,
+     * only if the specified flow has an intrinsic direction.
+     * For Ex. if the cFlow only has the protocol field configured, no matter
+     * if unidirectional flag is set or not, only one match per vlan will be returned
+     * The client just has to iterate over the returned list
+     * @return the matches
+     */
+    public List<Match> getMatches() {
+        List<Match> matches = new ArrayList<Match>();
+
+        if (this.dlVlan != null && !this.dlVlan.isEmpty()) {
+            for(Short vlan:getVlanList()){
+                Match match = getMatch(vlan);
+                matches.add(match);
+            }
+        }
+        else{
+            Match match = getMatch(null);
+            matches.add(match);
+        }
+
+        if (!ContainerFlowConfig.unidirectional) {
+            List<Match> forwardMatches = new ArrayList<Match>(matches);
+            for (Match match : forwardMatches) {
+                Match reverse = match.reverse();
+                if (!match.equals(reverse)) {
+                    matches.add(reverse);
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    private Match getMatch(Short vlan){
+        Match match = new Match();
+
+        if (vlan != null) {
+            match.setField(MatchType.DL_VLAN, vlan);
+        }
+        if (this.nwSrc != null && !this.nwSrc.trim().isEmpty()) {
+            String parts[] = this.nwSrc.split("/");
+            InetAddress ip = NetUtils.parseInetAddress(parts[0]);
+            InetAddress mask = null;
+            int maskLen = 0;
+            if (parts.length > 1) {
+                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 && !this.nwDst.trim().isEmpty()) {
+            String parts[] = this.nwDst.split("/");
+            InetAddress ip = NetUtils.parseInetAddress(parts[0]);
+            InetAddress mask = null;
+            int maskLen = 0;
+            if (parts.length > 1) {
+                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 (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
+            match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
+        }
+        if (this.tpSrc != null && !this.tpSrc.trim().isEmpty()) {
+            match.setField(MatchType.TP_SRC, Integer.valueOf(tpSrc).shortValue());
+        }
+        if (this.tpDst != null && !this.tpDst.trim().isEmpty()) {
+            match.setField(MatchType.TP_DST, Integer.valueOf(tpDst).shortValue());
+        }
+        return match;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "Container Flow={name:" + name + " dlVlan:" + dlVlan + " nwSrc:" + nwSrc + " nwDst:" + nwDst + " " + "protocol:" + protocol
+                + " tpSrc:" + tpSrc + " tpDst:" + tpDst + "}";
+    }
+}