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.Arrays;
21 import java.util.List;
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;
31 * Represents an ofp_error_msg
33 * @author David Erickson (daviderickson@cs.stanford.edu)
34 * @author Rob Sherwood (rob.sherwood@stanford.edu)
36 public class OFError extends OFMessage implements OFMessageFactoryAware {
37 public static int MINIMUM_LENGTH = 12;
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);
48 protected short value;
50 private OFErrorType() {
51 this.value = (short) this.ordinal();
54 private OFErrorType(short value) {
58 public short getValue() {
63 public enum OFHelloFailedCode {
64 OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
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
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
75 public enum OFFlowModFailedCode {
76 OFPFMFC_ALL_TABLES_FULL, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_EMERG_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_UNSUPPORTED
79 public enum OFPortModFailedCode {
80 OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR
83 public enum OFQueueOpFailedCode {
84 OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
87 protected short errorType;
88 protected short errorCode;
90 protected int vendorErrorType;
91 protected short vendorErrorCode;
92 protected OFMessageFactory factory;
93 protected byte[] error;
94 protected boolean errorIsAscii;
98 this.type = OFType.ERROR;
99 this.length = U16.t(MINIMUM_LENGTH);
102 /** convenience constructor */
103 public OFError(OFErrorType errorType) {
105 setErrorType(errorType);
109 * @return the errorType
111 public short getErrorType() {
117 * the errorType to set
119 public void setErrorType(short errorType) {
120 this.errorType = errorType;
123 public void setErrorType(OFErrorType type) {
124 this.errorType = type.getValue();
128 * @return true if the error is an extended vendor error
130 public boolean isVendorError() {
131 return errorType == OFErrorType.OFPET_VENDOR_ERROR.getValue();
135 * @return the errorCode
137 public short getErrorCode() {
143 * the errorCode to set
145 public void setErrorCode(OFHelloFailedCode code) {
146 this.errorCode = (short) code.ordinal();
149 public void setErrorCode(short errorCode) {
150 this.errorCode = errorCode;
153 public void setErrorCode(OFBadRequestCode code) {
154 this.errorCode = (short) code.ordinal();
157 public void setErrorCode(OFBadActionCode code) {
158 this.errorCode = (short) code.ordinal();
161 public void setErrorCode(OFFlowModFailedCode code) {
162 this.errorCode = (short) code.ordinal();
165 public void setErrorCode(OFPortModFailedCode code) {
166 this.errorCode = (short) code.ordinal();
169 public void setErrorCode(OFQueueOpFailedCode code) {
170 this.errorCode = (short) code.ordinal();
173 public int getVendorErrorType() {
174 return vendorErrorType;
177 public void setVendorErrorType(int vendorErrorType) {
178 this.vendorErrorType = vendorErrorType;
181 public short getVendorErrorCode() {
182 return vendorErrorCode;
185 public void setVendorErrorCode(short vendorErrorCode) {
186 this.vendorErrorCode = vendorErrorCode;
189 public OFMessage getOffendingMsg() throws MessageParseException {
190 // should only have one message embedded; if more than one, just
192 if (this.error == null)
194 ChannelBuffer errorMsg = ChannelBuffers.wrappedBuffer(this.error);
196 throw new RuntimeException("MessageFactory not set");
198 List<OFMessage> msglist = this.factory.parseMessage(errorMsg);
201 return msglist.get(0);
205 * Write this offending message into the payload of the Error message
207 * @param offendingMsg
210 public void setOffendingMsg(OFMessage offendingMsg) {
211 if (offendingMsg == null) {
212 super.setLengthU(MINIMUM_LENGTH);
214 this.error = new byte[offendingMsg.getLengthU()];
215 ChannelBuffer data = ChannelBuffers.wrappedBuffer(this.error);
217 offendingMsg.writeTo(data);
218 super.setLengthU(MINIMUM_LENGTH + offendingMsg.getLengthU());
222 public OFMessageFactory getFactory() {
227 public void setMessageFactory(OFMessageFactory factory) {
228 this.factory = factory;
234 public byte[] getError() {
242 public void setError(byte[] error) {
247 * @return the errorIsAscii
249 public boolean isErrorIsAscii() {
254 * @param errorIsAscii
255 * the errorIsAscii to set
257 public void setErrorIsAscii(boolean errorIsAscii) {
258 this.errorIsAscii = errorIsAscii;
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;
276 public void writeTo(ChannelBuffer data) {
278 data.writeShort(errorType);
279 data.writeShort(errorCode);
281 data.writeBytes(error);
287 * @see java.lang.Object#hashCode()
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;
303 * @see java.lang.Object#equals(java.lang.Object)
306 public boolean equals(Object obj) {
309 if (!super.equals(obj))
311 if (getClass() != obj.getClass())
313 OFError other = (OFError) obj;
314 if (!Arrays.equals(error, other.error))
316 if (errorCode != other.errorCode)
318 if (errorIsAscii != other.errorIsAscii)
320 if (errorType != other.errorType)