Added openflow-codec and openflowj_netty from openflowplugin
[openflowjava.git] / third-party / openflow-codec / src / main / java / org / openflow / codec / protocol / OFPFlowMod.java
1 package org.openflow.codec.protocol;
2
3 import java.util.LinkedList;
4 import java.util.List;
5
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;
11
12 /**
13  * Represents an ofp_flow_mod message
14  *
15  * @author David Erickson (daviderickson@cs.stanford.edu)
16  *
17  */
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;
21
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
26                                                         * matching wildcards
27                                                         */
28     public static final short OFPFC_DELETE = 3; /* Delete all matching flows. */
29     public static final short OFPFC_DELETE_STRICT = 4; /*
30                                                         * Strictly match
31                                                         * wildcards and
32                                                         * priority.
33                                                         */
34
35     private OFPInstructionFactory instructionFactory;
36     private long cookie;
37     private long cookieMask;
38     private byte tableId;
39     private OFPFlowModCommand command;
40     private short idleTimeout;
41     private short hardTimeout;
42     private short priority;
43     private int bufferId;
44     private int outPort;
45     private int outGroup;
46     private short flags;
47     private OFPMatch match;
48     private List<OFPInstruction> instructions;
49
50     public OFPFlowMod() {
51         super();
52         this.type = OFPType.FLOW_MOD;
53         this.length = U16.t(MINIMUM_LENGTH);
54     }
55
56     /**
57      * Get buffer_id
58      *
59      * @return
60      */
61     public int getBufferId() {
62         return this.bufferId;
63     }
64
65     /**
66      * Set buffer_id
67      *
68      * @param bufferId
69      */
70     public OFPFlowMod setBufferId(int bufferId) {
71         this.bufferId = bufferId;
72         return this;
73     }
74
75     /**
76      * Get cookie
77      *
78      * @return
79      */
80     public long getCookie() {
81         return this.cookie;
82     }
83
84     /**
85      * Set cookie
86      *
87      * @param cookie
88      */
89     public OFPFlowMod setCookie(long cookie) {
90         this.cookie = cookie;
91         return this;
92     }
93
94     public long getCookieMask() {
95         return cookieMask;
96     }
97
98     public void setCookieMask(long cookieMask) {
99         this.cookieMask = cookieMask;
100     }
101
102     public byte getTableId() {
103         return tableId;
104     }
105
106     public void setTableId(byte tableId) {
107         this.tableId = tableId;
108     }
109
110     /**
111      * Get command
112      *
113      * @return
114      */
115     public OFPFlowModCommand getCommand() {
116         return this.command;
117     }
118
119     /**
120      * Set command
121      *
122      * @param command
123      */
124     public OFPFlowMod setCommand(OFPFlowModCommand command) {
125         this.command = command;
126         return this;
127     }
128
129     /**
130      * Get flags
131      *
132      * @return
133      */
134     public short getFlags() {
135         return this.flags;
136     }
137
138     /**
139      * Set flags
140      *
141      * @param flags
142      */
143     public OFPFlowMod setFlags(short flags) {
144         this.flags = flags;
145         return this;
146     }
147
148     /**
149      * Get hard_timeout
150      *
151      * @return
152      */
153     public short getHardTimeout() {
154         return this.hardTimeout;
155     }
156
157     /**
158      * Set hard_timeout
159      *
160      * @param hardTimeout
161      */
162     public OFPFlowMod setHardTimeout(short hardTimeout) {
163         this.hardTimeout = hardTimeout;
164         return this;
165     }
166
167     /**
168      * Get idle_timeout
169      *
170      * @return
171      */
172     public short getIdleTimeout() {
173         return this.idleTimeout;
174     }
175
176     /**
177      * Set idle_timeout
178      *
179      * @param idleTimeout
180      */
181     public OFPFlowMod setIdleTimeout(short idleTimeout) {
182         this.idleTimeout = idleTimeout;
183         return this;
184     }
185
186     /**
187      * Gets a copy of the OFPMatch object for this FlowMod, changes to this
188      * object do not modify the FlowMod
189      *
190      * @return
191      */
192     public OFPMatch getMatch() {
193         return this.match;
194     }
195
196     /**
197      * Set match
198      *
199      * @param match
200      */
201     public OFPFlowMod setMatch(OFPMatch match) {
202         this.match = match;
203         return this;
204     }
205
206     /**
207      * Get out_port
208      *
209      * @return
210      */
211     public int getOutPort() {
212         return this.outPort;
213     }
214
215     /**
216      * Set out_port
217      *
218      * @param outPort
219      */
220     public OFPFlowMod setOutPort(int outPort) {
221         this.outPort = outPort;
222         return this;
223     }
224
225     /**
226      * Set out_port
227      *
228      * @param port
229      */
230     public OFPFlowMod setOutPort(OFPPortNo port) {
231         this.outPort = port.getValue();
232         return this;
233     }
234
235     public int getOutGroup() {
236         return outGroup;
237     }
238
239     public void setOutGroup(int outGroup) {
240         this.outGroup = outGroup;
241     }
242
243     /**
244      * Get priority
245      *
246      * @return
247      */
248     public short getPriority() {
249         return this.priority;
250     }
251
252     /**
253      * Set priority
254      *
255      * @param priority
256      */
257     public OFPFlowMod setPriority(short priority) {
258         this.priority = priority;
259         return this;
260     }
261
262     /**
263      * Returns instructions contained in this Flow Mod
264      *
265      * @return a list of ordered OFPInstruction objects
266      */
267     public List<OFPInstruction> getInstructions() {
268         return this.instructions;
269     }
270
271     /**
272      * Sets the list of instruction this Flow Mod contains
273      *
274      * @param instruction
275      *            a list of ordered OFPInstruction objects
276      */
277     public OFPFlowMod setInstructions(List<OFPInstruction> instructions) {
278         this.instructions = instructions;
279         return this;
280     }
281
282     @Override
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);
304     }
305
306     @Override
307     public void writeTo(IDataBuffer data) {
308         length = getLength();
309         super.writeTo(data);
310         data.putLong(cookie);
311         data.putLong(cookieMask);
312         data.put(tableId);
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) {
325                 instr.writeTo(data);
326             }
327         }
328     }
329
330     /**
331      * get length based on match and instruction length
332      */
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();
339             }
340         }
341         length = U16.t(totalLength);
342         return length;
343     }
344
345     @Override
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;
362         return result;
363     }
364
365     @Override
366     public boolean equals(Object obj) {
367         if (this == obj) {
368             return true;
369         }
370         if (!super.equals(obj)) {
371             return false;
372         }
373         if (!(obj instanceof OFPFlowMod)) {
374             return false;
375         }
376         OFPFlowMod other = (OFPFlowMod) obj;
377         if (instructions == null) {
378             if (other.instructions != null) {
379                 return false;
380             }
381         } else if (!instructions.equals(other.instructions)) {
382             return false;
383         }
384         if (bufferId != other.bufferId) {
385             return false;
386         }
387         if (command != other.command) {
388             return false;
389         }
390         if (cookie != other.cookie) {
391             return false;
392         }
393         if (cookieMask != other.cookieMask) {
394             return false;
395         }
396         if (tableId != other.tableId) {
397             return false;
398         }
399         if (flags != other.flags) {
400             return false;
401         }
402         if (hardTimeout != other.hardTimeout) {
403             return false;
404         }
405         if (idleTimeout != other.idleTimeout) {
406             return false;
407         }
408         if (match == null) {
409             if (other.match != null) {
410                 return false;
411             }
412         } else if (!match.equals(other.match)) {
413             return false;
414         }
415         if (outPort != other.outPort) {
416             return false;
417         }
418         if (outGroup != other.outGroup) {
419             return false;
420         }
421         if (priority != other.priority) {
422             return false;
423         }
424         return true;
425     }
426
427     /*
428      * (non-Javadoc)
429      *
430      * @see java.lang.Object#clone()
431      */
432     @Override
433     public OFPFlowMod clone() {
434         try {
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);
442             return flowMod;
443         } catch (CloneNotSupportedException e) {
444             // Won't happen
445             throw new RuntimeException(e);
446         }
447     }
448
449     /*
450      * (non-Javadoc)
451      *
452      * @see java.lang.Object#toString()
453      */
454     @Override
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 + "]";
462     }
463
464     @Override
465     public void setInstructionFactory(OFPInstructionFactory instructionFactory) {
466         this.instructionFactory = instructionFactory;
467
468     }
469 }