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;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
19 import javax.xml.bind.annotation.XmlAccessType;
20 import javax.xml.bind.annotation.XmlAccessorType;
21 import javax.xml.bind.annotation.XmlElement;
22 import javax.xml.bind.annotation.XmlRootElement;
24 import org.opendaylight.controller.configuration.ConfigurationObject;
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.Enqueue;
30 import org.opendaylight.controller.sal.action.Flood;
31 import org.opendaylight.controller.sal.action.FloodAll;
32 import org.opendaylight.controller.sal.action.HwPath;
33 import org.opendaylight.controller.sal.action.Loopback;
34 import org.opendaylight.controller.sal.action.Output;
35 import org.opendaylight.controller.sal.action.PopVlan;
36 import org.opendaylight.controller.sal.action.SetDlDst;
37 import org.opendaylight.controller.sal.action.SetDlSrc;
38 import org.opendaylight.controller.sal.action.SetNextHop;
39 import org.opendaylight.controller.sal.action.SetNwDst;
40 import org.opendaylight.controller.sal.action.SetNwSrc;
41 import org.opendaylight.controller.sal.action.SetNwTos;
42 import org.opendaylight.controller.sal.action.SetTpDst;
43 import org.opendaylight.controller.sal.action.SetTpSrc;
44 import org.opendaylight.controller.sal.action.SetVlanId;
45 import org.opendaylight.controller.sal.action.SetVlanPcp;
46 import org.opendaylight.controller.sal.action.SwPath;
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.HexEncode;
53 import org.opendaylight.controller.sal.utils.IPProtocols;
54 import org.opendaylight.controller.sal.utils.NetUtils;
55 import org.opendaylight.controller.sal.utils.Status;
56 import org.opendaylight.controller.sal.utils.StatusCode;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
61 * Configuration Java Object which represents a flow configuration information
62 * for Forwarding Rules Manager.
65 @XmlAccessorType(XmlAccessType.NONE)
66 public class FlowConfig extends ConfigurationObject implements Serializable {
67 private static final long serialVersionUID = 1L;
68 private static final Logger log = LoggerFactory.getLogger(FlowConfig.class);
69 public static final String STATICFLOWGROUP = "__StaticFlows__";
70 public static final String INTERNALSTATICFLOWGROUP = "__InternalStaticFlows__";
71 public static final String INTERNALSTATICFLOWBEGIN = "__";
72 public static final String INTERNALSTATICFLOWEND = "__";
73 private boolean dynamic;
74 private String status;
77 * The order of the object data defined below is used directly in the UI
78 * built using JSP. Hence try to keep the order in a more logical way.
81 private String installInHw;
87 private String ingressPort;
88 private String portGroup;
90 private String priority;
92 private String etherType;
94 private String vlanId;
96 private String vlanPriority;
100 private String dlDst;
102 private String nwSrc;
104 private String nwDst;
106 private String protocol;
108 private String tosBits;
110 private String tpSrc;
112 private String tpDst;
114 private String cookie;
116 private String idleTimeout;
118 private String hardTimeout;
120 private List<String> actions;
122 private enum EtherIPType {
126 public FlowConfig() {
129 public FlowConfig(String installInHw, String name, Node node, String priority, String cookie, String ingressPort,
130 String portGroup, String vlanId, String vlanPriority, String etherType, String srcMac, String dstMac,
131 String protocol, String tosBits, String srcIP, String dstIP, String tpSrc, String tpDst,
132 String idleTimeout, String hardTimeout, List<String> actions) {
134 this.installInHw = installInHw;
137 this.priority = priority;
138 this.cookie = cookie;
139 this.ingressPort = ingressPort;
140 this.portGroup = portGroup;
141 this.vlanId = vlanId;
142 this.vlanPriority = vlanPriority;
143 this.etherType = etherType;
146 this.protocol = protocol;
147 this.tosBits = tosBits;
152 this.idleTimeout = idleTimeout;
153 this.hardTimeout = hardTimeout;
154 this.actions = actions;
155 this.status = StatusCode.SUCCESS.toString();
158 public FlowConfig(FlowConfig from) {
159 this.installInHw = from.installInHw;
160 this.name = from.name;
161 this.node = from.node;
162 this.priority = from.priority;
163 this.cookie = from.cookie;
164 this.ingressPort = from.ingressPort;
165 this.portGroup = from.portGroup;
166 this.vlanId = from.vlanId;
167 this.vlanPriority = from.vlanPriority;
168 this.etherType = from.etherType;
169 this.dlSrc = from.dlSrc;
170 this.dlDst = from.dlDst;
171 this.protocol = from.protocol;
172 this.tosBits = from.tosBits;
173 this.nwSrc = from.nwSrc;
174 this.nwDst = from.nwDst;
175 this.tpSrc = from.tpSrc;
176 this.tpDst = from.tpDst;
177 this.idleTimeout = from.idleTimeout;
178 this.hardTimeout = from.hardTimeout;
179 this.actions = new ArrayList<String>(from.actions);
182 public boolean installInHw() {
183 if (installInHw == null) {
184 // backward compatibility
185 installInHw = Boolean.toString(true);
187 return Boolean.valueOf(installInHw);
190 public void setInstallInHw(boolean inHw) {
191 installInHw = String.valueOf(inHw);
194 public String getInstallInHw() {
198 public boolean isInternalFlow() {
199 return (this.name != null &&
200 this.name.startsWith(FlowConfig.INTERNALSTATICFLOWBEGIN) &&
201 this.name.endsWith(FlowConfig.INTERNALSTATICFLOWEND));
204 public String getName() {
208 public void setName(String name) {
215 public Node getNode() {
219 public void setNode(Node node) {
223 public String getPriority() {
227 public void setPriority(String priority) {
228 this.priority = priority;
231 public String getCookie() {
235 public void setCookie(String cookie) {
236 this.cookie = cookie;
239 public String getIngressPort() {
243 public void setIngressPort(String ingressPort) {
244 this.ingressPort = ingressPort;
247 public String getPortGroup() {
252 public String toString() {
253 return "FlowConfig [dynamic=" + dynamic + ", status=" + status + ", installInHw=" + installInHw + ", name="
254 + name + ", switchId=" + node + ", ingressPort=" + ingressPort + ", portGroup=" + portGroup
255 + ", etherType=" + etherType + ", priority=" + priority + ", vlanId=" + vlanId + ", vlanPriority="
256 + vlanPriority + ", dlSrc=" + dlSrc + ", dlDst=" + dlDst + ", nwSrc=" + nwSrc + ", nwDst=" + nwDst
257 + ", protocol=" + protocol + ", tosBits=" + tosBits + ", tpSrc=" + tpSrc + ", tpDst=" + tpDst
258 + ", cookie=" + cookie + ", idleTimeout=" + idleTimeout + ", hardTimeout=" + hardTimeout + ", actions="
262 public void setPortGroup(String portGroup) {
263 this.portGroup = portGroup;
266 public String getVlanId() {
270 public void setVlanId(String vlanId) {
271 this.vlanId = vlanId;
274 public String getVlanPriority() {
278 public void setVlanPriority(String vlanPriority) {
279 this.vlanPriority = vlanPriority;
282 public String getEtherType() {
286 public void setEtherType(String etherType) {
287 this.etherType = etherType;
290 public String getSrcMac() {
294 public void setSrcMac(String srcMac) {
298 public String getDstMac() {
302 public void setDstMac(String dstMac) {
306 public String getProtocol() {
310 public void setProtocol(String protocol) {
311 this.protocol = protocol;
314 public String getTosBits() {
318 public void setTosBits(String tos_bits) {
319 this.tosBits = tos_bits;
322 public String getSrcIp() {
326 public void setSrcIp(String src_ip) {
330 public String getDstIp() {
334 public void setDstIp(String dst_ip) {
338 public String getSrcPort() {
342 public void setSrcPort(String src_port) {
343 this.tpSrc = src_port;
346 public String getDstPort() {
350 public void setDstPort(String dst_port) {
351 this.tpDst = dst_port;
354 public String getIdleTimeout() {
358 public void setIdleTimeout(String idleTimeout) {
359 this.idleTimeout = idleTimeout;
362 public String getHardTimeout() {
366 public void setHardTimeout(String hardTimeout) {
367 this.hardTimeout = hardTimeout;
370 public boolean isIPv6() {
371 return NetUtils.isIPv6AddressValid(this.getSrcIp()) || NetUtils.isIPv6AddressValid(this.getDstIp());
374 public List<String> getActions() {
378 public void setActions(List<String> actions) {
379 this.actions = actions;
382 public boolean isPortGroupEnabled() {
383 return (portGroup != null);
386 public boolean isDynamic() {
390 public void setDynamic(boolean dynamic) {
391 this.dynamic = dynamic;
394 public String getStatus() {
398 public void setStatus(String status) {
399 this.status = status;
402 public boolean isStatusSuccessful() {
403 return status.equals(StatusCode.SUCCESS.toString());
407 public int hashCode() {
408 final int prime = 31;
410 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
411 result = prime * result + ((cookie == null) ? 0 : cookie.hashCode());
412 result = prime * result + ((dlDst == null) ? 0 : dlDst.hashCode());
413 result = prime * result + ((dlSrc == null) ? 0 : dlSrc.hashCode());
414 result = prime * result + (dynamic ? 1231 : 1237);
415 result = prime * result + ((etherType == null) ? 0 : etherType.hashCode());
416 result = prime * result + ((ingressPort == null) ? 0 : ingressPort.hashCode());
417 result = prime * result + ((name == null) ? 0 : name.hashCode());
418 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
419 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
420 result = prime * result + ((portGroup == null) ? 0 : portGroup.hashCode());
421 result = prime * result + ((priority == null) ? 0 : priority.hashCode());
422 result = prime * result + ((protocol == null) ? 0 : protocol.hashCode());
423 result = prime * result + ((node == null) ? 0 : node.hashCode());
424 result = prime * result + ((tosBits == null) ? 0 : tosBits.hashCode());
425 result = prime * result + ((tpDst == null) ? 0 : tpDst.hashCode());
426 result = prime * result + ((tpSrc == null) ? 0 : tpSrc.hashCode());
427 result = prime * result + ((vlanId == null) ? 0 : vlanId.hashCode());
428 result = prime * result + ((vlanPriority == null) ? 0 : vlanPriority.hashCode());
429 result = prime * result + ((idleTimeout == null) ? 0 : idleTimeout.hashCode());
430 result = prime * result + ((hardTimeout == null) ? 0 : hardTimeout.hashCode());
435 public boolean equals(Object obj) {
442 if (getClass() != obj.getClass()) {
445 FlowConfig other = (FlowConfig) obj;
446 if (actions == null) {
447 if (other.actions != null) {
450 } else if (!actions.equals(other.actions)) {
453 if (cookie == null) {
454 if (other.cookie != null) {
457 } else if (!cookie.equals(other.cookie)) {
461 if (other.dlDst != null) {
464 } else if (!dlDst.equals(other.dlDst)) {
468 if (other.dlSrc != null) {
471 } else if (!dlSrc.equals(other.dlSrc)) {
474 if (dynamic != other.dynamic) {
477 if (etherType == null) {
478 if (other.etherType != null) {
481 } else if (!etherType.equals(other.etherType)) {
484 if (ingressPort == null) {
485 if (other.ingressPort != null) {
488 } else if (!ingressPort.equals(other.ingressPort)) {
492 if (other.name != null) {
495 } else if (!name.equals(other.name)) {
499 if (other.nwDst != null) {
502 } else if (!nwDst.equals(other.nwDst)) {
506 if (other.nwSrc != null) {
509 } else if (!nwSrc.equals(other.nwSrc)) {
512 if (portGroup == null) {
513 if (other.portGroup != null) {
516 } else if (!portGroup.equals(other.portGroup)) {
519 if (priority == null) {
520 if (other.priority != null) {
523 } else if (!priority.equals(other.priority)) {
526 if (protocol == null) {
527 if (other.protocol != null) {
530 } else if (!protocol.equals(other.protocol)) {
534 if (other.node != null) {
537 } else if (!node.equals(other.node)) {
540 if (tosBits == null) {
541 if (other.tosBits != null) {
544 } else if (!tosBits.equals(other.tosBits)) {
548 if (other.tpDst != null) {
551 } else if (!tpDst.equals(other.tpDst)) {
555 if (other.tpSrc != null) {
558 } else if (!tpSrc.equals(other.tpSrc)) {
561 if (vlanId == null) {
562 if (other.vlanId != null) {
565 } else if (!vlanId.equals(other.vlanId)) {
568 if (vlanPriority == null) {
569 if (other.vlanPriority != null) {
572 } else if (!vlanPriority.equals(other.vlanPriority)) {
575 if (idleTimeout == null) {
576 if (other.idleTimeout != null) {
579 } else if (!idleTimeout.equals(other.idleTimeout)) {
582 if (hardTimeout == null) {
583 if (other.hardTimeout != null) {
586 } else if (!hardTimeout.equals(other.hardTimeout)) {
592 public boolean isL2AddressValid(String mac) {
597 Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
598 Matcher mm = macPattern.matcher(mac);
600 log.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
606 public boolean isVlanIdValid(String vlanId) {
607 int vlan = Integer.decode(vlanId);
608 return ((vlan >= 0) && (vlan < 4096));
611 public boolean isVlanPriorityValid(String vlanPriority) {
612 int pri = Integer.decode(vlanPriority);
613 return ((pri >= 0) && (pri < 8));
616 public boolean isTOSBitsValid(String tosBits) {
617 int tos = Integer.decode(tosBits);
618 return ((tos >= 0) && (tos < 64));
621 public boolean isTpPortValid(String tpPort) {
622 int port = Integer.decode(tpPort);
623 return ((port >= 0) && (port <= 0xffff));
626 public boolean isTimeoutValid(String timeout) {
627 int to = Integer.decode(timeout);
628 return ((to >= 0) && (to <= 0xffff));
631 public boolean isProtocolValid(String protocol) {
632 IPProtocols proto = IPProtocols.fromString(protocol);
633 return (proto != null);
636 public Status validate() {
637 EtherIPType etype = EtherIPType.ANY;
638 EtherIPType ipsrctype = EtherIPType.ANY;
639 EtherIPType ipdsttype = EtherIPType.ANY;
642 // Flow name cannot be internal flow signature
643 if (!isValidResourceName(name) || isInternalFlow()) {
644 return new Status(StatusCode.BADREQUEST, "Invalid name");
648 return new Status(StatusCode.BADREQUEST, "Node is null");
651 if (priority != null) {
652 if (Integer.decode(priority) < 0 || (Integer.decode(priority) > 65535)) {
653 return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535",
658 // make sure it's a valid number
659 if (cookie != null) {
663 if (ingressPort != null && ingressPort.isEmpty()) {
664 return new Status(StatusCode.BADREQUEST, "Invalid ingress port");
667 if ((vlanId != null) && !isVlanIdValid(vlanId)) {
668 return new Status(StatusCode.BADREQUEST, String.format("Vlan ID %s is not in the range 0 - 4095",
672 if ((vlanPriority != null) && !isVlanPriorityValid(vlanPriority)) {
673 return new Status(StatusCode.BADREQUEST, String.format("Vlan priority %s is not in the range 0 - 7",
676 if (etherType != null) {
677 int type = Integer.decode(etherType);
678 if ((type < 0) || (type > 0xffff)) {
679 return new Status(StatusCode.BADREQUEST, String.format("Ethernet type %s is not valid", etherType));
682 etype = EtherIPType.V4;
683 } else if (type == 0x86dd) {
684 etype = EtherIPType.V6;
689 if ((protocol != null) && !isProtocolValid(protocol)) {
690 return new Status(StatusCode.BADREQUEST, String.format("Protocol %s is not valid", protocol));
693 if ((tosBits != null) && !isTOSBitsValid(tosBits)) {
694 return new Status(StatusCode.BADREQUEST, String.format("IP ToS bits %s is not in the range 0 - 63",
698 if ((tpSrc != null) && !isTpPortValid(tpSrc)) {
699 return new Status(StatusCode.BADREQUEST, String.format("Transport source port %s is not valid", tpSrc));
702 if ((tpDst != null) && !isTpPortValid(tpDst)) {
703 return new Status(StatusCode.BADREQUEST, String.format("Transport destination port %s is not valid",
707 if ((dlSrc != null) && !isL2AddressValid(dlSrc)) {
708 return new Status(StatusCode.BADREQUEST, String.format(
709 "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f", dlSrc));
712 if ((dlDst != null) && !isL2AddressValid(dlDst)) {
713 return new Status(StatusCode.BADREQUEST, String.format(
714 "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f", dlDst));
718 if (NetUtils.isIPv4AddressValid(nwSrc)) {
719 ipsrctype = EtherIPType.V4;
720 } else if (NetUtils.isIPv6AddressValid(nwSrc)) {
721 ipsrctype = EtherIPType.V6;
723 return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid", nwSrc));
728 if (NetUtils.isIPv4AddressValid(nwDst)) {
729 ipdsttype = EtherIPType.V4;
730 } else if (NetUtils.isIPv6AddressValid(nwDst)) {
731 ipdsttype = EtherIPType.V6;
733 return new Status(StatusCode.BADREQUEST, String.format("IP destination address %s is not valid",
738 if (etype != EtherIPType.ANY) {
739 if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
740 return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Src IP"));
742 if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
743 return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Dst IP"));
746 if (ipsrctype != ipdsttype) {
747 if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
748 return new Status(StatusCode.BADREQUEST, String.format("IP Src Dest Type mismatch"));
752 if ((idleTimeout != null) && !isTimeoutValid(idleTimeout)) {
753 return new Status(StatusCode.BADREQUEST, String.format("Idle Timeout value %s is not valid",
757 if ((hardTimeout != null) && !isTimeoutValid(hardTimeout)) {
758 return new Status(StatusCode.BADREQUEST, String.format("Hard Timeout value %s is not valid",
763 if (actions == null || actions.isEmpty()) {
764 return new Status(StatusCode.BADREQUEST, "Actions value is null or empty");
766 for (String actiongrp : actions) {
768 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
769 if (sstr.matches()) {
770 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
771 return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid",
777 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
778 if (sstr.matches()) {
779 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
780 return new Status(StatusCode.BADREQUEST, String.format(
781 "IP destination address %s is not valid", sstr.group(1)));
786 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
787 if (sstr.matches()) {
788 if ((sstr.group(1) != null) && !isVlanIdValid(sstr.group(1))) {
789 return new Status(StatusCode.BADREQUEST, String.format(
790 "Vlan ID %s is not in the range 0 - 4095", sstr.group(1)));
795 sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
796 if (sstr.matches()) {
797 for (String t : sstr.group(1).split(",")) {
799 String parts[] = t.split(":");
800 String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
801 if (NodeConnector.fromString(nc) == null) {
802 return new Status(StatusCode.BADREQUEST, String.format("Enqueue port is not valid"));
804 if (parts.length > 1) {
806 Integer.parseInt(parts[1]);
807 } catch (NumberFormatException e) {
808 return new Status(StatusCode.BADREQUEST, String.format("Enqueue %s is not in the range 0 - 2147483647", parts[1]));
816 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
817 if (sstr.matches()) {
818 if ((sstr.group(1) != null) && !isVlanPriorityValid(sstr.group(1))) {
819 return new Status(StatusCode.BADREQUEST, String.format(
820 "Vlan priority %s is not in the range 0 - 7", sstr.group(1)));
825 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
826 if (sstr.matches()) {
827 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
828 return new Status(StatusCode.BADREQUEST, String.format(
829 "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
834 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
835 if (sstr.matches()) {
836 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
837 return new Status(StatusCode.BADREQUEST, String.format(
838 "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
844 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
845 if (sstr.matches()) {
846 if ((sstr.group(1) != null) && !isTOSBitsValid(sstr.group(1))) {
847 return new Status(StatusCode.BADREQUEST, String.format(
848 "IP ToS bits %s is not in the range 0 - 63", sstr.group(1)));
853 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
854 if (sstr.matches()) {
855 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
856 return new Status(StatusCode.BADREQUEST, String.format(
857 "Transport source port %s is not valid", sstr.group(1)));
862 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
863 if (sstr.matches()) {
864 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
865 return new Status(StatusCode.BADREQUEST, String.format(
866 "Transport destination port %s is not valid", sstr.group(1)));
871 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
872 if (sstr.matches()) {
873 if (!NetUtils.isIPAddressValid(sstr.group(1))) {
874 return new Status(StatusCode.BADREQUEST, String.format(
875 "IP destination address %s is not valid", sstr.group(1)));
880 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
881 if (sstr.matches()) {
885 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
886 if (sstr.matches()) {
890 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
891 if (sstr.matches()) {
895 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
896 if (sstr.matches()) {
900 sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
901 if (sstr.matches()) {
905 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
906 if (sstr.matches()) {
910 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
911 if (sstr.matches()) {
915 sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
916 if (sstr.matches()) {
920 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
921 if (sstr.matches()) {
925 // If execution reached here, it means there is an Action
926 // which is not recognized by the controller. Return error
928 return new Status(StatusCode.BADREQUEST, String.format("%s is an UnSupported Action", actiongrp));
930 } catch (NumberFormatException e) {
931 return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
934 return new Status(StatusCode.SUCCESS);
937 public FlowEntry getFlowEntry() {
938 String group = this.isInternalFlow() ? FlowConfig.INTERNALSTATICFLOWGROUP : FlowConfig.STATICFLOWGROUP;
939 return new FlowEntry(group, this.name, this.getFlow(), this.getNode());
942 public Flow getFlow() {
943 Match match = new Match();
945 if (this.ingressPort != null) {
946 match.setField(MatchType.IN_PORT,
947 NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString())));
949 if (this.dlSrc != null) {
950 match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
952 if (this.dlDst != null) {
953 match.setField(MatchType.DL_DST, HexEncode.bytesFromHexString(this.dlDst));
955 if (this.etherType != null) {
956 match.setField(MatchType.DL_TYPE, Integer.decode(etherType).shortValue());
958 if (this.vlanId != null) {
959 match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
961 if (this.vlanPriority != null) {
962 match.setField(MatchType.DL_VLAN_PR, Byte.parseByte(this.vlanPriority));
964 if (this.nwSrc != null) {
965 String parts[] = this.nwSrc.split("/");
966 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
967 InetAddress mask = null;
969 if (parts.length > 1) {
970 maskLen = Integer.parseInt(parts[1]);
972 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
974 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
975 match.setField(MatchType.NW_SRC, ip, mask);
977 if (this.nwDst != null) {
978 String parts[] = this.nwDst.split("/");
979 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
980 InetAddress mask = null;
982 if (parts.length > 1) {
983 maskLen = Integer.parseInt(parts[1]);
985 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
987 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
988 match.setField(MatchType.NW_DST, ip, mask);
990 if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
991 match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
993 if (this.tosBits != null) {
994 match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
996 if (this.tpSrc != null) {
997 match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc).shortValue());
999 if (this.tpDst != null) {
1000 match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst).shortValue());
1003 Flow flow = new Flow(match, getActionList());
1005 if (this.cookie != null) {
1006 flow.setId(Long.parseLong(cookie));
1008 if (this.hardTimeout != null) {
1009 flow.setHardTimeout(Short.parseShort(this.hardTimeout));
1011 if (this.idleTimeout != null) {
1012 flow.setIdleTimeout(Short.parseShort(idleTimeout));
1014 if (this.priority != null) {
1015 flow.setPriority(Integer.decode(this.priority).shortValue());
1022 public boolean isByNameAndNodeIdEqual(FlowConfig that) {
1023 return (this.name.equals(that.name) && this.node.equals(that.node));
1026 public boolean isByNameAndNodeIdEqual(String name, Node node) {
1027 return (this.name.equals(name) && this.node.equals(node));
1030 public boolean onNode(Node node) {
1031 return this.node.equals(node);
1034 public void toggleInstallation() {
1035 installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw));
1039 * Parses the actions string and return the List of SAL Action No syntax
1040 * check run, as this function will be called when the config validation
1041 * check has already been performed
1043 private List<Action> getActionList() {
1044 List<Action> actionList = new ArrayList<Action>();
1046 if (actions != null) {
1048 for (String actiongrp : actions) {
1049 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
1050 if (sstr.matches()) {
1051 for (String t : sstr.group(1).split(",")) {
1053 String nc = String.format("%s|%s@%s", node.getType(), t, node.toString());
1054 actionList.add(new Output(NodeConnector.fromString(nc)));
1060 sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
1061 if (sstr.matches()) {
1062 for (String t : sstr.group(1).split(",")) {
1064 String parts[] = t.split(":");
1065 String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
1066 if (parts.length == 1) {
1067 actionList.add(new Enqueue(NodeConnector.fromString(nc)));
1070 .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1])));
1077 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
1078 if (sstr.matches()) {
1079 actionList.add(new Drop());
1083 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
1084 if (sstr.matches()) {
1085 actionList.add(new Loopback());
1089 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
1090 if (sstr.matches()) {
1091 actionList.add(new Flood());
1095 sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
1096 if (sstr.matches()) {
1097 actionList.add(new FloodAll());
1101 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
1102 if (sstr.matches()) {
1103 actionList.add(new SwPath());
1107 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
1108 if (sstr.matches()) {
1109 actionList.add(new HwPath());
1113 sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
1114 if (sstr.matches()) {
1115 actionList.add(new Controller());
1119 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
1120 if (sstr.matches()) {
1121 actionList.add(new SetVlanId(Short.parseShort(sstr.group(1))));
1125 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
1126 if (sstr.matches()) {
1127 actionList.add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
1131 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
1132 if (sstr.matches()) {
1133 actionList.add(new PopVlan());
1137 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
1138 if (sstr.matches()) {
1139 actionList.add(new SetDlSrc(HexEncode.bytesFromHexString(sstr.group(1))));
1143 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
1144 if (sstr.matches()) {
1145 actionList.add(new SetDlDst(HexEncode.bytesFromHexString(sstr.group(1))));
1148 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
1149 if (sstr.matches()) {
1150 actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr.group(1))));
1153 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
1154 if (sstr.matches()) {
1155 actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr.group(1))));
1159 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
1160 if (sstr.matches()) {
1161 actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
1165 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
1166 if (sstr.matches()) {
1167 actionList.add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
1171 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
1172 if (sstr.matches()) {
1173 actionList.add(new SetTpDst(Integer.valueOf(sstr.group(1))));
1177 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
1178 if (sstr.matches()) {
1179 actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr.group(1))));