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)));
870 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
871 if (sstr.matches()) {
872 if (!NetUtils.isIPAddressValid(sstr.group(1))) {
873 return new Status(StatusCode.BADREQUEST, String.format(
874 "IP destination address %s is not valid", sstr.group(1)));
879 } catch (NumberFormatException e) {
880 return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
883 return new Status(StatusCode.SUCCESS);
886 public FlowEntry getFlowEntry() {
887 String group = this.isInternalFlow() ? FlowConfig.INTERNALSTATICFLOWGROUP : FlowConfig.STATICFLOWGROUP;
888 return new FlowEntry(group, this.name, this.getFlow(), this.getNode());
891 public Flow getFlow() {
892 Match match = new Match();
894 if (this.ingressPort != null) {
895 match.setField(MatchType.IN_PORT,
896 NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString())));
898 if (this.dlSrc != null) {
899 match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
901 if (this.dlDst != null) {
902 match.setField(MatchType.DL_DST, HexEncode.bytesFromHexString(this.dlDst));
904 if (this.etherType != null) {
905 match.setField(MatchType.DL_TYPE, Integer.decode(etherType).shortValue());
907 if (this.vlanId != null) {
908 match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
910 if (this.vlanPriority != null) {
911 match.setField(MatchType.DL_VLAN_PR, Byte.parseByte(this.vlanPriority));
913 if (this.nwSrc != null) {
914 String parts[] = this.nwSrc.split("/");
915 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
916 InetAddress mask = null;
918 if (parts.length > 1) {
919 maskLen = Integer.parseInt(parts[1]);
921 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
923 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
924 match.setField(MatchType.NW_SRC, ip, mask);
926 if (this.nwDst != null) {
927 String parts[] = this.nwDst.split("/");
928 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
929 InetAddress mask = null;
931 if (parts.length > 1) {
932 maskLen = Integer.parseInt(parts[1]);
934 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
936 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
937 match.setField(MatchType.NW_DST, ip, mask);
939 if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
940 match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
942 if (this.tosBits != null) {
943 match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
945 if (this.tpSrc != null) {
946 match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc).shortValue());
948 if (this.tpDst != null) {
949 match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst).shortValue());
952 Flow flow = new Flow(match, getActionList());
954 if (this.cookie != null) {
955 flow.setId(Long.parseLong(cookie));
957 if (this.hardTimeout != null) {
958 flow.setHardTimeout(Short.parseShort(this.hardTimeout));
960 if (this.idleTimeout != null) {
961 flow.setIdleTimeout(Short.parseShort(idleTimeout));
963 if (this.priority != null) {
964 flow.setPriority(Integer.decode(this.priority).shortValue());
971 public boolean isByNameAndNodeIdEqual(FlowConfig that) {
972 return (this.name.equals(that.name) && this.node.equals(that.node));
975 public boolean isByNameAndNodeIdEqual(String name, Node node) {
976 return (this.name.equals(name) && this.node.equals(node));
979 public boolean onNode(Node node) {
980 return this.node.equals(node);
983 public void toggleInstallation() {
984 installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw));
988 * Parses the actions string and return the List of SAL Action No syntax
989 * check run, as this function will be called when the config validation
990 * check has already been performed
992 private List<Action> getActionList() {
993 List<Action> actionList = new ArrayList<Action>();
995 if (actions != null) {
997 for (String actiongrp : actions) {
998 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
999 if (sstr.matches()) {
1000 for (String t : sstr.group(1).split(",")) {
1002 String nc = String.format("%s|%s@%s", node.getType(), t, node.toString());
1003 actionList.add(new Output(NodeConnector.fromString(nc)));
1009 sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
1010 if (sstr.matches()) {
1011 for (String t : sstr.group(1).split(",")) {
1013 String parts[] = t.split(":");
1014 String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
1015 if (parts.length == 1) {
1016 actionList.add(new Enqueue(NodeConnector.fromString(nc)));
1019 .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1])));
1026 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
1027 if (sstr.matches()) {
1028 actionList.add(new Drop());
1032 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
1033 if (sstr.matches()) {
1034 actionList.add(new Loopback());
1038 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
1039 if (sstr.matches()) {
1040 actionList.add(new Flood());
1044 sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
1045 if (sstr.matches()) {
1046 actionList.add(new FloodAll());
1050 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
1051 if (sstr.matches()) {
1052 actionList.add(new SwPath());
1056 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
1057 if (sstr.matches()) {
1058 actionList.add(new HwPath());
1062 sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
1063 if (sstr.matches()) {
1064 actionList.add(new Controller());
1068 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
1069 if (sstr.matches()) {
1070 actionList.add(new SetVlanId(Short.parseShort(sstr.group(1))));
1074 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
1075 if (sstr.matches()) {
1076 actionList.add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
1080 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
1081 if (sstr.matches()) {
1082 actionList.add(new PopVlan());
1086 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
1087 if (sstr.matches()) {
1088 actionList.add(new SetDlSrc(HexEncode.bytesFromHexString(sstr.group(1))));
1092 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
1093 if (sstr.matches()) {
1094 actionList.add(new SetDlDst(HexEncode.bytesFromHexString(sstr.group(1))));
1097 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
1098 if (sstr.matches()) {
1099 actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr.group(1))));
1102 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
1103 if (sstr.matches()) {
1104 actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr.group(1))));
1108 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
1109 if (sstr.matches()) {
1110 actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
1114 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
1115 if (sstr.matches()) {
1116 actionList.add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
1120 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
1121 if (sstr.matches()) {
1122 actionList.add(new SetTpDst(Integer.valueOf(sstr.group(1))));
1126 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
1127 if (sstr.matches()) {
1128 actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr.group(1))));