X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fforwardingrulesmanager%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fforwardingrulesmanager%2FFlowConfig.java;h=de6b8182b07c71c8975cd5fcfa49e3326197ef9e;hp=8a77825d7943c12e8be971687cb4f3e8ac187b72;hb=5913578c89e52af7a7b755d69b2bb5db0939cd27;hpb=cc5814b25b247f5ffe0c17ede1850e71ca06eee6 diff --git a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java index 8a77825d79..de6b8182b0 100644 --- a/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java +++ b/opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java @@ -8,24 +8,11 @@ package org.opendaylight.controller.forwardingrulesmanager; -import java.io.Serializable; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -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.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; import org.opendaylight.controller.sal.action.Controller; import org.opendaylight.controller.sal.action.Drop; +import org.opendaylight.controller.sal.action.Enqueue; import org.opendaylight.controller.sal.action.Flood; import org.opendaylight.controller.sal.action.HwPath; import org.opendaylight.controller.sal.action.Loopback; @@ -62,6 +49,18 @@ import org.opendaylight.controller.switchmanager.Switch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +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 java.io.Serializable; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Configuration Java Object which represents a flow configuration information * for Forwarding Rules Manager. @@ -71,9 +70,11 @@ import org.slf4j.LoggerFactory; public class FlowConfig implements Serializable { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(FlowConfig.class); - public static final String staticFlowsGroup = "**StaticFlows"; - public static final String internalStaticFlowsGroup = "**InternalStaticFlows"; - public static final String internalStaticFlowBegin = "**"; + 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; @@ -186,13 +187,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() { @@ -200,8 +201,9 @@ public class FlowConfig implements Serializable { } public boolean isInternalFlow() { - // Controller generated static flows have name starting with "**" - return (this.name != null && this.name.startsWith(FlowConfig.internalStaticFlowBegin)); + return (this.name != null && + this.name.startsWith(FlowConfig.INTERNALSTATICFLOWBEGIN) && + this.name.endsWith(FlowConfig.INTERNALSTATICFLOWEND)); } public String getName() { @@ -606,25 +608,13 @@ public class FlowConfig implements Serializable { return true; } - public boolean isPortValid(Switch sw, Short port) { - if (port < 1) { - log.debug("port {} is not valid", port); - return false; - } - + public boolean isPortValid(Switch sw, String port) { if (sw == null) { log.debug("switch info is not available. Skip checking if port is part of a switch or not."); return true; } - - Set nodeConnectorSet = sw.getNodeConnectors(); - for (NodeConnector nodeConnector : nodeConnectorSet) { - if (((Short) nodeConnector.getID()).equals(port)) { - return true; - } - } - log.debug("port {} is not a valid port of node {}", port, sw.getNode()); - return false; + NodeConnector nc = NodeConnectorCreator.createNodeConnector(port, sw.getNode()); + return sw.getNodeConnectors().contains(nc); } public boolean isVlanIdValid(String vlanId) { @@ -644,7 +634,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) { @@ -652,6 +642,11 @@ public class FlowConfig implements Serializable { return ((to >= 0) && (to <= 0xffff)); } + 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())) { @@ -692,7 +687,7 @@ public class FlowConfig implements Serializable { Switch sw = null; try { - if (name == null || name.trim().isEmpty()) { + if (name == null || name.trim().isEmpty() || !name.matches(FlowConfig.NAMEREGEX)) { return new Status(StatusCode.BADREQUEST, "Invalid name"); } @@ -727,11 +722,10 @@ public class FlowConfig implements Serializable { } if (ingressPort != null) { - Short port = Short.decode(ingressPort); - if (isPortValid(sw, port) == false) { - String msg = String.format("Ingress port %d is not valid for the Switch", port); - if ((container != null) && !container.getName().equals(GlobalConstants.DEFAULT.toString())) { - msg += " in Container " + container.getName(); + if (!isPortValid(sw, ingressPort)) { + String msg = String.format("Ingress port %s is not valid for the Switch", ingressPort); + if (!containerName.equals(GlobalConstants.DEFAULT.toString())) { + msg += " in Container " + containerName; } return new Status(StatusCode.BADREQUEST, msg); } @@ -759,6 +753,10 @@ public class FlowConfig implements Serializable { } } + if ((protocol != null) && !isProtocolValid(protocol)) { + return new Status(StatusCode.BADREQUEST, String.format("Protocol %s is not valid", protocol)); + } + if ((tosBits != null) && !isTOSBitsValid(tosBits)) { return new Status(StatusCode.BADREQUEST, String.format("IP ToS bits %s is not in the range 0 - 63", tosBits)); @@ -829,133 +827,146 @@ public class FlowConfig implements Serializable { } 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) { - String msg = String.format("Output port %d is not valid for this switch", port); - if ((container != null) - && !container.getName().equals(GlobalConstants.DEFAULT.toString())) { - msg += " in Container " + container.getName(); - } - return new Status(StatusCode.BADREQUEST, msg); - } + 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(",")) { + if (t != null) { + if (!isPortValid(sw, t)) { + String msg = String.format("Output port %s is not valid for this switch", t); + 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) { - return new Status(StatusCode.BADREQUEST, String.format( - "flood is not allowed in container %s", container.getName())); + continue; + } + // check enqueue + sstr = Pattern.compile("ENQUEUE=(.*)").matcher(actiongrp); + if (sstr.matches()) { + for (String t : sstr.group(1).split(",")) { + if (t != null) { + String port = t.split(":")[0]; + if (!isPortValid(sw, port)) { + 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.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))); - } - 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 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; + 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))); } + 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))) { - 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_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))) { - 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_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))) { - return new Status(StatusCode.BADREQUEST, String.format( - "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f", - 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))) { + 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))) { - 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; + 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))) { - 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_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))) { - return new Status(StatusCode.BADREQUEST, String.format( - "Transport source port %s is not valid", 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))) { + 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))) { - return new Status(StatusCode.BADREQUEST, String.format( - "Transport destination 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))) { + 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()) { - if (!NetUtils.isIPAddressValid(sstr.group(1))) { - return new Status(StatusCode.BADREQUEST, String.format( - "IP destination address %s is not valid", sstr.group(1))); - } - 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 Status status; - if ((container != null) && !(status = conflictWithContainerFlow(container)).isSuccess()) { + if (!containerName.equals(GlobalConstants.DEFAULT.toString()) && !(status = conflictWithContainerFlow(container)).isSuccess()) { return status; } } catch (NumberFormatException e) { @@ -966,7 +977,8 @@ public class FlowConfig implements Serializable { } 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() { @@ -974,7 +986,7 @@ public class FlowConfig implements Serializable { if (this.ingressPort != null) { match.setField(MatchType.IN_PORT, - NodeConnectorCreator.createOFNodeConnector(Short.parseShort(ingressPort), getNode())); + NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString()))); } if (this.dlSrc != null) { match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc)); @@ -1017,7 +1029,7 @@ public class FlowConfig implements Serializable { mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address); match.setField(MatchType.NW_DST, ip, mask); } - if (this.protocol != null) { + if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) { match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol)); } if (this.tosBits != null) { @@ -1031,6 +1043,7 @@ public class FlowConfig implements Serializable { } Flow flow = new Flow(match, getActionList()); + if (this.cookie != null) { flow.setId(Long.parseLong(cookie)); } @@ -1043,6 +1056,8 @@ public class FlowConfig implements Serializable { if (this.priority != null) { flow.setPriority(Integer.decode(this.priority).shortValue()); } + + return flow; } @@ -1059,7 +1074,7 @@ public class FlowConfig implements Serializable { } public void toggleInstallation() { - installInHw = (installInHw == null) ? "true" : (installInHw.equals("true")) ? "false" : "true"; + installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw)); } /* @@ -1076,12 +1091,25 @@ public class FlowConfig implements Serializable { 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()))); + if (t != null) { + String nc = String.format("%s|%s@%s", node.getType(), t, node.toString()); + actionList.add(new Output(NodeConnector.fromString(nc))); + } + } + continue; + } + + sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp); + if (sstr.matches()) { + for (String t : sstr.group(1).split(",")) { + if (t != null) { + String parts[] = t.split(":"); + String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString()); + if (parts.length == 1) { + actionList.add(new Enqueue(NodeConnector.fromString(nc))); + } else { + actionList + .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1]))); } } }