1 package org.openflow.codec.protocol;
3 import java.util.LinkedList;
6 import org.openflow.codec.io.IDataBuffer;
7 import org.openflow.codec.protocol.factory.OFPInstructionFactory;
8 import org.openflow.codec.protocol.factory.OFPInstructionFactoryAware;
9 import org.openflow.codec.protocol.instruction.OFPInstruction;
10 import org.openflow.codec.util.U16;
13 * Represents an ofp_flow_mod message
15 * @author David Erickson (daviderickson@cs.stanford.edu)
18 public class OFPFlowMod extends OFPMessage implements OFPInstructionFactoryAware, Cloneable {
19 public static int MINIMUM_LENGTH = 56;
20 public static int MIN_LENGTH_WITHOUT_MATCH = MINIMUM_LENGTH - 8;
22 public static final short OFPFC_ADD = 0; /* New flow. */
23 public static final short OFPFC_MODIFY = 1; /* Modify all matching flows. */
24 public static final short OFPFC_MODIFY_STRICT = 2; /*
25 * Modify entry strictly
28 public static final short OFPFC_DELETE = 3; /* Delete all matching flows. */
29 public static final short OFPFC_DELETE_STRICT = 4; /*
35 private OFPInstructionFactory instructionFactory;
37 private long cookieMask;
39 private OFPFlowModCommand command;
40 private short idleTimeout;
41 private short hardTimeout;
42 private short priority;
47 private OFPMatch match;
48 private List<OFPInstruction> instructions;
52 this.type = OFPType.FLOW_MOD;
53 this.length = U16.t(MINIMUM_LENGTH);
61 public int getBufferId() {
70 public OFPFlowMod setBufferId(int bufferId) {
71 this.bufferId = bufferId;
80 public long getCookie() {
89 public OFPFlowMod setCookie(long cookie) {
94 public long getCookieMask() {
98 public void setCookieMask(long cookieMask) {
99 this.cookieMask = cookieMask;
102 public byte getTableId() {
106 public void setTableId(byte tableId) {
107 this.tableId = tableId;
115 public OFPFlowModCommand getCommand() {
124 public OFPFlowMod setCommand(OFPFlowModCommand command) {
125 this.command = command;
134 public short getFlags() {
143 public OFPFlowMod setFlags(short flags) {
153 public short getHardTimeout() {
154 return this.hardTimeout;
162 public OFPFlowMod setHardTimeout(short hardTimeout) {
163 this.hardTimeout = hardTimeout;
172 public short getIdleTimeout() {
173 return this.idleTimeout;
181 public OFPFlowMod setIdleTimeout(short idleTimeout) {
182 this.idleTimeout = idleTimeout;
187 * Gets a copy of the OFPMatch object for this FlowMod, changes to this
188 * object do not modify the FlowMod
192 public OFPMatch getMatch() {
201 public OFPFlowMod setMatch(OFPMatch match) {
211 public int getOutPort() {
220 public OFPFlowMod setOutPort(int outPort) {
221 this.outPort = outPort;
230 public OFPFlowMod setOutPort(OFPPortNo port) {
231 this.outPort = port.getValue();
235 public int getOutGroup() {
239 public void setOutGroup(int outGroup) {
240 this.outGroup = outGroup;
248 public short getPriority() {
249 return this.priority;
257 public OFPFlowMod setPriority(short priority) {
258 this.priority = priority;
263 * Returns instructions contained in this Flow Mod
265 * @return a list of ordered OFPInstruction objects
267 public List<OFPInstruction> getInstructions() {
268 return this.instructions;
272 * Sets the list of instruction this Flow Mod contains
275 * a list of ordered OFPInstruction objects
277 public OFPFlowMod setInstructions(List<OFPInstruction> instructions) {
278 this.instructions = instructions;
283 public void readFrom(IDataBuffer data) {
284 super.readFrom(data);
285 this.cookie = data.getLong();
286 this.cookieMask = data.getLong();
287 this.tableId = data.get();
288 this.command = OFPFlowModCommand.valueOf(data.get());
289 this.idleTimeout = data.getShort();
290 this.hardTimeout = data.getShort();
291 this.priority = data.getShort();
292 this.bufferId = data.getInt();
293 this.outPort = data.getInt();
294 this.outGroup = data.getInt();
295 this.flags = data.getShort();
296 data.getShort(); // pad
297 if (this.match == null)
298 this.match = new OFPMatch();
299 this.match.readFrom(data);
300 if (this.instructionFactory == null)
301 throw new RuntimeException("OFPInstructionFactory is not set");
302 int instructionLength = getLengthU() - MIN_LENGTH_WITHOUT_MATCH - match.getLengthWithPadding();
303 this.instructions = this.instructionFactory.parseInstructions(data, instructionLength);
307 public void writeTo(IDataBuffer data) {
308 length = getLength();
310 data.putLong(cookie);
311 data.putLong(cookieMask);
313 data.put(command.getValue());
314 data.putShort(idleTimeout);
315 data.putShort(hardTimeout);
316 data.putShort(priority);
317 data.putInt(bufferId);
318 data.putInt(outPort);
319 data.putInt(outGroup);
320 data.putShort(flags);
321 data.putShort((short) 0);
322 this.match.writeTo(data);
323 if (instructions != null) {
324 for (OFPInstruction instr : instructions) {
331 * get length based on match and instruction length
333 public short getLength() {
334 int totalLength = MIN_LENGTH_WITHOUT_MATCH;
335 totalLength += this.match.getLengthWithPadding();
336 if (instructions != null) {
337 for (OFPInstruction instr : instructions) {
338 totalLength += instr.getLength();
341 length = U16.t(totalLength);
346 public int hashCode() {
347 final int prime = 227;
348 int result = super.hashCode();
349 result = prime * result + ((instructions == null) ? 0 : instructions.hashCode());
350 result = prime * result + bufferId;
351 result = prime * result + command.getValue();
352 result = prime * result + (int) (cookie ^ (cookie >>> 32));
353 result = prime * result + (int) (cookieMask ^ (cookieMask >>> 32));
354 result = prime * result + tableId;
355 result = prime * result + flags;
356 result = prime * result + hardTimeout;
357 result = prime * result + idleTimeout;
358 result = prime * result + ((match == null) ? 0 : match.hashCode());
359 result = prime * result + outPort;
360 result = prime * result + outGroup;
361 result = prime * result + priority;
366 public boolean equals(Object obj) {
370 if (!super.equals(obj)) {
373 if (!(obj instanceof OFPFlowMod)) {
376 OFPFlowMod other = (OFPFlowMod) obj;
377 if (instructions == null) {
378 if (other.instructions != null) {
381 } else if (!instructions.equals(other.instructions)) {
384 if (bufferId != other.bufferId) {
387 if (command != other.command) {
390 if (cookie != other.cookie) {
393 if (cookieMask != other.cookieMask) {
396 if (tableId != other.tableId) {
399 if (flags != other.flags) {
402 if (hardTimeout != other.hardTimeout) {
405 if (idleTimeout != other.idleTimeout) {
409 if (other.match != null) {
412 } else if (!match.equals(other.match)) {
415 if (outPort != other.outPort) {
418 if (outGroup != other.outGroup) {
421 if (priority != other.priority) {
430 * @see java.lang.Object#clone()
433 public OFPFlowMod clone() {
435 OFPMatch neoMatch = match.clone();
436 OFPFlowMod flowMod = (OFPFlowMod) super.clone();
437 flowMod.setMatch(neoMatch);
438 List<OFPInstruction> instrList = new LinkedList<OFPInstruction>();
439 for (OFPInstruction instr : this.instructions)
440 instrList.add((OFPInstruction) instr.clone());
441 flowMod.setInstructions(instrList);
443 } catch (CloneNotSupportedException e) {
445 throw new RuntimeException(e);
452 * @see java.lang.Object#toString()
455 public String toString() {
456 return "OFPFlowMod [instructionFactory=" + instructionFactory + ", instructions=" + instructions
457 + ", bufferId=" + bufferId + ", command=" + command + ", cookie=" + cookie + ", cookieMask="
458 + cookieMask + ", tableId=" + tableId + ", flags=" + flags + ", hardTimeout=" + hardTimeout
459 + ", idleTimeout=" + idleTimeout + ", match=" + match + ", outPort=" + outPort + ", outGroup="
460 + outGroup + ", priority=" + priority + ", length=" + length + ", type=" + type + ", version="
461 + version + ", xid=" + xid + "]";
465 public void setInstructionFactory(OFPInstructionFactory instructionFactory) {
466 this.instructionFactory = instructionFactory;