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.sal.flowprogrammer;
11 import org.opendaylight.controller.sal.action.Action;
12 import org.opendaylight.controller.sal.action.ActionType;
13 import org.opendaylight.controller.sal.action.SetDlType;
14 import org.opendaylight.controller.sal.action.SetNwDst;
15 import org.opendaylight.controller.sal.action.SetNwSrc;
16 import org.opendaylight.controller.sal.match.Match;
17 import org.opendaylight.controller.sal.utils.EtherTypes;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
21 import javax.xml.bind.annotation.XmlAccessType;
22 import javax.xml.bind.annotation.XmlAccessorType;
23 import javax.xml.bind.annotation.XmlElement;
24 import javax.xml.bind.annotation.XmlRootElement;
25 import java.io.Serializable;
26 import java.net.Inet6Address;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
32 * Represent a flow: match + actions + flow specific properties
35 @XmlAccessorType(XmlAccessType.NONE)
36 public class Flow implements Cloneable, Serializable {
37 protected static final Logger logger = LoggerFactory.getLogger(Flow.class);
38 private static final long serialVersionUID = 1L;
42 private List<Action> actions;
44 private short priority;
46 private short idleTimeout;
48 private short hardTimeout;
50 private long id; // unique identifier for this flow
57 public Flow(Match match, List<Action> actions) {
58 if (match.isIPv4() && actionsAreIPv6()) {
60 throw new Exception("Conflicting Match and Action list");
61 } catch (Exception e) {
66 this.actions = actions;
71 * Return a copy of the Match configured on this flow
75 public Match getMatch() {
80 * Set the Match for this flow This operation will overwrite an existing
85 public void setMatch(Match match) {
90 * Returns a copy of the actions list of this flow
94 public List<Action> getActions() {
95 return (actions == null) ? null : new ArrayList<Action>(actions);
99 * Set the actions list for this flow If a list is already present, it will
100 * be replaced with the passed one. During addition, only the valid actions
101 * will be added It is a no op if the passed actions is null An empty
102 * actions is a vlaid input
106 public void setActions(List<Action> actions) {
107 if (actions == null) {
111 this.actions = new ArrayList<Action>(actions.size());
112 for (Action action : actions) {
113 if (action.isValid()) {
114 this.actions.add(action);
120 * Returns whether the Flow is for IPv4 or IPv6 Information is derived from
121 * match and actions list
125 public boolean isIPv6() {
126 return (match.isIPv6()) ? true : actionsAreIPv6();
130 * Returns true if it finds at least one action which is for IPv6 in the
131 * list of actions for this Flow
135 private boolean actionsAreIPv6() {
136 if (this.actions != null) {
137 for (Action action : actions) {
138 switch (action.getType()) {
140 if (((SetNwSrc) action).getAddress() instanceof Inet6Address) {
145 if (((SetNwDst) action).getAddress() instanceof Inet6Address) {
150 if (((SetDlType) action).getDlType() == EtherTypes.IPv6.intValue()) {
162 public Flow clone() {
165 cloned = (Flow) super.clone();
166 cloned.match = this.getMatch();
167 cloned.actions = this.getActions();
168 } catch (CloneNotSupportedException e) {
175 public int hashCode() {
176 final int prime = 31;
178 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
179 result = prime * result + hardTimeout;
180 result = prime * result + (int) (id ^ (id >>> 32));
181 result = prime * result + idleTimeout;
182 result = prime * result + ((match == null) ? 0 : match.hashCode());
183 result = prime * result + priority;
188 public boolean equals(Object obj) {
195 if (getClass() != obj.getClass()) {
198 Flow other = (Flow) obj;
199 if (actions == null) {
200 if (other.actions != null) {
203 } else if (!actions.equals(other.actions)) {
206 if (hardTimeout != other.hardTimeout) {
209 if (id != other.id) {
212 if (idleTimeout != other.idleTimeout) {
216 if (other.match != null) {
219 } else if (!match.equals(other.match)) {
222 if (priority != other.priority) {
229 public String toString() {
230 return "Flow[match = " + match + ", actions = " + actions + ", priority = " + priority + ", id = " + id
231 + ", idleTimeout = " + idleTimeout + ", hardTimeout = " + hardTimeout + "]";
234 public short getPriority() {
238 public void setPriority(short priority) {
239 this.priority = priority;
242 public short getIdleTimeout() {
246 public void setIdleTimeout(short idleTimeout) {
247 this.idleTimeout = idleTimeout;
250 public short getHardTimeout() {
254 public void setHardTimeout(short hardTimeout) {
255 this.hardTimeout = hardTimeout;
258 public long getId() {
262 public void setId(long id) {
267 * Adds the specified action to the list of action of this flow
270 * @return false if the passed action is null or not valid or if it fails to
273 public boolean addAction(Action action) {
274 if (action == null || !action.isValid()) {
277 return actions.add(action);
280 public boolean removeAction(Action action) {
281 if (action == null) {
284 return actions.remove(action);
288 * remove ALL actions of type actionType from the list of actions of this
292 * @return false if an action of that type is present and it fails to remove
295 public boolean removeAction(ActionType actionType) {
296 Iterator<Action> actionIter = this.getActions().iterator();
297 while (actionIter.hasNext()) {
298 Action action = actionIter.next();
299 if (action.getType() == actionType) {
300 if (!this.removeAction(action)) {