2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.forwardingrulesmanager;
11 import java.io.Serializable;
12 import java.net.Inet6Address;
13 import java.net.InetAddress;
14 import java.util.ArrayList;
15 import java.util.List;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
20 import javax.xml.bind.annotation.XmlAccessType;
21 import javax.xml.bind.annotation.XmlAccessorType;
22 import javax.xml.bind.annotation.XmlElement;
23 import javax.xml.bind.annotation.XmlRootElement;
25 import org.opendaylight.controller.sal.action.Action;
26 import org.opendaylight.controller.sal.action.ActionType;
27 import org.opendaylight.controller.sal.action.Controller;
28 import org.opendaylight.controller.sal.action.Drop;
29 import org.opendaylight.controller.sal.action.Flood;
30 import org.opendaylight.controller.sal.action.HwPath;
31 import org.opendaylight.controller.sal.action.Loopback;
32 import org.opendaylight.controller.sal.action.Output;
33 import org.opendaylight.controller.sal.action.PopVlan;
34 import org.opendaylight.controller.sal.action.SetDlDst;
35 import org.opendaylight.controller.sal.action.SetDlSrc;
36 import org.opendaylight.controller.sal.action.SetNextHop;
37 import org.opendaylight.controller.sal.action.SetNwDst;
38 import org.opendaylight.controller.sal.action.SetNwSrc;
39 import org.opendaylight.controller.sal.action.SetNwTos;
40 import org.opendaylight.controller.sal.action.SetTpDst;
41 import org.opendaylight.controller.sal.action.SetTpSrc;
42 import org.opendaylight.controller.sal.action.SetVlanId;
43 import org.opendaylight.controller.sal.action.SetVlanPcp;
44 import org.opendaylight.controller.sal.action.SwPath;
45 import org.opendaylight.controller.sal.core.ContainerFlow;
46 import org.opendaylight.controller.sal.core.IContainer;
47 import org.opendaylight.controller.sal.core.Node;
48 import org.opendaylight.controller.sal.core.NodeConnector;
49 import org.opendaylight.controller.sal.flowprogrammer.Flow;
50 import org.opendaylight.controller.sal.match.Match;
51 import org.opendaylight.controller.sal.match.MatchType;
52 import org.opendaylight.controller.sal.utils.GlobalConstants;
53 import org.opendaylight.controller.sal.utils.HexEncode;
54 import org.opendaylight.controller.sal.utils.IPProtocols;
55 import org.opendaylight.controller.sal.utils.NetUtils;
56 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
57 import org.opendaylight.controller.sal.utils.ServiceHelper;
58 import org.opendaylight.controller.sal.utils.StatusCode;
59 import org.opendaylight.controller.switchmanager.ISwitchManager;
60 import org.opendaylight.controller.switchmanager.Switch;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
65 * Configuration Java Object which represents a flow configuration information
66 * for Forwarding Rules Manager.
70 @XmlAccessorType(XmlAccessType.NONE)
71 public class FlowConfig implements Serializable {
72 private static final long serialVersionUID = 1L;
73 private static final Logger log = LoggerFactory.getLogger(FlowConfig.class);
74 private static final String staticFlowsGroup = "**StaticFlows";
75 private boolean dynamic;
76 private String status;
79 * The order of the object data defined below is used directly in the UI
80 * built using JSP. Hence try to keep the order in a more logical way.
83 private String installInHw;
89 private String ingressPort;
90 private String portGroup;
92 private String priority;
94 private String etherType;
96 private String vlanId;
98 private String vlanPriority;
100 private String dlSrc;
102 private String dlDst;
104 private String nwSrc;
106 private String nwDst;
108 private String protocol;
110 private String tosBits;
112 private String tpSrc;
114 private String tpDst;
116 private String cookie;
118 private String idleTimeout;
120 private String hardTimeout;
122 private List<String> actions;
124 private enum EtherIPType {
128 public FlowConfig() {
131 public FlowConfig(String installInHw, String name, Node node,
132 String priority, String cookie, String ingressPort,
133 String portGroup, String vlanId, String vlanPriority,
134 String etherType, String srcMac, String dstMac, String protocol,
135 String tosBits, String srcIP, String dstIP, String tpSrc,
136 String tpDst, String idleTimeout, String hardTimeout,
137 List<String> actions) {
139 this.installInHw = installInHw;
142 this.priority = priority;
143 this.cookie = cookie;
144 this.ingressPort = ingressPort;
145 this.portGroup = portGroup;
146 this.vlanId = vlanId;
147 this.vlanPriority = vlanPriority;
148 this.etherType = etherType;
151 this.protocol = protocol;
152 this.tosBits = tosBits;
157 this.idleTimeout = idleTimeout;
158 this.hardTimeout = hardTimeout;
159 this.actions = actions;
160 this.status = StatusCode.SUCCESS.toString();
163 public FlowConfig(FlowConfig from) {
164 this.installInHw = from.installInHw;
165 this.name = from.name;
166 this.node = from.node;
167 this.priority = from.priority;
168 this.cookie = from.cookie;
169 this.ingressPort = from.ingressPort;
170 this.portGroup = from.portGroup;
171 this.vlanId = from.vlanId;
172 this.vlanPriority = from.vlanPriority;
173 this.etherType = from.etherType;
174 this.dlSrc = from.dlSrc;
175 this.dlDst = from.dlDst;
176 this.protocol = from.protocol;
177 this.tosBits = from.tosBits;
178 this.nwSrc = from.nwSrc;
179 this.nwDst = from.nwDst;
180 this.tpSrc = from.tpSrc;
181 this.tpDst = from.tpDst;
182 this.idleTimeout = from.idleTimeout;
183 this.hardTimeout = from.hardTimeout;
184 this.actions = new ArrayList<String>(from.actions);
187 public boolean installInHw() {
188 if (installInHw == null) {
189 // backward compatibility
190 installInHw = "true";
192 return installInHw.equals("true");
195 public void setInstallInHw(boolean inHw) {
196 installInHw = inHw ? "true" : "false";
199 public String getInstallInHw() {
203 public boolean isInternalFlow() {
204 // Controller generated static flows have name starting with "**"
205 return (this.name != null && this.name.startsWith("**"));
208 public String getName() {
212 public void setName(String name) {
219 public Node getNode() {
223 public void setNode(Node node) {
227 public String getPriority() {
231 public void setPriority(String priority) {
232 this.priority = priority;
235 public String getCookie() {
239 public void setCookie(String cookie) {
240 this.cookie = cookie;
243 public String getIngressPort() {
247 public void setIngressPort(String ingressPort) {
248 this.ingressPort = ingressPort;
251 public String getPortGroup() {
256 public String toString() {
257 return "FlowConfig [dynamic=" + dynamic + ", status=" + status
258 + ", installInHw=" + installInHw + ", name=" + name
259 + ", switchId=" + node + ", ingressPort=" + ingressPort
260 + ", portGroup=" + portGroup + ", etherType=" + etherType
261 + ", priority=" + priority + ", vlanId=" + vlanId
262 + ", vlanPriority=" + vlanPriority + ", dlSrc=" + dlSrc
263 + ", dlDst=" + dlDst + ", nwSrc=" + nwSrc + ", nwDst=" + nwDst
264 + ", protocol=" + protocol + ", tosBits=" + tosBits
265 + ", tpSrc=" + tpSrc + ", tpDst=" + tpDst + ", cookie="
266 + cookie + ", idleTimeout=" + idleTimeout + ", hardTimeout="
267 + hardTimeout + ", actions=" + actions + "]";
270 public void setPortGroup(String portGroup) {
271 this.portGroup = portGroup;
274 public String getVlanId() {
278 public void setVlanId(String vlanId) {
279 this.vlanId = vlanId;
282 public String getVlanPriority() {
286 public void setVlanPriority(String vlanPriority) {
287 this.vlanPriority = vlanPriority;
290 public String getEtherType() {
294 public void setEtherType(String etherType) {
295 this.etherType = etherType;
298 public String getSrcMac() {
302 public void setSrcMac(String srcMac) {
306 public String getDstMac() {
310 public void setDstMac(String dstMac) {
314 public String getProtocol() {
318 public void setProtocol(String protocol) {
319 this.protocol = protocol;
322 public String getTosBits() {
326 public void setTosBits(String tos_bits) {
327 this.tosBits = tos_bits;
330 public String getSrcIp() {
334 public void setSrcIp(String src_ip) {
338 public String getDstIp() {
342 public void setDstIp(String dst_ip) {
346 public String getSrcPort() {
350 public void setSrcPort(String src_port) {
351 this.tpSrc = src_port;
354 public String getDstPort() {
358 public void setDstPort(String dst_port) {
359 this.tpDst = dst_port;
362 public String getIdleTimeout() {
366 public void setIdleTimeout(String idleTimeout) {
367 this.idleTimeout = idleTimeout;
370 public String getHardTimeout() {
374 public void setHardTimeout(String hardTimeout) {
375 this.hardTimeout = hardTimeout;
378 public boolean isIPv6() {
379 if (NetUtils.isIPv6AddressValid(this.getSrcIp())
380 || NetUtils.isIPv6AddressValid(this.getDstIp())) {
386 public List<String> getActions() {
390 public void setActions(List<String> actions) {
391 this.actions = actions;
394 public boolean isPortGroupEnabled() {
395 return (portGroup != null);
398 public boolean isDynamic() {
402 public void setDynamic(boolean dynamic) {
403 this.dynamic = dynamic;
406 public String getStatus() {
410 public void setStatus(String status) {
411 this.status = status;
414 public boolean isStatusSuccessful() {
415 return status.equals(StatusCode.SUCCESS.toString());
419 public int hashCode() {
420 final int prime = 31;
422 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
423 result = prime * result + ((cookie == null) ? 0 : cookie.hashCode());
424 result = prime * result + ((dlDst == null) ? 0 : dlDst.hashCode());
425 result = prime * result + ((dlSrc == null) ? 0 : dlSrc.hashCode());
426 result = prime * result + (dynamic ? 1231 : 1237);
427 result = prime * result
428 + ((etherType == null) ? 0 : etherType.hashCode());
429 result = prime * result
430 + ((ingressPort == null) ? 0 : ingressPort.hashCode());
431 result = prime * result + ((name == null) ? 0 : name.hashCode());
432 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
433 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
434 result = prime * result
435 + ((portGroup == null) ? 0 : portGroup.hashCode());
436 result = prime * result
437 + ((priority == null) ? 0 : priority.hashCode());
438 result = prime * result
439 + ((protocol == null) ? 0 : protocol.hashCode());
440 result = prime * result + ((node == null) ? 0 : node.hashCode());
441 result = prime * result + ((tosBits == null) ? 0 : tosBits.hashCode());
442 result = prime * result + ((tpDst == null) ? 0 : tpDst.hashCode());
443 result = prime * result + ((tpSrc == null) ? 0 : tpSrc.hashCode());
444 result = prime * result + ((vlanId == null) ? 0 : vlanId.hashCode());
445 result = prime * result
446 + ((vlanPriority == null) ? 0 : vlanPriority.hashCode());
447 result = prime * result
448 + ((idleTimeout == null) ? 0 : idleTimeout.hashCode());
449 result = prime * result
450 + ((hardTimeout == null) ? 0 : hardTimeout.hashCode());
455 public boolean equals(Object obj) {
462 if (getClass() != obj.getClass()) {
465 FlowConfig other = (FlowConfig) obj;
466 if (actions == null) {
467 if (other.actions != null) {
470 } else if (!actions.equals(other.actions)) {
473 if (cookie == null) {
474 if (other.cookie != null) {
477 } else if (!cookie.equals(other.cookie)) {
481 if (other.dlDst != null) {
484 } else if (!dlDst.equals(other.dlDst)) {
488 if (other.dlSrc != null) {
491 } else if (!dlSrc.equals(other.dlSrc)) {
494 if (dynamic != other.dynamic) {
497 if (etherType == null) {
498 if (other.etherType != null) {
501 } else if (!etherType.equals(other.etherType)) {
504 if (ingressPort == null) {
505 if (other.ingressPort != null) {
508 } else if (!ingressPort.equals(other.ingressPort)) {
512 if (other.name != null) {
515 } else if (!name.equals(other.name)) {
519 if (other.nwDst != null) {
522 } else if (!nwDst.equals(other.nwDst)) {
526 if (other.nwSrc != null) {
529 } else if (!nwSrc.equals(other.nwSrc)) {
532 if (portGroup == null) {
533 if (other.portGroup != null) {
536 } else if (!portGroup.equals(other.portGroup)) {
539 if (priority == null) {
540 if (other.priority != null) {
543 } else if (!priority.equals(other.priority)) {
546 if (protocol == null) {
547 if (other.protocol != null) {
550 } else if (!protocol.equals(other.protocol)) {
554 if (other.node != null) {
557 } else if (!node.equals(other.node)) {
560 if (tosBits == null) {
561 if (other.tosBits != null) {
564 } else if (!tosBits.equals(other.tosBits)) {
568 if (other.tpDst != null) {
571 } else if (!tpDst.equals(other.tpDst)) {
575 if (other.tpSrc != null) {
578 } else if (!tpSrc.equals(other.tpSrc)) {
581 if (vlanId == null) {
582 if (other.vlanId != null) {
585 } else if (!vlanId.equals(other.vlanId)) {
588 if (vlanPriority == null) {
589 if (other.vlanPriority != null) {
592 } else if (!vlanPriority.equals(other.vlanPriority)) {
595 if (idleTimeout == null) {
596 if (other.idleTimeout != null) {
599 } else if (!idleTimeout.equals(other.idleTimeout)) {
602 if (hardTimeout == null) {
603 if (other.hardTimeout != null) {
606 } else if (!hardTimeout.equals(other.hardTimeout)) {
612 public boolean isL2AddressValid(String mac) {
617 Pattern macPattern = Pattern
618 .compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
619 Matcher mm = macPattern.matcher(mac);
622 "Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f",
629 public boolean isPortValid(Switch sw, Short port) {
631 log.debug("port {} is not valid", port);
636 log.debug("switch info is not available. Skip checking if port is part of a switch or not.");
640 Set<NodeConnector> nodeConnectorSet = sw.getNodeConnectors();
641 for (NodeConnector nodeConnector : nodeConnectorSet) {
642 if (((Short) nodeConnector.getID()).equals(port)) {
646 log.debug("port {} is not a valid port of node {}", port, sw.getNode());
650 public boolean isVlanIdValid(String vlanId) {
651 int vlan = Integer.decode(vlanId);
652 return ((vlan >= 0) && (vlan < 4096));
655 public boolean isVlanPriorityValid(String vlanPriority) {
656 int pri = Integer.decode(vlanPriority);
657 return ((pri >= 0) && (pri < 8));
660 public boolean isTOSBitsValid(String tosBits) {
661 int tos = Integer.decode(tosBits);
662 return ((tos >= 0) && (tos < 64));
665 public boolean isTpPortValid(String tpPort) {
666 int port = Integer.decode(tpPort);
667 return ((port > 0) && (port <= 0xffff));
670 public boolean isTimeoutValid(String timeout) {
671 int to = Integer.decode(timeout);
672 return ((to >= 0) && (to <= 0xffff));
675 private boolean conflictWithContainerFlow(IContainer container,
676 StringBuffer resultStr) {
677 // Return true if it's default container
678 if (container.getName().equals(GlobalConstants.DEFAULT.toString())) {
682 // No container flow = no conflict
683 List<ContainerFlow> cFlowList = container.getContainerFlows();
684 if (((cFlowList == null)) || cFlowList.isEmpty()) {
688 // Check against each container's flow
689 Flow flow = this.getFlow();
691 // Configuration is rejected if it conflicts with _all_ the container
693 for (ContainerFlow cFlow : cFlowList) {
694 if (cFlow.allowsFlow(flow)) {
695 log.trace("Config is congruent with at least one container flow");
699 String msg = "Flow Config conflicts with all existing container flows";
700 resultStr.append(msg);
706 public boolean isValid(IContainer container, StringBuffer resultStr) {
707 EtherIPType etype = EtherIPType.ANY;
708 EtherIPType ipsrctype = EtherIPType.ANY;
709 EtherIPType ipdsttype = EtherIPType.ANY;
711 String containerName = (container == null) ? GlobalConstants.DEFAULT
712 .toString() : container.getName();
713 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
714 .getInstance(ISwitchManager.class, containerName, this);
719 resultStr.append(String.format("Name is null"));
723 resultStr.append(String.format("Node is null"));
726 if (switchManager != null) {
727 for (Switch device : switchManager.getNetworkDevices()) {
728 if (device.getNode().equals(node)) {
734 resultStr.append(String.format("Node %s not found", node));
738 log.debug("switchmanager is not set yet");
741 if (priority != null) {
742 if (Integer.decode(priority) < 0
743 || (Integer.decode(priority) > 65535)) {
744 resultStr.append(String.format(
745 "priority %s is not in the range 0 - 65535",
751 // make sure it's a valid number
752 if (cookie != null) {
756 if (ingressPort != null) {
757 Short port = Short.decode(ingressPort);
758 if (isPortValid(sw, port) == false) {
761 .format("Ingress port %d is not valid for the Switch",
763 if ((container != null)
764 && !container.getName().equals(
765 GlobalConstants.DEFAULT.toString())) {
767 .append(" in Container " + container.getName());
773 if ((vlanId != null) && !isVlanIdValid(vlanId)) {
774 resultStr.append(String.format(
775 "Vlan ID %s is not in the range 0 - 4095", vlanId));
779 if ((vlanPriority != null) && !isVlanPriorityValid(vlanPriority)) {
780 resultStr.append(String.format(
781 "Vlan priority %s is not in the range 0 - 7",
786 if (etherType != null) {
787 int type = Integer.decode(etherType);
788 if ((type < 0) || (type > 0xffff)) {
789 resultStr.append(String.format(
790 "Ethernet type %s is not valid", etherType));
794 etype = EtherIPType.V4;
795 } else if (type == 0x86dd) {
796 etype = EtherIPType.V6;
801 if ((tosBits != null) && !isTOSBitsValid(tosBits)) {
802 resultStr.append(String.format(
803 "IP ToS bits %s is not in the range 0 - 63", tosBits));
807 if ((tpSrc != null) && !isTpPortValid(tpSrc)) {
808 resultStr.append(String.format(
809 "Transport source port %s is not valid", tpSrc));
812 if ((tpDst != null) && !isTpPortValid(tpDst)) {
813 resultStr.append(String.format(
814 "Transport destination port %s is not valid", tpDst));
818 if ((dlSrc != null) && !isL2AddressValid(dlSrc)) {
821 .format("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
826 if ((dlDst != null) && !isL2AddressValid(dlDst)) {
829 .format("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
835 if (NetUtils.isIPv4AddressValid(nwSrc)) {
836 ipsrctype = EtherIPType.V4;
837 } else if (NetUtils.isIPv6AddressValid(nwSrc)) {
838 ipsrctype = EtherIPType.V6;
840 resultStr.append(String.format(
841 "IP source address %s is not valid", nwSrc));
847 if (NetUtils.isIPv4AddressValid(nwDst)) {
848 ipdsttype = EtherIPType.V4;
849 } else if (NetUtils.isIPv6AddressValid(nwDst)) {
850 ipdsttype = EtherIPType.V6;
852 resultStr.append(String.format(
853 "IP destination address %s is not valid", nwDst));
858 if (etype != EtherIPType.ANY) {
859 if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
860 resultStr.append(String
861 .format("Type mismatch between Ethernet & Src IP"));
864 if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
865 resultStr.append(String
866 .format("Type mismatch between Ethernet & Dst IP"));
870 if (ipsrctype != ipdsttype) {
871 if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
873 .append(String.format("IP Src Dest Type mismatch"));
878 if ((idleTimeout != null) && !isTimeoutValid(idleTimeout)) {
879 resultStr.append(String.format(
880 "Idle Timeout value %s is not valid", idleTimeout));
884 if ((hardTimeout != null) && !isTimeoutValid(hardTimeout)) {
885 resultStr.append(String.format(
886 "Hard Timeout value %s is not valid", hardTimeout));
891 if (actions != null && !actions.isEmpty()) {
892 for (String actiongrp : actions) {
893 // check output ports
894 sstr = Pattern.compile("OUTPUT=(.*)").matcher(actiongrp);
895 if (sstr.matches()) {
896 for (String t : sstr.group(1).split(",")) {
897 Matcher n = Pattern.compile("(?:(\\d+))")
900 if (n.group(1) != null) {
901 Short port = Short.parseShort(n.group(1));
902 if (isPortValid(sw, port) == false) {
905 .format("Output port %d is not valid for this switch",
907 if ((container != null)
908 && !container.getName().equals(
909 GlobalConstants.DEFAULT
911 resultStr.append(" in Container "
912 + container.getName());
922 sstr = Pattern.compile(ActionType.FLOOD.toString())
924 if (sstr.matches()) {
925 if (container != null) {
926 resultStr.append(String.format(
927 "flood is not allowed in container %s",
928 container.getName()));
934 sstr = Pattern.compile(
935 ActionType.SET_NW_SRC.toString() + "=(.*)")
937 if (sstr.matches()) {
938 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
939 resultStr.append(String.format(
940 "IP source address %s is not valid",
947 sstr = Pattern.compile(
948 ActionType.SET_NW_DST.toString() + "=(.*)")
950 if (sstr.matches()) {
951 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
952 resultStr.append(String.format(
953 "IP destination address %s is not valid",
960 sstr = Pattern.compile(
961 ActionType.SET_VLAN_ID.toString() + "=(.*)")
963 if (sstr.matches()) {
964 if ((sstr.group(1) != null)
965 && !isVlanIdValid(sstr.group(1))) {
966 resultStr.append(String.format(
967 "Vlan ID %s is not in the range 0 - 4095",
974 sstr = Pattern.compile(
975 ActionType.SET_VLAN_PCP.toString() + "=(.*)")
977 if (sstr.matches()) {
978 if ((sstr.group(1) != null)
979 && !isVlanPriorityValid(sstr.group(1))) {
982 .format("Vlan priority %s is not in the range 0 - 7",
989 sstr = Pattern.compile(
990 ActionType.SET_DL_SRC.toString() + "=(.*)")
992 if (sstr.matches()) {
993 if ((sstr.group(1) != null)
994 && !isL2AddressValid(sstr.group(1))) {
997 .format("Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
1004 sstr = Pattern.compile(
1005 ActionType.SET_DL_DST.toString() + "=(.*)")
1006 .matcher(actiongrp);
1007 if (sstr.matches()) {
1008 if ((sstr.group(1) != null)
1009 && !isL2AddressValid(sstr.group(1))) {
1012 .format("Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
1019 sstr = Pattern.compile(
1020 ActionType.SET_NW_TOS.toString() + "=(.*)")
1021 .matcher(actiongrp);
1022 if (sstr.matches()) {
1023 if ((sstr.group(1) != null)
1024 && !isTOSBitsValid(sstr.group(1))) {
1027 .format("IP ToS bits %s is not in the range 0 - 63",
1034 sstr = Pattern.compile(
1035 ActionType.SET_TP_SRC.toString() + "=(.*)")
1036 .matcher(actiongrp);
1037 if (sstr.matches()) {
1038 if ((sstr.group(1) != null)
1039 && !isTpPortValid(sstr.group(1))) {
1040 resultStr.append(String.format(
1041 "Transport source port %s is not valid",
1048 sstr = Pattern.compile(
1049 ActionType.SET_TP_DST.toString() + "=(.*)")
1050 .matcher(actiongrp);
1051 if (sstr.matches()) {
1052 if ((sstr.group(1) != null)
1053 && !isTpPortValid(sstr.group(1))) {
1056 .format("Transport destination port %s is not valid",
1062 sstr = Pattern.compile(
1063 ActionType.SET_NEXT_HOP.toString() + "=(.*)")
1064 .matcher(actiongrp);
1065 if (sstr.matches()) {
1066 if (!NetUtils.isIPAddressValid(sstr.group(1))) {
1067 resultStr.append(String.format(
1068 "IP destination address %s is not valid",
1076 // Check against the container flow
1077 if ((container != null)
1078 && conflictWithContainerFlow(container, resultStr)) {
1081 } catch (NumberFormatException e) {
1082 resultStr.append(String.format("Invalid number format %s",
1090 public FlowEntry getFlowEntry() {
1091 return new FlowEntry(FlowConfig.staticFlowsGroup, this.name,
1092 this.getFlow(), this.getNode());
1095 public Flow getFlow() {
1096 Match match = new Match();
1098 if (this.ingressPort != null) {
1101 NodeConnectorCreator.createOFNodeConnector(
1102 Short.parseShort(ingressPort), getNode()));
1104 if (this.dlSrc != null) {
1105 match.setField(MatchType.DL_SRC,
1106 HexEncode.bytesFromHexString(this.dlSrc));
1108 if (this.dlDst != null) {
1109 match.setField(MatchType.DL_DST,
1110 HexEncode.bytesFromHexString(this.dlDst));
1112 if (this.etherType != null) {
1113 match.setField(MatchType.DL_TYPE, Integer.decode(etherType)
1116 if (this.vlanId != null) {
1117 match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
1119 if (this.vlanPriority != null) {
1120 match.setField(MatchType.DL_VLAN_PR,
1121 Byte.parseByte(this.vlanPriority));
1123 if (this.nwSrc != null) {
1124 String parts[] = this.nwSrc.split("/");
1125 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
1126 InetAddress mask = null;
1127 if (parts.length > 1) {
1128 int maskLen = Integer.parseInt(parts[1]);
1129 mask = NetUtils.getInetNetworkMask(maskLen,
1130 ip instanceof Inet6Address);
1132 match.setField(MatchType.NW_SRC, ip, mask);
1134 if (this.nwDst != null) {
1135 String parts[] = this.nwDst.split("/");
1136 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
1137 InetAddress mask = null;
1138 if (parts.length > 1) {
1139 int maskLen = Integer.parseInt(parts[1]);
1140 mask = NetUtils.getInetNetworkMask(maskLen,
1141 ip instanceof Inet6Address);
1143 match.setField(MatchType.NW_DST, ip, mask);
1145 if (this.protocol != null) {
1146 match.setField(MatchType.NW_PROTO,
1147 IPProtocols.getProtocolNumberByte(this.protocol));
1149 if (this.tosBits != null) {
1150 match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
1152 if (this.tpSrc != null) {
1153 match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc)
1156 if (this.tpDst != null) {
1157 match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst)
1161 Flow flow = new Flow(match, getActionList());
1162 if (this.cookie != null) {
1163 flow.setId(Long.parseLong(cookie));
1165 if (this.hardTimeout != null) {
1166 flow.setHardTimeout(Short.parseShort(this.hardTimeout));
1168 if (this.idleTimeout != null) {
1169 flow.setIdleTimeout(Short.parseShort(idleTimeout));
1171 if (this.priority != null) {
1172 flow.setPriority(Integer.decode(this.priority).shortValue());
1177 public boolean isByNameAndNodeIdEqual(FlowConfig that) {
1178 return (this.name.equals(that.name) && this.node.equals(that.node));
1181 public boolean isByNameAndNodeIdEqual(String name, Node node) {
1182 return (this.name.equals(name) && this.node.equals(node));
1185 public boolean onNode(Node node) {
1186 return this.node.equals(node);
1189 public void toggleStatus() {
1190 installInHw = (installInHw == null) ? "true" : (installInHw
1191 .equals("true")) ? "false" : "true";
1195 * Parses the actions string and return the List of SAL Action No syntax
1196 * check run, as this function will be called when the config validation
1197 * check has already been performed
1199 private List<Action> getActionList() {
1200 List<Action> actionList = new ArrayList<Action>();
1202 if (actions != null) {
1204 for (String actiongrp : actions) {
1205 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(
1207 if (sstr.matches()) {
1208 for (String t : sstr.group(1).split(",")) {
1209 Matcher n = Pattern.compile("(?:(\\d+))").matcher(t);
1211 if (n.group(1) != null) {
1212 short ofPort = Short.parseShort(n.group(1));
1213 actionList.add(new Output(NodeConnectorCreator
1214 .createOFNodeConnector(ofPort,
1222 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(
1224 if (sstr.matches()) {
1225 actionList.add(new Drop());
1229 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(
1231 if (sstr.matches()) {
1232 actionList.add(new Loopback());
1236 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(
1238 if (sstr.matches()) {
1239 actionList.add(new Flood());
1243 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(
1245 if (sstr.matches()) {
1246 actionList.add(new SwPath());
1250 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(
1252 if (sstr.matches()) {
1253 actionList.add(new HwPath());
1257 sstr = Pattern.compile(ActionType.CONTROLLER.toString())
1258 .matcher(actiongrp);
1259 if (sstr.matches()) {
1260 actionList.add(new Controller());
1264 sstr = Pattern.compile(
1265 ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(
1267 if (sstr.matches()) {
1268 actionList.add(new SetVlanId(
1269 Short.parseShort(sstr.group(1))));
1273 sstr = Pattern.compile(
1274 ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(
1276 if (sstr.matches()) {
1278 .add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
1282 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(
1284 if (sstr.matches()) {
1285 actionList.add(new PopVlan());
1289 sstr = Pattern.compile(
1290 ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(
1292 if (sstr.matches()) {
1293 actionList.add(new SetDlSrc(HexEncode
1294 .bytesFromHexString(sstr.group(1))));
1298 sstr = Pattern.compile(
1299 ActionType.SET_DL_DST.toString() + "=(.*)").matcher(
1301 if (sstr.matches()) {
1302 actionList.add(new SetDlDst(HexEncode
1303 .bytesFromHexString(sstr.group(1))));
1306 sstr = Pattern.compile(
1307 ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(
1309 if (sstr.matches()) {
1310 actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr
1314 sstr = Pattern.compile(
1315 ActionType.SET_NW_DST.toString() + "=(.*)").matcher(
1317 if (sstr.matches()) {
1318 actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr
1323 sstr = Pattern.compile(
1324 ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(
1326 if (sstr.matches()) {
1327 actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
1331 sstr = Pattern.compile(
1332 ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(
1334 if (sstr.matches()) {
1336 .add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
1340 sstr = Pattern.compile(
1341 ActionType.SET_TP_DST.toString() + "=(.*)").matcher(
1343 if (sstr.matches()) {
1345 .add(new SetTpDst(Integer.valueOf(sstr.group(1))));
1349 sstr = Pattern.compile(
1350 ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(
1352 if (sstr.matches()) {
1353 actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr