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.HwPath;
32 import org.opendaylight.controller.sal.action.Loopback;
33 import org.opendaylight.controller.sal.action.Output;
34 import org.opendaylight.controller.sal.action.PopVlan;
35 import org.opendaylight.controller.sal.action.SetDlDst;
36 import org.opendaylight.controller.sal.action.SetDlSrc;
37 import org.opendaylight.controller.sal.action.SetNextHop;
38 import org.opendaylight.controller.sal.action.SetNwDst;
39 import org.opendaylight.controller.sal.action.SetNwSrc;
40 import org.opendaylight.controller.sal.action.SetNwTos;
41 import org.opendaylight.controller.sal.action.SetTpDst;
42 import org.opendaylight.controller.sal.action.SetTpSrc;
43 import org.opendaylight.controller.sal.action.SetVlanId;
44 import org.opendaylight.controller.sal.action.SetVlanPcp;
45 import org.opendaylight.controller.sal.action.SwPath;
46 import org.opendaylight.controller.sal.core.Node;
47 import org.opendaylight.controller.sal.core.NodeConnector;
48 import org.opendaylight.controller.sal.flowprogrammer.Flow;
49 import org.opendaylight.controller.sal.match.Match;
50 import org.opendaylight.controller.sal.match.MatchType;
51 import org.opendaylight.controller.sal.utils.HexEncode;
52 import org.opendaylight.controller.sal.utils.IPProtocols;
53 import org.opendaylight.controller.sal.utils.NetUtils;
54 import org.opendaylight.controller.sal.utils.Status;
55 import org.opendaylight.controller.sal.utils.StatusCode;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
60 * Configuration Java Object which represents a flow configuration information
61 * for Forwarding Rules Manager.
64 @XmlAccessorType(XmlAccessType.NONE)
65 public class FlowConfig extends ConfigurationObject implements Serializable {
66 private static final long serialVersionUID = 1L;
67 private static final Logger log = LoggerFactory.getLogger(FlowConfig.class);
68 public static final String STATICFLOWGROUP = "__StaticFlows__";
69 public static final String INTERNALSTATICFLOWGROUP = "__InternalStaticFlows__";
70 public static final String INTERNALSTATICFLOWBEGIN = "__";
71 public static final String INTERNALSTATICFLOWEND = "__";
72 private boolean dynamic;
73 private String status;
76 * The order of the object data defined below is used directly in the UI
77 * built using JSP. Hence try to keep the order in a more logical way.
80 private String installInHw;
86 private String ingressPort;
87 private String portGroup;
89 private String priority;
91 private String etherType;
93 private String vlanId;
95 private String vlanPriority;
101 private String nwSrc;
103 private String nwDst;
105 private String protocol;
107 private String tosBits;
109 private String tpSrc;
111 private String tpDst;
113 private String cookie;
115 private String idleTimeout;
117 private String hardTimeout;
119 private List<String> actions;
121 private enum EtherIPType {
125 public FlowConfig() {
128 public FlowConfig(String installInHw, String name, Node node, String priority, String cookie, String ingressPort,
129 String portGroup, String vlanId, String vlanPriority, String etherType, String srcMac, String dstMac,
130 String protocol, String tosBits, String srcIP, String dstIP, String tpSrc, String tpDst,
131 String idleTimeout, String hardTimeout, List<String> actions) {
133 this.installInHw = installInHw;
136 this.priority = priority;
137 this.cookie = cookie;
138 this.ingressPort = ingressPort;
139 this.portGroup = portGroup;
140 this.vlanId = vlanId;
141 this.vlanPriority = vlanPriority;
142 this.etherType = etherType;
145 this.protocol = protocol;
146 this.tosBits = tosBits;
151 this.idleTimeout = idleTimeout;
152 this.hardTimeout = hardTimeout;
153 this.actions = actions;
154 this.status = StatusCode.SUCCESS.toString();
157 public FlowConfig(FlowConfig from) {
158 this.installInHw = from.installInHw;
159 this.name = from.name;
160 this.node = from.node;
161 this.priority = from.priority;
162 this.cookie = from.cookie;
163 this.ingressPort = from.ingressPort;
164 this.portGroup = from.portGroup;
165 this.vlanId = from.vlanId;
166 this.vlanPriority = from.vlanPriority;
167 this.etherType = from.etherType;
168 this.dlSrc = from.dlSrc;
169 this.dlDst = from.dlDst;
170 this.protocol = from.protocol;
171 this.tosBits = from.tosBits;
172 this.nwSrc = from.nwSrc;
173 this.nwDst = from.nwDst;
174 this.tpSrc = from.tpSrc;
175 this.tpDst = from.tpDst;
176 this.idleTimeout = from.idleTimeout;
177 this.hardTimeout = from.hardTimeout;
178 this.actions = new ArrayList<String>(from.actions);
181 public boolean installInHw() {
182 if (installInHw == null) {
183 // backward compatibility
184 installInHw = Boolean.toString(true);
186 return Boolean.valueOf(installInHw);
189 public void setInstallInHw(boolean inHw) {
190 installInHw = String.valueOf(inHw);
193 public String getInstallInHw() {
197 public boolean isInternalFlow() {
198 return (this.name != null &&
199 this.name.startsWith(FlowConfig.INTERNALSTATICFLOWBEGIN) &&
200 this.name.endsWith(FlowConfig.INTERNALSTATICFLOWEND));
203 public String getName() {
207 public void setName(String name) {
214 public Node getNode() {
218 public void setNode(Node node) {
222 public String getPriority() {
226 public void setPriority(String priority) {
227 this.priority = priority;
230 public String getCookie() {
234 public void setCookie(String cookie) {
235 this.cookie = cookie;
238 public String getIngressPort() {
242 public void setIngressPort(String ingressPort) {
243 this.ingressPort = ingressPort;
246 public String getPortGroup() {
251 public String toString() {
252 return "FlowConfig [dynamic=" + dynamic + ", status=" + status + ", installInHw=" + installInHw + ", name="
253 + name + ", switchId=" + node + ", ingressPort=" + ingressPort + ", portGroup=" + portGroup
254 + ", etherType=" + etherType + ", priority=" + priority + ", vlanId=" + vlanId + ", vlanPriority="
255 + vlanPriority + ", dlSrc=" + dlSrc + ", dlDst=" + dlDst + ", nwSrc=" + nwSrc + ", nwDst=" + nwDst
256 + ", protocol=" + protocol + ", tosBits=" + tosBits + ", tpSrc=" + tpSrc + ", tpDst=" + tpDst
257 + ", cookie=" + cookie + ", idleTimeout=" + idleTimeout + ", hardTimeout=" + hardTimeout + ", actions="
261 public void setPortGroup(String portGroup) {
262 this.portGroup = portGroup;
265 public String getVlanId() {
269 public void setVlanId(String vlanId) {
270 this.vlanId = vlanId;
273 public String getVlanPriority() {
277 public void setVlanPriority(String vlanPriority) {
278 this.vlanPriority = vlanPriority;
281 public String getEtherType() {
285 public void setEtherType(String etherType) {
286 this.etherType = etherType;
289 public String getSrcMac() {
293 public void setSrcMac(String srcMac) {
297 public String getDstMac() {
301 public void setDstMac(String dstMac) {
305 public String getProtocol() {
309 public void setProtocol(String protocol) {
310 this.protocol = protocol;
313 public String getTosBits() {
317 public void setTosBits(String tos_bits) {
318 this.tosBits = tos_bits;
321 public String getSrcIp() {
325 public void setSrcIp(String src_ip) {
329 public String getDstIp() {
333 public void setDstIp(String dst_ip) {
337 public String getSrcPort() {
341 public void setSrcPort(String src_port) {
342 this.tpSrc = src_port;
345 public String getDstPort() {
349 public void setDstPort(String dst_port) {
350 this.tpDst = dst_port;
353 public String getIdleTimeout() {
357 public void setIdleTimeout(String idleTimeout) {
358 this.idleTimeout = idleTimeout;
361 public String getHardTimeout() {
365 public void setHardTimeout(String hardTimeout) {
366 this.hardTimeout = hardTimeout;
369 public boolean isIPv6() {
370 return NetUtils.isIPv6AddressValid(this.getSrcIp()) || NetUtils.isIPv6AddressValid(this.getDstIp());
373 public List<String> getActions() {
377 public void setActions(List<String> actions) {
378 this.actions = actions;
381 public boolean isPortGroupEnabled() {
382 return (portGroup != null);
385 public boolean isDynamic() {
389 public void setDynamic(boolean dynamic) {
390 this.dynamic = dynamic;
393 public String getStatus() {
397 public void setStatus(String status) {
398 this.status = status;
401 public boolean isStatusSuccessful() {
402 return status.equals(StatusCode.SUCCESS.toString());
406 public int hashCode() {
407 final int prime = 31;
409 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
410 result = prime * result + ((cookie == null) ? 0 : cookie.hashCode());
411 result = prime * result + ((dlDst == null) ? 0 : dlDst.hashCode());
412 result = prime * result + ((dlSrc == null) ? 0 : dlSrc.hashCode());
413 result = prime * result + (dynamic ? 1231 : 1237);
414 result = prime * result + ((etherType == null) ? 0 : etherType.hashCode());
415 result = prime * result + ((ingressPort == null) ? 0 : ingressPort.hashCode());
416 result = prime * result + ((name == null) ? 0 : name.hashCode());
417 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
418 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
419 result = prime * result + ((portGroup == null) ? 0 : portGroup.hashCode());
420 result = prime * result + ((priority == null) ? 0 : priority.hashCode());
421 result = prime * result + ((protocol == null) ? 0 : protocol.hashCode());
422 result = prime * result + ((node == null) ? 0 : node.hashCode());
423 result = prime * result + ((tosBits == null) ? 0 : tosBits.hashCode());
424 result = prime * result + ((tpDst == null) ? 0 : tpDst.hashCode());
425 result = prime * result + ((tpSrc == null) ? 0 : tpSrc.hashCode());
426 result = prime * result + ((vlanId == null) ? 0 : vlanId.hashCode());
427 result = prime * result + ((vlanPriority == null) ? 0 : vlanPriority.hashCode());
428 result = prime * result + ((idleTimeout == null) ? 0 : idleTimeout.hashCode());
429 result = prime * result + ((hardTimeout == null) ? 0 : hardTimeout.hashCode());
434 public boolean equals(Object obj) {
441 if (getClass() != obj.getClass()) {
444 FlowConfig other = (FlowConfig) obj;
445 if (actions == null) {
446 if (other.actions != null) {
449 } else if (!actions.equals(other.actions)) {
452 if (cookie == null) {
453 if (other.cookie != null) {
456 } else if (!cookie.equals(other.cookie)) {
460 if (other.dlDst != null) {
463 } else if (!dlDst.equals(other.dlDst)) {
467 if (other.dlSrc != null) {
470 } else if (!dlSrc.equals(other.dlSrc)) {
473 if (dynamic != other.dynamic) {
476 if (etherType == null) {
477 if (other.etherType != null) {
480 } else if (!etherType.equals(other.etherType)) {
483 if (ingressPort == null) {
484 if (other.ingressPort != null) {
487 } else if (!ingressPort.equals(other.ingressPort)) {
491 if (other.name != null) {
494 } else if (!name.equals(other.name)) {
498 if (other.nwDst != null) {
501 } else if (!nwDst.equals(other.nwDst)) {
505 if (other.nwSrc != null) {
508 } else if (!nwSrc.equals(other.nwSrc)) {
511 if (portGroup == null) {
512 if (other.portGroup != null) {
515 } else if (!portGroup.equals(other.portGroup)) {
518 if (priority == null) {
519 if (other.priority != null) {
522 } else if (!priority.equals(other.priority)) {
525 if (protocol == null) {
526 if (other.protocol != null) {
529 } else if (!protocol.equals(other.protocol)) {
533 if (other.node != null) {
536 } else if (!node.equals(other.node)) {
539 if (tosBits == null) {
540 if (other.tosBits != null) {
543 } else if (!tosBits.equals(other.tosBits)) {
547 if (other.tpDst != null) {
550 } else if (!tpDst.equals(other.tpDst)) {
554 if (other.tpSrc != null) {
557 } else if (!tpSrc.equals(other.tpSrc)) {
560 if (vlanId == null) {
561 if (other.vlanId != null) {
564 } else if (!vlanId.equals(other.vlanId)) {
567 if (vlanPriority == null) {
568 if (other.vlanPriority != null) {
571 } else if (!vlanPriority.equals(other.vlanPriority)) {
574 if (idleTimeout == null) {
575 if (other.idleTimeout != null) {
578 } else if (!idleTimeout.equals(other.idleTimeout)) {
581 if (hardTimeout == null) {
582 if (other.hardTimeout != null) {
585 } else if (!hardTimeout.equals(other.hardTimeout)) {
591 public boolean isL2AddressValid(String mac) {
596 Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
597 Matcher mm = macPattern.matcher(mac);
599 log.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
605 public boolean isVlanIdValid(String vlanId) {
606 int vlan = Integer.decode(vlanId);
607 return ((vlan >= 0) && (vlan < 4096));
610 public boolean isVlanPriorityValid(String vlanPriority) {
611 int pri = Integer.decode(vlanPriority);
612 return ((pri >= 0) && (pri < 8));
615 public boolean isTOSBitsValid(String tosBits) {
616 int tos = Integer.decode(tosBits);
617 return ((tos >= 0) && (tos < 64));
620 public boolean isTpPortValid(String tpPort) {
621 int port = Integer.decode(tpPort);
622 return ((port >= 0) && (port <= 0xffff));
625 public boolean isTimeoutValid(String timeout) {
626 int to = Integer.decode(timeout);
627 return ((to >= 0) && (to <= 0xffff));
630 public boolean isProtocolValid(String protocol) {
631 IPProtocols proto = IPProtocols.fromString(protocol);
632 return (proto != null);
635 public Status validate() {
636 EtherIPType etype = EtherIPType.ANY;
637 EtherIPType ipsrctype = EtherIPType.ANY;
638 EtherIPType ipdsttype = EtherIPType.ANY;
641 // Flow name cannot be internal flow signature
642 if (!isValidResourceName(name) || isInternalFlow()) {
643 return new Status(StatusCode.BADREQUEST, "Invalid name");
647 return new Status(StatusCode.BADREQUEST, "Node is null");
650 if (priority != null) {
651 if (Integer.decode(priority) < 0 || (Integer.decode(priority) > 65535)) {
652 return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535",
657 // make sure it's a valid number
658 if (cookie != null) {
662 if (ingressPort != null && ingressPort.isEmpty()) {
663 return new Status(StatusCode.BADREQUEST, "Invalid ingress port");
666 if ((vlanId != null) && !isVlanIdValid(vlanId)) {
667 return new Status(StatusCode.BADREQUEST, String.format("Vlan ID %s is not in the range 0 - 4095",
671 if ((vlanPriority != null) && !isVlanPriorityValid(vlanPriority)) {
672 return new Status(StatusCode.BADREQUEST, String.format("Vlan priority %s is not in the range 0 - 7",
675 if (etherType != null) {
676 int type = Integer.decode(etherType);
677 if ((type < 0) || (type > 0xffff)) {
678 return new Status(StatusCode.BADREQUEST, String.format("Ethernet type %s is not valid", etherType));
681 etype = EtherIPType.V4;
682 } else if (type == 0x86dd) {
683 etype = EtherIPType.V6;
688 if ((protocol != null) && !isProtocolValid(protocol)) {
689 return new Status(StatusCode.BADREQUEST, String.format("Protocol %s is not valid", protocol));
692 if ((tosBits != null) && !isTOSBitsValid(tosBits)) {
693 return new Status(StatusCode.BADREQUEST, String.format("IP ToS bits %s is not in the range 0 - 63",
697 if ((tpSrc != null) && !isTpPortValid(tpSrc)) {
698 return new Status(StatusCode.BADREQUEST, String.format("Transport source port %s is not valid", tpSrc));
701 if ((tpDst != null) && !isTpPortValid(tpDst)) {
702 return new Status(StatusCode.BADREQUEST, String.format("Transport destination port %s is not valid",
706 if ((dlSrc != null) && !isL2AddressValid(dlSrc)) {
707 return new Status(StatusCode.BADREQUEST, String.format(
708 "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f", dlSrc));
711 if ((dlDst != null) && !isL2AddressValid(dlDst)) {
712 return new Status(StatusCode.BADREQUEST, String.format(
713 "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f", dlDst));
717 if (NetUtils.isIPv4AddressValid(nwSrc)) {
718 ipsrctype = EtherIPType.V4;
719 } else if (NetUtils.isIPv6AddressValid(nwSrc)) {
720 ipsrctype = EtherIPType.V6;
722 return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid", nwSrc));
727 if (NetUtils.isIPv4AddressValid(nwDst)) {
728 ipdsttype = EtherIPType.V4;
729 } else if (NetUtils.isIPv6AddressValid(nwDst)) {
730 ipdsttype = EtherIPType.V6;
732 return new Status(StatusCode.BADREQUEST, String.format("IP destination address %s is not valid",
737 if (etype != EtherIPType.ANY) {
738 if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
739 return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Src IP"));
741 if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
742 return new Status(StatusCode.BADREQUEST, String.format("Type mismatch between Ethernet & Dst IP"));
745 if (ipsrctype != ipdsttype) {
746 if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
747 return new Status(StatusCode.BADREQUEST, String.format("IP Src Dest Type mismatch"));
751 if ((idleTimeout != null) && !isTimeoutValid(idleTimeout)) {
752 return new Status(StatusCode.BADREQUEST, String.format("Idle Timeout value %s is not valid",
756 if ((hardTimeout != null) && !isTimeoutValid(hardTimeout)) {
757 return new Status(StatusCode.BADREQUEST, String.format("Hard Timeout value %s is not valid",
762 if (actions == null || actions.isEmpty()) {
763 return new Status(StatusCode.BADREQUEST, "Actions value is null or empty");
765 for (String actiongrp : actions) {
767 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
768 if (sstr.matches()) {
769 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
770 return new Status(StatusCode.BADREQUEST, String.format("IP source address %s is not valid",
776 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
777 if (sstr.matches()) {
778 if (!NetUtils.isIPv4AddressValid(sstr.group(1))) {
779 return new Status(StatusCode.BADREQUEST, String.format(
780 "IP destination address %s is not valid", sstr.group(1)));
785 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
786 if (sstr.matches()) {
787 if ((sstr.group(1) != null) && !isVlanIdValid(sstr.group(1))) {
788 return new Status(StatusCode.BADREQUEST, String.format(
789 "Vlan ID %s is not in the range 0 - 4095", sstr.group(1)));
794 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
795 if (sstr.matches()) {
796 if ((sstr.group(1) != null) && !isVlanPriorityValid(sstr.group(1))) {
797 return new Status(StatusCode.BADREQUEST, String.format(
798 "Vlan priority %s is not in the range 0 - 7", sstr.group(1)));
803 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
804 if (sstr.matches()) {
805 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
806 return new Status(StatusCode.BADREQUEST, String.format(
807 "Ethernet source address %s is not valid. Example: 00:05:b9:7c:81:5f",
812 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
813 if (sstr.matches()) {
814 if ((sstr.group(1) != null) && !isL2AddressValid(sstr.group(1))) {
815 return new Status(StatusCode.BADREQUEST, String.format(
816 "Ethernet destination address %s is not valid. Example: 00:05:b9:7c:81:5f",
822 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
823 if (sstr.matches()) {
824 if ((sstr.group(1) != null) && !isTOSBitsValid(sstr.group(1))) {
825 return new Status(StatusCode.BADREQUEST, String.format(
826 "IP ToS bits %s is not in the range 0 - 63", sstr.group(1)));
831 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
832 if (sstr.matches()) {
833 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
834 return new Status(StatusCode.BADREQUEST, String.format(
835 "Transport source port %s is not valid", sstr.group(1)));
840 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
841 if (sstr.matches()) {
842 if ((sstr.group(1) != null) && !isTpPortValid(sstr.group(1))) {
843 return new Status(StatusCode.BADREQUEST, String.format(
844 "Transport destination port %s is not valid", sstr.group(1)));
848 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
849 if (sstr.matches()) {
850 if (!NetUtils.isIPAddressValid(sstr.group(1))) {
851 return new Status(StatusCode.BADREQUEST, String.format(
852 "IP destination address %s is not valid", sstr.group(1)));
857 } catch (NumberFormatException e) {
858 return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
861 return new Status(StatusCode.SUCCESS);
864 public FlowEntry getFlowEntry() {
865 String group = this.isInternalFlow() ? FlowConfig.INTERNALSTATICFLOWGROUP : FlowConfig.STATICFLOWGROUP;
866 return new FlowEntry(group, this.name, this.getFlow(), this.getNode());
869 public Flow getFlow() {
870 Match match = new Match();
872 if (this.ingressPort != null) {
873 match.setField(MatchType.IN_PORT,
874 NodeConnector.fromString(String.format("%s|%s@%s", node.getType(), ingressPort, node.toString())));
876 if (this.dlSrc != null) {
877 match.setField(MatchType.DL_SRC, HexEncode.bytesFromHexString(this.dlSrc));
879 if (this.dlDst != null) {
880 match.setField(MatchType.DL_DST, HexEncode.bytesFromHexString(this.dlDst));
882 if (this.etherType != null) {
883 match.setField(MatchType.DL_TYPE, Integer.decode(etherType).shortValue());
885 if (this.vlanId != null) {
886 match.setField(MatchType.DL_VLAN, Short.parseShort(this.vlanId));
888 if (this.vlanPriority != null) {
889 match.setField(MatchType.DL_VLAN_PR, Byte.parseByte(this.vlanPriority));
891 if (this.nwSrc != null) {
892 String parts[] = this.nwSrc.split("/");
893 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
894 InetAddress mask = null;
896 if (parts.length > 1) {
897 maskLen = Integer.parseInt(parts[1]);
899 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
901 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
902 match.setField(MatchType.NW_SRC, ip, mask);
904 if (this.nwDst != null) {
905 String parts[] = this.nwDst.split("/");
906 InetAddress ip = NetUtils.parseInetAddress(parts[0]);
907 InetAddress mask = null;
909 if (parts.length > 1) {
910 maskLen = Integer.parseInt(parts[1]);
912 maskLen = (ip instanceof Inet6Address) ? 128 : 32;
914 mask = NetUtils.getInetNetworkMask(maskLen, ip instanceof Inet6Address);
915 match.setField(MatchType.NW_DST, ip, mask);
917 if (IPProtocols.fromString(this.protocol) != IPProtocols.ANY) {
918 match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(this.protocol));
920 if (this.tosBits != null) {
921 match.setField(MatchType.NW_TOS, Byte.parseByte(this.tosBits));
923 if (this.tpSrc != null) {
924 match.setField(MatchType.TP_SRC, Integer.valueOf(this.tpSrc).shortValue());
926 if (this.tpDst != null) {
927 match.setField(MatchType.TP_DST, Integer.valueOf(this.tpDst).shortValue());
930 Flow flow = new Flow(match, getActionList());
932 if (this.cookie != null) {
933 flow.setId(Long.parseLong(cookie));
935 if (this.hardTimeout != null) {
936 flow.setHardTimeout(Short.parseShort(this.hardTimeout));
938 if (this.idleTimeout != null) {
939 flow.setIdleTimeout(Short.parseShort(idleTimeout));
941 if (this.priority != null) {
942 flow.setPriority(Integer.decode(this.priority).shortValue());
949 public boolean isByNameAndNodeIdEqual(FlowConfig that) {
950 return (this.name.equals(that.name) && this.node.equals(that.node));
953 public boolean isByNameAndNodeIdEqual(String name, Node node) {
954 return (this.name.equals(name) && this.node.equals(node));
957 public boolean onNode(Node node) {
958 return this.node.equals(node);
961 public void toggleInstallation() {
962 installInHw = (installInHw == null) ? Boolean.toString(false) : Boolean.toString(!Boolean.valueOf(installInHw));
966 * Parses the actions string and return the List of SAL Action No syntax
967 * check run, as this function will be called when the config validation
968 * check has already been performed
970 private List<Action> getActionList() {
971 List<Action> actionList = new ArrayList<Action>();
973 if (actions != null) {
975 for (String actiongrp : actions) {
976 sstr = Pattern.compile(ActionType.OUTPUT + "=(.*)").matcher(actiongrp);
977 if (sstr.matches()) {
978 for (String t : sstr.group(1).split(",")) {
980 String nc = String.format("%s|%s@%s", node.getType(), t, node.toString());
981 actionList.add(new Output(NodeConnector.fromString(nc)));
987 sstr = Pattern.compile(ActionType.ENQUEUE + "=(.*)").matcher(actiongrp);
988 if (sstr.matches()) {
989 for (String t : sstr.group(1).split(",")) {
991 String parts[] = t.split(":");
992 String nc = String.format("%s|%s@%s", node.getType(), parts[0], node.toString());
993 if (parts.length == 1) {
994 actionList.add(new Enqueue(NodeConnector.fromString(nc)));
997 .add(new Enqueue(NodeConnector.fromString(nc), Integer.parseInt(parts[1])));
1004 sstr = Pattern.compile(ActionType.DROP.toString()).matcher(actiongrp);
1005 if (sstr.matches()) {
1006 actionList.add(new Drop());
1010 sstr = Pattern.compile(ActionType.LOOPBACK.toString()).matcher(actiongrp);
1011 if (sstr.matches()) {
1012 actionList.add(new Loopback());
1016 sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
1017 if (sstr.matches()) {
1018 actionList.add(new Flood());
1022 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
1023 if (sstr.matches()) {
1024 actionList.add(new SwPath());
1028 sstr = Pattern.compile(ActionType.HW_PATH.toString()).matcher(actiongrp);
1029 if (sstr.matches()) {
1030 actionList.add(new HwPath());
1034 sstr = Pattern.compile(ActionType.CONTROLLER.toString()).matcher(actiongrp);
1035 if (sstr.matches()) {
1036 actionList.add(new Controller());
1040 sstr = Pattern.compile(ActionType.SET_VLAN_ID.toString() + "=(.*)").matcher(actiongrp);
1041 if (sstr.matches()) {
1042 actionList.add(new SetVlanId(Short.parseShort(sstr.group(1))));
1046 sstr = Pattern.compile(ActionType.SET_VLAN_PCP.toString() + "=(.*)").matcher(actiongrp);
1047 if (sstr.matches()) {
1048 actionList.add(new SetVlanPcp(Byte.parseByte(sstr.group(1))));
1052 sstr = Pattern.compile(ActionType.POP_VLAN.toString()).matcher(actiongrp);
1053 if (sstr.matches()) {
1054 actionList.add(new PopVlan());
1058 sstr = Pattern.compile(ActionType.SET_DL_SRC.toString() + "=(.*)").matcher(actiongrp);
1059 if (sstr.matches()) {
1060 actionList.add(new SetDlSrc(HexEncode.bytesFromHexString(sstr.group(1))));
1064 sstr = Pattern.compile(ActionType.SET_DL_DST.toString() + "=(.*)").matcher(actiongrp);
1065 if (sstr.matches()) {
1066 actionList.add(new SetDlDst(HexEncode.bytesFromHexString(sstr.group(1))));
1069 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
1070 if (sstr.matches()) {
1071 actionList.add(new SetNwSrc(NetUtils.parseInetAddress(sstr.group(1))));
1074 sstr = Pattern.compile(ActionType.SET_NW_DST.toString() + "=(.*)").matcher(actiongrp);
1075 if (sstr.matches()) {
1076 actionList.add(new SetNwDst(NetUtils.parseInetAddress(sstr.group(1))));
1080 sstr = Pattern.compile(ActionType.SET_NW_TOS.toString() + "=(.*)").matcher(actiongrp);
1081 if (sstr.matches()) {
1082 actionList.add(new SetNwTos(Byte.parseByte(sstr.group(1))));
1086 sstr = Pattern.compile(ActionType.SET_TP_SRC.toString() + "=(.*)").matcher(actiongrp);
1087 if (sstr.matches()) {
1088 actionList.add(new SetTpSrc(Integer.valueOf(sstr.group(1))));
1092 sstr = Pattern.compile(ActionType.SET_TP_DST.toString() + "=(.*)").matcher(actiongrp);
1093 if (sstr.matches()) {
1094 actionList.add(new SetTpDst(Integer.valueOf(sstr.group(1))));
1098 sstr = Pattern.compile(ActionType.SET_NEXT_HOP.toString() + "=(.*)").matcher(actiongrp);
1099 if (sstr.matches()) {
1100 actionList.add(new SetNextHop(NetUtils.parseInetAddress(sstr.group(1))));