3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.sal.flowprogrammer;
12 import java.io.Serializable;
13 import java.net.Inet6Address;
14 import java.util.ArrayList;
15 import java.util.Iterator;
16 import java.util.List;
18 import javax.xml.bind.annotation.XmlAccessType;
19 import javax.xml.bind.annotation.XmlAccessorType;
20 import javax.xml.bind.annotation.XmlElement;
21 import javax.xml.bind.annotation.XmlRootElement;
23 import org.opendaylight.controller.sal.action.Action;
24 import org.opendaylight.controller.sal.action.ActionType;
25 import org.opendaylight.controller.sal.action.SetDlType;
26 import org.opendaylight.controller.sal.action.SetNwDst;
27 import org.opendaylight.controller.sal.action.SetNwSrc;
28 import org.opendaylight.controller.sal.match.Match;
29 import org.opendaylight.controller.sal.utils.EtherTypes;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * Represent a flow: match + actions + flow specific properties
38 @XmlAccessorType(XmlAccessType.NONE)
39 public class Flow implements Cloneable, Serializable {
40 protected static final Logger logger = LoggerFactory
41 .getLogger(Flow.class);
42 private static final long serialVersionUID = 1L;
46 private List<Action> actions;
48 private short priority;
50 private short idleTimeout;
52 private short hardTimeout;
54 private long id; // unique identifier for this flow
61 public Flow(Match match, List<Action> actions) {
62 if (match.isIPv4() && actionsAreIPv6()) {
64 throw new Exception("Conflicting Match and Action list");
65 } catch (Exception e) {
70 this.actions = actions;
75 * Return a copy of the Match configured on this flow
79 public Match getMatch() {
84 * Set the Match for this flow
85 * This operation will overwrite an existing Match if present
89 public void setMatch(Match match) {
94 * Returns a copy of the actions list of this flow
97 public List<Action> getActions() {
98 return (actions == null) ? null : new ArrayList<Action>(actions);
102 * Set the actions list for this flow
103 * If a list is already present, it will be
104 * replaced with the passed one. During
105 * addition, only the valid actions will be added
106 * It is a no op if the passed actions is null
107 * An empty actions is a vlaid input
111 public void setActions(List<Action> actions) {
112 if (actions == null) {
116 this.actions = new ArrayList<Action>(actions.size());
117 for (Action action : actions) {
118 if (action.isValid()) {
119 this.actions.add(action);
125 * Returns whether the Flow is for IPv4 or IPv6
126 * Information is derived from match and actions list
130 public boolean isIPv6() {
131 return (match.isIPv6()) ? true : actionsAreIPv6();
135 * Returns true if it finds at least one action which is for IPv6
136 * in the list of actions for this Flow
140 private boolean actionsAreIPv6() {
141 if (this.actions != null) {
142 for (Action action : actions) {
143 switch (action.getType()) {
145 if (((SetNwSrc) action).getAddress() instanceof Inet6Address) {
150 if (((SetNwDst) action).getAddress() instanceof Inet6Address) {
155 if (((SetDlType) action).getDlType() == EtherTypes.IPv6
168 public Flow clone() {
171 cloned = (Flow) super.clone();
172 cloned.match = this.getMatch();
173 cloned.actions = this.getActions();
174 } catch (CloneNotSupportedException e) {
181 public int hashCode() {
182 final int prime = 31;
184 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
185 result = prime * result + hardTimeout;
186 result = prime * result + (int) (id ^ (id >>> 32));
187 result = prime * result + idleTimeout;
188 result = prime * result + ((match == null) ? 0 : match.hashCode());
189 result = prime * result + priority;
194 public boolean equals(Object obj) {
199 if (getClass() != obj.getClass())
201 Flow other = (Flow) obj;
202 if (actions == null) {
203 if (other.actions != null)
205 } else if (!actions.equals(other.actions))
207 if (hardTimeout != other.hardTimeout)
211 if (idleTimeout != other.idleTimeout)
214 if (other.match != null)
216 } else if (!match.equals(other.match))
218 if (priority != other.priority)
224 public String toString() {
225 return "Flow[match = " + match + ", actions = " + actions
226 + ", priority = " + priority + ", id = " + id
227 + ", idleTimeout = " + idleTimeout + ", hardTimeout = "
231 public short getPriority() {
235 public void setPriority(short priority) {
236 this.priority = priority;
239 public short getIdleTimeout() {
243 public void setIdleTimeout(short idleTimeout) {
244 this.idleTimeout = idleTimeout;
247 public short getHardTimeout() {
251 public void setHardTimeout(short hardTimeout) {
252 this.hardTimeout = hardTimeout;
255 public long getId() {
259 public void setId(long id) {
264 * Adds the specified action to the list of action of this flow
267 * @return false if the passed action is null or not valid or if it fails to add it
269 public boolean addAction(Action action) {
270 if (action == null || !action.isValid()) {
273 return actions.add(action);
276 public boolean removeAction(Action action) {
277 if (action == null) {
280 return actions.remove(action);
284 * remove ALL actions of type actionType from the list of actions of this flow
287 * @return false if an action of that type is present and it fails to remove it
289 public boolean removeAction(ActionType actionType) {
290 Iterator<Action> actionIter = this.getActions().iterator();
291 while (actionIter.hasNext()) {
292 Action action = actionIter.next();
293 if (action.getType() == actionType) {
294 if (!this.removeAction(action))