1 package org.openflow.codec.protocol;
3 import java.util.Arrays;
6 import org.openflow.codec.io.IDataBuffer;
7 import org.openflow.codec.protocol.factory.OFPMessageFactory;
8 import org.openflow.codec.protocol.factory.OFPMessageFactoryAware;
9 import org.openflow.codec.util.U16;
12 * Represents an ofp_error_msg and also ofp_error_experimenter_msg
14 * @author David Erickson (daviderickson@cs.stanford.edu)
15 * @author Rob Sherwood (rob.sherwood@stanford.edu)
17 public class OFPErrorMsg extends OFPMessage implements OFPMessageFactoryAware
19 private static int MINIMUM_LENGTH = 12;
20 private static int EXP_MINIMUM_LENGTH = 16;
22 // correspond to enum ofp_hello_failed_code
23 public enum OFPHelloFailedCode
25 OFPHFC_INCOMPATIBLE, OFPHFC_EPERM
28 // correspond to enum ofp_bad_request_code
29 public enum OFPBadRequestCode
31 OFPBRC_BAD_VERSION, OFPBRC_BAD_TYPE, OFPBRC_BAD_MULTIPART, OFPBRC_BAD_EXPERIMENTER, OFPBRC_BAD_EXP_TYPE, OFPBRC_EPERM, OFPBRC_BAD_LEN, OFPBRC_BUFFER_EMPTY, OFPBRC_BUFFER_UNKNOWN, OFPBRC_BAD_TABLE_ID, OFPBRC_IS_SLAVE, OFPBRC_BAD_PORT, OFPBRC_BAD_PACKET, OFPBRC_MULTIPART_BUFFER_OVERFLOW
34 // correspond to enum ofp_bad_action_code
35 public enum OFPBadActionCode
37 OFPBAC_BAD_TYPE, OFPBAC_BAD_LEN, OFPBAC_BAD_EXPERIMENTER, OFPBAC_BAD_EXP_TYPE, OFPBAC_BAD_OUT_PORT, OFPBAC_BAD_ARGUMENT, OFPBAC_EPERM, OFPBAC_TOO_MANY, OFPBAC_BAD_QUEUE, OFPBAC_BAD_OUT_GROUP, OFPBAC_MATCH_INCONSISTENT, OFPBAC_UNSUPPORTED_ORDER, OFPBAC_BAD_TAG, OFPBAC_BAD_SET_TYPE, OFPBAC_BAD_SET_LEN, OFPBAC_BAD_SET_ARGUMENT
40 // correspond to enum ofp_bad_instruction_code
41 public enum OFPBadInstructionCode
43 OFPBIC_UNKNOWN_INST, OFPBIC_UNSUP_INST, OFPBIC_BAD_TABLE_ID, OFPBIC_UNSUP_METADATA, OFPBIC_UNSUP_METADATA_MASK, OFPBIC_BAD_EXPERIMENTER, OFPBIC_BAD_EXP_TYPE, OFPBIC_BAD_LEN, OFPBIC_EPERM
46 // correspond to enum ofp_bad_match_code
47 public enum OFPBadMatchCode
49 OFPBMC_BAD_TYPE, OFPBMC_BAD_LEN, OFPBMC_BAD_TAG, OFPBMC_BAD_DL_ADDR_MASK, OFPBMC_BAD_NW_ADDR_MASK, OFPBMC_BAD_WILDCARDS, OFPBMC_BAD_FIELD, OFPBMC_BAD_VALUE, OFPBMC_BAD_MASK, OFPBMC_BAD_PREREQ, OFPBMC_DUP_FIELD, OFPBMC_EPERM
53 // correspond to enum ofp_flow_mod_failed_code
54 public enum OFPFlowModFailedCode
56 OFPFMFC_UNKNOWN, OFPFMFC_TABLE_FULL, OFPFMFC_BAD_TABLE_ID, OFPFMFC_OVERLAP, OFPFMFC_EPERM, OFPFMFC_BAD_TIMEOUT, OFPFMFC_BAD_COMMAND, OFPFMFC_BAD_FLAGS
59 // correspond to enum ofp_group_mod_failed_code
60 public enum OFPGroupModFailedCode
62 OFPGMFC_GROUP_EXISTS, OFPGMFC_INVALID_GROUP, OFPGMFC_WEIGHT_UNSUPPORTED, OFPGMFC_OUT_OF_GROUPS, OFPGMFC_OUT_OF_BUCKETS, OFPGMFC_CHAINING_UNSUPPORTED, OFPGMFC_WATCH_UNSUPPORTED, OFPGMFC_LOOP, OFPGMFC_UNKNOWN_GROUP, OFPGMFC_CHAINED_GROUP, OFPGMFC_BAD_TYPE, OFPGMFC_BAD_COMMAND, OFPGMFC_BAD_BUCKET, OFPGMFC_BAD_WATCH, OFPGMFC_EPERM
65 // correspond to enum ofp_port_mod_failed_code
66 public enum OFPPortModFailedCode
68 OFPPMFC_BAD_PORT, OFPPMFC_BAD_HW_ADDR, OFPPMFC_BAD_CONFIG, OFPPMFC_BAD_ADVERTISE, OFPPMFC_EPERM
71 // correspond to enum ofp_table_mod_failed_code
72 public enum OFPTableModFailedCode
74 OFPTMFC_BAD_TABLE, OFPTMFC_BAD_CONFIG, OFPTMFC_EPERM
77 // correspond to enum ofp_queue_op_failed_code
78 public enum OFPQueueOpFailedCode
80 OFPQOFC_BAD_PORT, OFPQOFC_BAD_QUEUE, OFPQOFC_EPERM
83 // correspond to enum ofp_switch_config_failed_code
84 public enum OFPSwitchConfigFailedCode
86 OFPSCFC_BAD_FLAGS, OFPSCFC_BAD_LEN, OFPSCFC_EPERM
89 // correspond to enum ofp_role_request_failed_code
90 public enum OFPRoleRequestFailedCode
92 OFPRRFC_STALE, OFPRRFC_UNSUP, OFPRRFC_BAD_ROLE
95 // correspond to enum ofp_meter_mod_failed_code
96 public enum OFPMeterModFailedCode
98 OFPMMFC_UNKNOWN, OFPMMFC_METER_EXISTS, OFPMMFC_INVALID_METER, OFPMMFC_UNKNOWN_METER, OFPMMFC_BAD_COMMAND, OFPMMFC_BAD_FLAGS, OFPMMFC_BAD_RATE, OFPMMFC_BAD_BURST, OFPMMFC_BAD_BAND, OFPMMFC_BAD_BAND_VALUE, OFPMMFC_OUT_OF_METERS, OFPMMFC_OUT_OF_BANDS
102 // correspond to enum ofp_table_features_failed_code
103 public enum OFPTableFeaturesFailedCode
105 OFPTFFC_BAD_TABLE, OFPTFFC_BAD_METADATA, OFPTFFC_BAD_TYPE, OFPTFFC_BAD_LEN, OFPTFFC_BAD_ARGUMENT, OFPTFFC_EPERM
108 private OFPErrorType errorType;
109 private short errorCode;
110 private byte[] errorData;
111 private short expType;
112 private int experimenter;
115 private OFPMessageFactory factory;
116 private boolean errorIsAscii;
121 this.type = OFPType.ERROR;
122 this.length = U16.t(MINIMUM_LENGTH);
126 * @return the errorType
128 public OFPErrorType getErrorType()
135 * the errorType to set
137 public void setErrorType(OFPErrorType type)
139 this.errorType = type;
143 * @return the errorCode
145 public short getErrorCode()
150 public void setErrorCode(short errorCode)
152 this.errorCode = errorCode;
157 * the errorCode to set
159 public void setErrorCode(OFPHelloFailedCode code)
161 this.errorCode = (short) code.ordinal();
164 public void setErrorCode(OFPBadRequestCode code)
166 this.errorCode = (short) code.ordinal();
169 public void setErrorCode(OFPBadActionCode code)
171 this.errorCode = (short) code.ordinal();
174 public void setErrorCode(OFPFlowModFailedCode code)
176 this.errorCode = (short) code.ordinal();
179 public void setErrorCode(OFPPortModFailedCode code)
181 this.errorCode = (short) code.ordinal();
184 public void setErrorCode(OFPQueueOpFailedCode code)
186 this.errorCode = (short) code.ordinal();
189 public void setErrorCode(OFPBadInstructionCode code)
191 this.errorCode = (short) code.ordinal();
194 public void setErrorCode(OFPBadMatchCode code)
196 this.errorCode = (short) code.ordinal();
199 public void setErrorCode(OFPGroupModFailedCode code)
201 this.errorCode = (short) code.ordinal();
204 public void setErrorCode(OFPTableModFailedCode code)
206 this.errorCode = (short) code.ordinal();
209 public void setErrorCode(OFPSwitchConfigFailedCode code)
211 this.errorCode = (short) code.ordinal();
214 public void setErrorCode(OFPRoleRequestFailedCode code)
216 this.errorCode = (short) code.ordinal();
219 public void setErrorCode(OFPMeterModFailedCode code)
221 this.errorCode = (short) code.ordinal();
224 public void setErrorCode(OFPTableFeaturesFailedCode code)
226 this.errorCode = (short) code.ordinal();
229 public OFPMessage getOffendingMsg(IDataBuffer data)
231 // should only have one message embedded; if more than one, just
233 if (this.errorData == null)
235 IDataBuffer errorMsg = data.wrap(this.errorData);
237 throw new RuntimeException("MessageFactory not set");
238 List<OFPMessage> messages = this.factory.parseMessages(errorMsg,
240 // OVS apparently sends partial messages in errors
241 // need to be careful of that AND can't use data.limit() as
242 // a packet boundary because there could be more data queued
243 if (messages.size() > 0)
244 return messages.get(0);
250 * Write this offending message into the payload of the Error message
252 * @param offendingMsg
255 public void setOffendingMsg(OFPMessage offendingMsg, IDataBuffer buffer)
257 int minlength = MINIMUM_LENGTH;
258 if (OFPErrorType.OFPET_EXPERIMENTER.getValue() == this.errorType
261 minlength = EXP_MINIMUM_LENGTH;
264 if (offendingMsg == null)
266 super.setLengthU(minlength);
269 this.errorData = new byte[offendingMsg.getLengthU()];
270 IDataBuffer data = buffer.wrap(errorData);
271 offendingMsg.writeTo(data);
272 super.setLengthU(minlength + offendingMsg.getLengthU());
276 public OFPMessageFactory getFactory()
282 public void setMessageFactory(OFPMessageFactory factory)
284 this.factory = factory;
290 public byte[] getErrorData()
299 public void setErrorData(byte[] error)
301 this.errorData = error;
305 * @return the errorIsAscii
307 public boolean isErrorIsAscii()
313 * @param errorIsAscii
314 * the errorIsAscii to set
316 public void setErrorIsAscii(boolean errorIsAscii)
318 this.errorIsAscii = errorIsAscii;
322 public void readFrom(IDataBuffer data)
324 super.readFrom(data);
325 this.errorType = OFPErrorType.valueOf(data.getShort());
326 if (this.errorType.getValue() == OFPErrorType.OFPET_EXPERIMENTER
329 this.expType = data.getShort();
330 this.experimenter = data.getInt();
331 int dataLength = this.getLengthU() - EXP_MINIMUM_LENGTH;
334 this.errorData = new byte[dataLength];
335 data.get(this.errorData);
340 this.errorCode = data.getShort();
341 int dataLength = this.getLengthU() - MINIMUM_LENGTH;
344 this.errorData = new byte[dataLength];
345 data.get(this.errorData);
346 if (this.errorType.getValue() == OFPErrorType.OFPET_HELLO_FAILED
348 this.errorIsAscii = true;
354 public void writeTo(IDataBuffer data)
356 if (this.errorType.getValue() == OFPErrorType.OFPET_EXPERIMENTER
359 this.length = U16.t(EXP_MINIMUM_LENGTH);
362 data.putShort(errorType.getValue());
363 if (this.errorType.getValue() == OFPErrorType.OFPET_EXPERIMENTER
366 data.putShort(expType);
367 data.putInt(experimenter);
370 data.putShort(errorCode);
372 if (errorData != null)
379 * @see java.lang.Object#hashCode()
382 public int hashCode()
384 final int prime = 31;
385 int result = super.hashCode();
386 result = prime * result + Arrays.hashCode(errorData);
387 result = prime * result + errorCode;
388 result = prime * result + (errorIsAscii ? 1231 : 1237);
389 result = prime * result + errorType.getValue();
390 result = prime * result + expType;
391 result = prime * result + experimenter;
398 * @see java.lang.Object#equals(java.lang.Object)
401 public boolean equals(Object obj)
405 if (!super.equals(obj))
407 if (getClass() != obj.getClass())
409 OFPErrorMsg other = (OFPErrorMsg) obj;
410 if (!Arrays.equals(errorData, other.errorData))
412 if (errorCode != other.errorCode)
414 if (errorIsAscii != other.errorIsAscii)
416 if (errorType != other.errorType)
418 if (expType != other.expType)
420 if (experimenter != other.experimenter)
426 * get experimenter type
430 public short getExpType()
436 * set experimenter type
440 public void setExpType(short expType)
442 this.expType = expType;
446 * get experimenter Id
450 public int getExperimenter()
456 * set experimenter id
458 * @param experimenter
460 public void setExperimenter(int experimenter)
462 this.experimenter = experimenter;