Performacne improvements via adding a netty-based openflowj and openflow plugin;...
[controller.git] / third-party / openflowj_netty / src / main / java / org / openflow / protocol / OFError.java
1 /**
2 *    Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
3 *    University
4 *
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
8 *
9 *         http://www.apache.org/licenses/LICENSE-2.0
10 *
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
15 *    under the License.
16 **/
17
18 package org.openflow.protocol;
19
20 import java.util.Arrays;
21 import java.util.List;
22
23 import org.jboss.netty.buffer.ChannelBuffer;
24 import org.jboss.netty.buffer.ChannelBuffers;
25 import org.openflow.protocol.factory.MessageParseException;
26 import org.openflow.protocol.factory.OFMessageFactory;
27 import org.openflow.protocol.factory.OFMessageFactoryAware;
28 import org.openflow.util.U16;
29
30 /**
31  * Represents an ofp_error_msg
32  *
33  * @author David Erickson (daviderickson@cs.stanford.edu)
34  * @author Rob Sherwood (rob.sherwood@stanford.edu)
35  */
36 public class OFError extends OFMessage implements OFMessageFactoryAware {
37     public static int MINIMUM_LENGTH = 12;
38
39     public enum OFErrorType {
40         // OFPET_VENDOR_ERROR is an extension that was added in Open vSwitch and isn't
41         // in the OF 1.0 spec, but it was easier to add it here instead of adding
42         // generic support for extensible vendor-defined error messages.
43         // It uses the random value 0xb0c2 to avoid conflicts with other possible new
44         // error types. Support for vendor-defined extended errors has been standardized
45         // in the OF 1.2 spec, so this workaround is only needed for 1.0.
46         OFPET_HELLO_FAILED, OFPET_BAD_REQUEST, OFPET_BAD_ACTION, OFPET_FLOW_MOD_FAILED, OFPET_PORT_MOD_FAILED, OFPET_QUEUE_OP_FAILED, OFPET_VENDOR_ERROR((short)0xb0c2);
47
48         protected short value;
49
50         private OFErrorType() {
51             this.value = (short) this.ordinal();
52         }
53
54         private OFErrorType(short value) {
55             this.value = value;
56         }
57
58         public short getValue() {
59             return value;
60         }
61     }
62
63     public enum OFHelloFailedCode {
64         OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
65     }
66
67     public enum OFBadRequestCode {
68         OFPBRC_BAD_VERSION, OFPBRC_BAD_TYPE, OFPBRC_BAD_STAT, OFPBRC_BAD_VENDOR, OFPBRC_BAD_SUBTYPE, OFPBRC_EPERM, OFPBRC_BAD_LEN, OFPBRC_BUFFER_EMPTY, OFPBRC_BUFFER_UNKNOWN
69     }
70
71     public enum OFBadActionCode {
72         OFPBAC_BAD_TYPE, OFPBAC_BAD_LEN, OFPBAC_BAD_VENDOR, OFPBAC_BAD_VENDOR_TYPE, OFPBAC_BAD_OUT_PORT, OFPBAC_BAD_ARGUMENT, OFPBAC_EPERM, OFPBAC_TOO_MANY, OFPBAC_BAD_QUEUE
73     }
74
75     public enum OFFlowModFailedCode {
76         OFPFMFC_ALL_TABLES_FULL, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_EMERG_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_UNSUPPORTED
77     }
78
79     public enum OFPortModFailedCode {
80         OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR
81     }
82
83     public enum OFQueueOpFailedCode {
84         OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
85     }
86
87     protected short errorType;
88     protected short errorCode;
89     protected int vendor;
90     protected int vendorErrorType;
91     protected short vendorErrorCode;
92     protected OFMessageFactory factory;
93     protected byte[] error;
94     protected boolean errorIsAscii;
95
96     public OFError() {
97         super();
98         this.type = OFType.ERROR;
99         this.length = U16.t(MINIMUM_LENGTH);
100     }
101
102     /** convenience constructor */
103     public OFError(OFErrorType errorType) {
104         this();
105         setErrorType(errorType);
106     }
107
108     /**
109      * @return the errorType
110      */
111     public short getErrorType() {
112         return errorType;
113     }
114
115     /**
116      * @param errorType
117      *            the errorType to set
118      */
119     public void setErrorType(short errorType) {
120         this.errorType = errorType;
121     }
122
123     public void setErrorType(OFErrorType type) {
124         this.errorType = type.getValue();
125     }
126
127     /**
128      * @return true if the error is an extended vendor error
129      */
130     public boolean isVendorError() {
131         return errorType == OFErrorType.OFPET_VENDOR_ERROR.getValue();
132     }
133
134     /**
135      * @return the errorCode
136      */
137     public short getErrorCode() {
138         return errorCode;
139     }
140
141     /**
142      * @param errorCode
143      *            the errorCode to set
144      */
145     public void setErrorCode(OFHelloFailedCode code) {
146         this.errorCode = (short) code.ordinal();
147     }
148
149     public void setErrorCode(short errorCode) {
150         this.errorCode = errorCode;
151     }
152
153     public void setErrorCode(OFBadRequestCode code) {
154         this.errorCode = (short) code.ordinal();
155     }
156
157     public void setErrorCode(OFBadActionCode code) {
158         this.errorCode = (short) code.ordinal();
159     }
160
161     public void setErrorCode(OFFlowModFailedCode code) {
162         this.errorCode = (short) code.ordinal();
163     }
164
165     public void setErrorCode(OFPortModFailedCode code) {
166         this.errorCode = (short) code.ordinal();
167     }
168
169     public void setErrorCode(OFQueueOpFailedCode code) {
170         this.errorCode = (short) code.ordinal();
171     }
172
173     public int getVendorErrorType() {
174         return vendorErrorType;
175     }
176
177     public void setVendorErrorType(int vendorErrorType) {
178         this.vendorErrorType = vendorErrorType;
179     }
180
181     public short getVendorErrorCode() {
182         return vendorErrorCode;
183     }
184
185     public void setVendorErrorCode(short vendorErrorCode) {
186         this.vendorErrorCode = vendorErrorCode;
187     }
188
189     public OFMessage getOffendingMsg() throws MessageParseException {
190         // should only have one message embedded; if more than one, just
191         // grab first
192         if (this.error == null)
193             return null;
194         ChannelBuffer errorMsg = ChannelBuffers.wrappedBuffer(this.error);
195         if (factory == null)
196             throw new RuntimeException("MessageFactory not set");
197
198         List<OFMessage> msglist = this.factory.parseMessage(errorMsg);
199         if (msglist == null)
200                 return null;
201         return msglist.get(0);
202     }
203
204     /**
205      * Write this offending message into the payload of the Error message
206      *
207      * @param offendingMsg
208      */
209
210     public void setOffendingMsg(OFMessage offendingMsg) {
211         if (offendingMsg == null) {
212             super.setLengthU(MINIMUM_LENGTH);
213         } else {
214             this.error = new byte[offendingMsg.getLengthU()];
215             ChannelBuffer data = ChannelBuffers.wrappedBuffer(this.error);
216             data.writerIndex(0);
217             offendingMsg.writeTo(data);
218             super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
219         }
220     }
221
222     public OFMessageFactory getFactory() {
223         return factory;
224     }
225
226     @Override
227     public void setMessageFactory(OFMessageFactory factory) {
228         this.factory = factory;
229     }
230
231     /**
232      * @return the error
233      */
234     public byte[] getError() {
235         return error;
236     }
237
238     /**
239      * @param error
240      *            the error to set
241      */
242     public void setError(byte[] error) {
243         this.error = error;
244     }
245
246     /**
247      * @return the errorIsAscii
248      */
249     public boolean isErrorIsAscii() {
250         return errorIsAscii;
251     }
252
253     /**
254      * @param errorIsAscii
255      *            the errorIsAscii to set
256      */
257     public void setErrorIsAscii(boolean errorIsAscii) {
258         this.errorIsAscii = errorIsAscii;
259     }
260
261     @Override
262     public void readFrom(ChannelBuffer data) {
263         super.readFrom(data);
264         this.errorType = data.readShort();
265         this.errorCode = data.readShort();
266         int dataLength = this.getLengthU() - MINIMUM_LENGTH;
267         if (dataLength > 0) {
268             this.error = new byte[dataLength];
269             data.readBytes(this.error);
270             if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.getValue())
271                 this.errorIsAscii = true;
272         }
273     }
274
275     @Override
276     public void writeTo(ChannelBuffer data) {
277         super.writeTo(data);
278         data.writeShort(errorType);
279         data.writeShort(errorCode);
280         if (error != null)
281             data.writeBytes(error);
282     }
283
284     /*
285      * (non-Javadoc)
286      *
287      * @see java.lang.Object#hashCode()
288      */
289     @Override
290     public int hashCode() {
291         final int prime = 31;
292         int result = super.hashCode();
293         result = prime * result + Arrays.hashCode(error);
294         result = prime * result + errorCode;
295         result = prime * result + (errorIsAscii ? 1231 : 1237);
296         result = prime * result + errorType;
297         return result;
298     }
299
300     /*
301      * (non-Javadoc)
302      *
303      * @see java.lang.Object#equals(java.lang.Object)
304      */
305     @Override
306     public boolean equals(Object obj) {
307         if (this == obj)
308             return true;
309         if (!super.equals(obj))
310             return false;
311         if (getClass() != obj.getClass())
312             return false;
313         OFError other = (OFError) obj;
314         if (!Arrays.equals(error, other.error))
315             return false;
316         if (errorCode != other.errorCode)
317             return false;
318         if (errorIsAscii != other.errorIsAscii)
319             return false;
320         if (errorType != other.errorType)
321             return false;
322         return true;
323     }
324
325 }