/* Act. */
error = chain_insert(chain, flow);
- if (error)
+ if (error == -ENOBUFS) {
+ dp_send_error_msg(chain->dp, sender, OFPET_FLOW_MOD_FAILED,
+ OFPFMFC_ALL_TABLES_FULL, ofm, ntohs(ofm->header.length));
+ goto error_free_flow;
+ } else if (error)
goto error_free_flow;
error = 0;
if (ntohl(ofm->buffer_id) != (uint32_t) -1) {
enum ofp_error_type {
OFPET_HELLO_FAILED, /* Hello protocol failed. */
OFPET_BAD_REQUEST, /* Request was not understood. */
- OFPET_BAD_ACTION /* Error in action description. */
+ OFPET_BAD_ACTION, /* Error in action description. */
+ OFPET_FLOW_MOD_FAILED /* Problem modifying flow entry. */
};
/* ofp_error_msg 'code' values for OFPET_HELLO_FAILED. 'data' contains an
OFPBAC_BAD_ARGUMENT /* Bad action argument. */
};
+/* ofp_error_msg 'code' values for OFPET_FLOW_MOD_FAILED. 'data' contains
+ * at least the first 64 bytes of the failed request. */
+enum ofp_flow_mod_failed_code {
+ OFPFMFC_ALL_TABLES_FULL /* Flow not added because of full tables. */
+};
+
/* OFPT_ERROR: Error message (datapath -> controller). */
struct ofp_error_msg {
struct ofp_header header;
ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR),
ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_VENDOR_TYPE),
ERROR_CODE(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT),
+
+ ERROR_TYPE(OFPET_FLOW_MOD_FAILED),
+ ERROR_CODE(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL)
};
#define N_ERROR_TYPES ARRAY_SIZE(error_types)
/* Act. */
error = chain_insert(dp->chain, flow);
- if (error) {
+ if (error == -ENOBUFS) {
+ dp_send_error_msg(dp, sender, OFPET_FLOW_MOD_FAILED,
+ OFPFMFC_ALL_TABLES_FULL, ofm, ntohs(ofm->header.length));
+ goto error_free_flow;
+ } else if (error) {
goto error_free_flow;
}
error = 0;