2 * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
18 package org.openflow.protocol;
20 import java.util.LinkedList;
21 import java.util.List;
23 import org.jboss.netty.buffer.ChannelBuffer;
24 import org.openflow.protocol.action.OFAction;
25 import org.openflow.protocol.factory.OFActionFactory;
26 import org.openflow.protocol.factory.OFActionFactoryAware;
27 import org.openflow.util.U16;
30 * Represents an ofp_flow_mod message
31 * @author David Erickson (daviderickson@cs.stanford.edu)
34 public class OFFlowMod extends OFMessage implements OFActionFactoryAware, Cloneable {
35 public static int MINIMUM_LENGTH = 72;
37 public static final short OFPFC_ADD = 0; /* New flow. */
38 public static final short OFPFC_MODIFY = 1; /* Modify all matching flows. */
39 public static final short OFPFC_MODIFY_STRICT = 2; /* Modify entry strictly matching wildcards */
40 public static final short OFPFC_DELETE=3; /* Delete all matching flows. */
41 public static final short OFPFC_DELETE_STRICT =4; /* Strictly match wildcards and priority. */
43 // Open Flow Flow Mod Flags. Use "or" operation to set multiple flags
44 public static final short OFPFF_SEND_FLOW_REM = 0x1; // 1 << 0
45 public static final short OFPFF_CHECK_OVERLAP = 0x2; // 1 << 1
46 public static final short OFPFF_EMERG = 0x4; // 1 << 2
48 protected OFActionFactory actionFactory;
49 protected OFMatch match;
50 protected long cookie;
51 protected short command;
52 protected short idleTimeout;
53 protected short hardTimeout;
54 protected short priority;
55 protected int bufferId;
56 protected short outPort;
57 protected short flags;
58 protected List<OFAction> actions;
62 this.outPort = OFPort.OFPP_NONE.getValue();
63 this.type = OFType.FLOW_MOD;
64 this.length = U16.t(MINIMUM_LENGTH);
71 public int getBufferId() {
79 public OFFlowMod setBufferId(int bufferId) {
80 this.bufferId = bufferId;
88 public long getCookie() {
96 public OFFlowMod setCookie(long cookie) {
105 public short getCommand() {
113 public OFFlowMod setCommand(short command) {
114 this.command = command;
122 public short getFlags() {
130 public OFFlowMod setFlags(short flags) {
139 public short getHardTimeout() {
140 return this.hardTimeout;
147 public OFFlowMod setHardTimeout(short hardTimeout) {
148 this.hardTimeout = hardTimeout;
156 public short getIdleTimeout() {
157 return this.idleTimeout;
164 public OFFlowMod setIdleTimeout(short idleTimeout) {
165 this.idleTimeout = idleTimeout;
170 * Gets a copy of the OFMatch object for this FlowMod, changes to this
171 * object do not modify the FlowMod
174 public OFMatch getMatch() {
182 public OFFlowMod setMatch(OFMatch match) {
191 public short getOutPort() {
199 public OFFlowMod setOutPort(short outPort) {
200 this.outPort = outPort;
208 public OFFlowMod setOutPort(OFPort port) {
209 this.outPort = port.getValue();
217 public short getPriority() {
218 return this.priority;
225 public OFFlowMod setPriority(short priority) {
226 this.priority = priority;
231 * Returns read-only copies of the actions contained in this Flow Mod
232 * @return a list of ordered OFAction objects
234 public List<OFAction> getActions() {
239 * Sets the list of actions this Flow Mod contains
240 * @param actions a list of ordered OFAction objects
242 public OFFlowMod setActions(List<OFAction> actions) {
243 this.actions = actions;
248 public void readFrom(ChannelBuffer data) {
249 super.readFrom(data);
250 if (this.match == null)
251 this.match = new OFMatch();
252 this.match.readFrom(data);
253 this.cookie = data.readLong();
254 this.command = data.readShort();
255 this.idleTimeout = data.readShort();
256 this.hardTimeout = data.readShort();
257 this.priority = data.readShort();
258 this.bufferId = data.readInt();
259 this.outPort = data.readShort();
260 this.flags = data.readShort();
261 if (this.actionFactory == null)
262 throw new RuntimeException("OFActionFactory not set");
263 this.actions = this.actionFactory.parseActions(data, getLengthU() -
268 public void writeTo(ChannelBuffer data) {
270 this.match.writeTo(data);
271 data.writeLong(cookie);
272 data.writeShort(command);
273 data.writeShort(idleTimeout);
274 data.writeShort(hardTimeout);
275 data.writeShort(priority);
276 data.writeInt(bufferId);
277 data.writeShort(outPort);
278 data.writeShort(flags);
279 if (actions != null) {
280 for (OFAction action : actions) {
281 action.writeTo(data);
287 public void setActionFactory(OFActionFactory actionFactory) {
288 this.actionFactory = actionFactory;
292 public int hashCode() {
293 final int prime = 227;
294 int result = super.hashCode();
295 result = prime * result + ((actions == null) ? 0 : actions.hashCode());
296 result = prime * result + bufferId;
297 result = prime * result + command;
298 result = prime * result + (int) (cookie ^ (cookie >>> 32));
299 result = prime * result + flags;
300 result = prime * result + hardTimeout;
301 result = prime * result + idleTimeout;
302 result = prime * result + ((match == null) ? 0 : match.hashCode());
303 result = prime * result + outPort;
304 result = prime * result + priority;
309 public boolean equals(Object obj) {
313 if (!super.equals(obj)) {
316 if (!(obj instanceof OFFlowMod)) {
319 OFFlowMod other = (OFFlowMod) obj;
320 if (actions == null) {
321 if (other.actions != null) {
324 } else if (!actions.equals(other.actions)) {
327 if (bufferId != other.bufferId) {
330 if (command != other.command) {
333 if (cookie != other.cookie) {
336 if (flags != other.flags) {
339 if (hardTimeout != other.hardTimeout) {
342 if (idleTimeout != other.idleTimeout) {
346 if (other.match != null) {
349 } else if (!match.equals(other.match)) {
352 if (outPort != other.outPort) {
355 if (priority != other.priority) {
362 * @see java.lang.Object#clone()
365 public OFFlowMod clone() throws CloneNotSupportedException {
366 OFMatch neoMatch = match.clone();
367 OFFlowMod flowMod= (OFFlowMod) super.clone();
368 flowMod.setMatch(neoMatch);
369 List<OFAction> neoActions = new LinkedList<OFAction>();
370 for(OFAction action: this.actions)
371 neoActions.add((OFAction) action.clone());
372 flowMod.setActions(neoActions);
377 * @see java.lang.Object#toString()
380 public String toString() {
381 return "OFFlowMod [actionFactory=" + actionFactory + ", actions="
382 + actions + ", bufferId=" + bufferId + ", command=" + command
383 + ", cookie=" + cookie + ", flags=" + flags + ", hardTimeout="
384 + hardTimeout + ", idleTimeout=" + idleTimeout + ", match="
385 + match + ", outPort=" + outPort + ", priority=" + priority
386 + ", length=" + length + ", type=" + type + ", version="
387 + version + ", xid=" + xid + "]";