blob: f936bfb856b94599bb204294e8d7db01c0f8a8f6 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
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
18package org.openflow.protocol;
19
20import java.util.Arrays;
21import java.util.List;
22
23import org.jboss.netty.buffer.ChannelBuffer;
24import org.jboss.netty.buffer.ChannelBuffers;
25import org.openflow.protocol.factory.MessageParseException;
26import org.openflow.protocol.factory.OFMessageFactory;
27import org.openflow.protocol.factory.OFMessageFactoryAware;
28import 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 */
36public 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 /**
103 * @return the errorType
104 */
105 public short getErrorType() {
106 return errorType;
107 }
108
109 /**
110 * @param errorType
111 * the errorType to set
112 */
113 public void setErrorType(short errorType) {
114 this.errorType = errorType;
115 }
116
117 public void setErrorType(OFErrorType type) {
118 this.errorType = type.getValue();
119 }
120
121 /**
122 * @return true if the error is an extended vendor error
123 */
124 public boolean isVendorError() {
125 return errorType == OFErrorType.OFPET_VENDOR_ERROR.getValue();
126 }
127
128 /**
129 * @return the errorCode
130 */
131 public short getErrorCode() {
132 return errorCode;
133 }
134
135 /**
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700136 * @param code
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800137 * the errorCode to set
138 */
139 public void setErrorCode(OFHelloFailedCode code) {
140 this.errorCode = (short) code.ordinal();
141 }
142
143 public void setErrorCode(short errorCode) {
144 this.errorCode = errorCode;
145 }
146
147 public void setErrorCode(OFBadRequestCode code) {
148 this.errorCode = (short) code.ordinal();
149 }
150
151 public void setErrorCode(OFBadActionCode code) {
152 this.errorCode = (short) code.ordinal();
153 }
154
155 public void setErrorCode(OFFlowModFailedCode code) {
156 this.errorCode = (short) code.ordinal();
157 }
158
159 public void setErrorCode(OFPortModFailedCode code) {
160 this.errorCode = (short) code.ordinal();
161 }
162
163 public void setErrorCode(OFQueueOpFailedCode code) {
164 this.errorCode = (short) code.ordinal();
165 }
166
167 public int getVendorErrorType() {
168 return vendorErrorType;
169 }
170
171 public void setVendorErrorType(int vendorErrorType) {
172 this.vendorErrorType = vendorErrorType;
173 }
174
175 public short getVendorErrorCode() {
176 return vendorErrorCode;
177 }
178
179 public void setVendorErrorCode(short vendorErrorCode) {
180 this.vendorErrorCode = vendorErrorCode;
181 }
182
183 public OFMessage getOffendingMsg() throws MessageParseException {
184 // should only have one message embedded; if more than one, just
185 // grab first
186 if (this.error == null)
187 return null;
188 ChannelBuffer errorMsg = ChannelBuffers.wrappedBuffer(this.error);
189 if (factory == null)
190 throw new RuntimeException("MessageFactory not set");
191
192 List<OFMessage> msglist = this.factory.parseMessage(errorMsg);
193 if (msglist == null)
194 return null;
195 return msglist.get(0);
196 }
197
198 /**
199 * Write this offending message into the payload of the Error message
200 *
201 * @param offendingMsg
202 */
203
204 public void setOffendingMsg(OFMessage offendingMsg) {
205 if (offendingMsg == null) {
206 super.setLengthU(MINIMUM_LENGTH);
207 } else {
208 this.error = new byte[offendingMsg.getLengthU()];
209 ChannelBuffer data = ChannelBuffers.wrappedBuffer(this.error);
210 data.writerIndex(0);
211 offendingMsg.writeTo(data);
212 super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
213 }
214 }
215
216 public OFMessageFactory getFactory() {
217 return factory;
218 }
219
220 @Override
221 public void setMessageFactory(OFMessageFactory factory) {
222 this.factory = factory;
223 }
224
225 /**
226 * @return the error
227 */
228 public byte[] getError() {
229 return error;
230 }
231
232 /**
233 * @param error
234 * the error to set
235 */
236 public void setError(byte[] error) {
237 this.error = error;
238 }
239
240 /**
241 * @return the errorIsAscii
242 */
243 public boolean isErrorIsAscii() {
244 return errorIsAscii;
245 }
246
247 /**
248 * @param errorIsAscii
249 * the errorIsAscii to set
250 */
251 public void setErrorIsAscii(boolean errorIsAscii) {
252 this.errorIsAscii = errorIsAscii;
253 }
254
255 @Override
256 public void readFrom(ChannelBuffer data) {
257 super.readFrom(data);
258 this.errorType = data.readShort();
259 this.errorCode = data.readShort();
260 int dataLength = this.getLengthU() - MINIMUM_LENGTH;
261 if (dataLength > 0) {
262 this.error = new byte[dataLength];
263 data.readBytes(this.error);
264 if (this.errorType == OFErrorType.OFPET_HELLO_FAILED.getValue())
265 this.errorIsAscii = true;
266 }
267 }
268
269 @Override
270 public void writeTo(ChannelBuffer data) {
271 super.writeTo(data);
272 data.writeShort(errorType);
273 data.writeShort(errorCode);
274 if (error != null)
275 data.writeBytes(error);
276 }
277
278 /*
279 * (non-Javadoc)
280 *
281 * @see java.lang.Object#hashCode()
282 */
283 @Override
284 public int hashCode() {
285 final int prime = 31;
286 int result = super.hashCode();
287 result = prime * result + Arrays.hashCode(error);
288 result = prime * result + errorCode;
289 result = prime * result + (errorIsAscii ? 1231 : 1237);
290 result = prime * result + errorType;
291 return result;
292 }
293
294 /*
295 * (non-Javadoc)
296 *
297 * @see java.lang.Object#equals(java.lang.Object)
298 */
299 @Override
300 public boolean equals(Object obj) {
301 if (this == obj)
302 return true;
303 if (!super.equals(obj))
304 return false;
305 if (getClass() != obj.getClass())
306 return false;
307 OFError other = (OFError) obj;
308 if (!Arrays.equals(error, other.error))
309 return false;
310 if (errorCode != other.errorCode)
311 return false;
312 if (errorIsAscii != other.errorIsAscii)
313 return false;
314 if (errorType != other.errorType)
315 return false;
316 return true;
317 }
318
319}