--- /dev/null
+
+/*
+ * 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 + "}";
+ }
+}