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.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
796 if (sstr.matches()) {
797 if ((sstr.group(1) != null) && !isVlanPriorityValid(sstr.group(1))) {
798 return new Status(StatusCode.BADREQUEST, String.format(
799 "Vlan priority %s is not in the range 0 - 7", sstr.group(1)));
804 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
805 if (sstr.matches()) {
806 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
807 return new Status(StatusCode.BADREQUEST, String.format(
808 "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
813 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
814 if (sstr.matches()) {
815 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
816 return new Status(StatusCode.BADREQUEST, String.format(
817 "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
823 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
824 if (sstr.matches()) {
825 if ((sstr.group(1) != null) && !isTOSBitsValid(sstr.group(1))) {
826 return new Status(StatusCode.BADREQUEST, String.format(
827 "IP ToS bits %s is not in the range 0 - 63", sstr.group(1)));
832 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
833 if (sstr.matches()) {
834 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
835 return new Status(StatusCode.BADREQUEST, String.format(
836 "Transport source port %s is not valid", sstr.group(1)));
841 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
842 if (sstr.matches()) {
843 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
844 return new Status(StatusCode.BADREQUEST, String.format(
845 "Transport destination port %s is not valid", sstr.group(1)));
849 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
850 if (sstr.matches()) {
851 if (!NetUtils.isIPAddressValid(sstr.group(1))) {
852 return new Status(StatusCode.BADREQUEST, String.format(
853 "IP destination address %s is not valid", sstr.group(1)));
858 } catch (NumberFormatException e) {
859 return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
862 return new Status(StatusCode.SUCCESS);
865 public FlowEntry getFlowEntry() {
866 String group = this.isInternalFlow() ? FlowConfig.INTERNALSTATICFLOWGROUP : FlowConfig.STATICFLOWGROUP;
867 return new FlowEntry(group, this.name, this.getFlow(), this.getNode());
870 public Flow getFlow() {
871 Match match = new Match();
873 if (this.ingressPort != null) {
874 match.setField(MatchType.IN_PORT,
875 NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString())));
877 if (this.dlSrc != null) {
878 match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
880 if (this.dlDst != null) {
881 match.setField(MatchType.DL_DST, HexEncode.bytesFromHexString(this.dlDst));
883 if (this.etherType != null) {
884 match.setField(MatchType.DL_TYPE, Integer.decode(etherType).shortValue());
886 if (this.vlanId != null) {
887 match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
889 if (this.vlanPriority != null) {
890 match.setField(MatchType.DL_VLAN_PR, Byte.parseByte(this.vlanPriority));
892 if (this.nwSrc != null) {
893 String parts[] = this.nwSrc.split("/");
894 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
895 InetAddress mask = null;
897 if (parts.length > 1) {
898 maskLen = Integer.parseInt(parts[1]);
900 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
902 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
903 match.setField(MatchType.NW_SRC, ip, mask);
905 if (this.nwDst != null) {
906 String parts[] = this.nwDst.split("/");
907 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
908 InetAddress mask = null;
910 if (parts.length > 1) {
911 maskLen = Integer.parseInt(parts[1]);
913 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
915 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
916 match.setField(MatchType.NW_DST, ip, mask);
918 if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
919 match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
921 if (this.tosBits != null) {
922 match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
924 if (this.tpSrc != null) {
925 match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc).shortValue());
927 if (this.tpDst != null) {
928 match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst).shortValue());
931 Flow flow = new Flow(match, getActionList());
933 if (this.cookie != null) {
934 flow.setId(Long.parseLong(cookie));
936 if (this.hardTimeout != null) {
937 flow.setHardTimeout(Short.parseShort(this.hardTimeout));
939 if (this.idleTimeout != null) {
940 flow.setIdleTimeout(Short.parseShort(idleTimeout));
942 if (this.priority != null) {
943 flow.setPriority(Integer.decode(this.priority).shortValue());
950 public boolean isByNameAndNodeIdEqual(FlowConfig that) {
951 return (this.name.equals(that.name) && this.node.equals(that.node));
954 public boolean isByNameAndNodeIdEqual(String name, Node node) {
955 return (this.name.equals(name) && this.node.equals(node));
958 public boolean onNode(Node node) {
959 return this.node.equals(node);
962 public void toggleInstallation() {
963 installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw));
967 * Parses the actions string and return the List of SAL Action No syntax
968 * check run, as this function will be called when the config validation
969 * check has already been performed
971 private List<Action> getActionList() {
972 List<Action> actionList = new ArrayList<Action>();
974 if (actions != null) {
976 for (String actiongrp : actions) {
977 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
978 if (sstr.matches()) {
979 for (String t : sstr.group(1).split(",")) {
981 String nc = String.format("%s|%s@%s", node.getType(), t, node.toString());
982 actionList.add(new Output(NodeConnector.fromString(nc)));
988 sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
989 if (sstr.matches()) {
990 for (String t : sstr.group(1).split(",")) {
992 String parts[] = t.split(":");
993 String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
994 if (parts.length == 1) {
995 actionList.add(new Enqueue(NodeConnector.fromString(nc)));
998 .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1])));
1005 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
1006 if (sstr.matches()) {
1007 actionList.add(new Drop());
1011 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
1012 if (sstr.matches()) {
1013 actionList.add(new Loopback());
1017 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
1018 if (sstr.matches()) {
1019 actionList.add(new Flood());
1023 sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
1024 if (sstr.matches()) {
1025 actionList.add(new FloodAll());
1029 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
1030 if (sstr.matches()) {
1031 actionList.add(new SwPath());
1035 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
1036 if (sstr.matches()) {
1037 actionList.add(new HwPath());
1041 sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
1042 if (sstr.matches()) {
1043 actionList.add(new Controller());
1047 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
1048 if (sstr.matches()) {
1049 actionList.add(new SetVlanId(Short.parseShort(sstr.group(1))));
1053 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
1054 if (sstr.matches()) {
1055 actionList.add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
1059 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
1060 if (sstr.matches()) {
1061 actionList.add(new PopVlan());
1065 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
1066 if (sstr.matches()) {
1067 actionList.add(new SetDlSrc(HexEncode.bytesFromHexString(sstr.group(1))));
1071 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
1072 if (sstr.matches()) {
1073 actionList.add(new SetDlDst(HexEncode.bytesFromHexString(sstr.group(1))));
1076 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
1077 if (sstr.matches()) {
1078 actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr.group(1))));
1081 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
1082 if (sstr.matches()) {
1083 actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr.group(1))));
1087 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
1088 if (sstr.matches()) {
1089 actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
1093 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
1094 if (sstr.matches()) {
1095 actionList.add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
1099 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
1100 if (sstr.matches()) {
1101 actionList.add(new SetTpDst(Integer.valueOf(sstr.group(1))));
1105 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
1106 if (sstr.matches()) {
1107 actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr.group(1))));