/* Followed by at least the first 64 bytes of the failed request. */
};
\f
+/* Specific Nicira extension error numbers.
+ *
+ * These are the "code" values used in nx_vendor_error. So far, the "type"
+ * values in nx_vendor_error are the same as those in ofp_error_msg. That is,
+ * at Nicira so far we've only needed additional vendor-specific 'code' values,
+ * so we're using the existing 'type' values to avoid having to invent new ones
+ * that duplicate the current ones' meanings. */
+
+/* Additional "code" values for OFPET_FLOW_MOD_FAILED. */
+enum {
+ /* Generic hardware error. */
+ NXFMFC_HARDWARE = 0x100,
+
+ /* A nonexistent table ID was specified in the "command" field of struct
+ * ofp_flow_mod, when the nxt_flow_mod_table_id extension is enabled. */
+ NXFMFC_BAD_TABLE_ID
+};
+\f
/* Nicira vendor requests and replies. */
enum nicira_type {
* are updated from 'put->idle_timeout' and 'put->hard_timeout',
* respectively.
*
- * Returns 0 if successful, otherwise a positive errno value. If
- * successful:
+ * If successful, returns 0 and:
*
* - If 'old_stats' is nonnull, then 'old_stats' is filled with the
* flow's stats as they existed just before the update, or it is zeroed
*
* - If 'rulep' is nonnull, then it is set to the newly created rule.
*
- * Some error return values have specific meanings:
+ * On failure, ordinarily returns an OpenFlow error code constructed with
+ * e.g. ofp_mkerr(), that will be reported to the controller. Some
+ * examples:
*
- * - ENOENT: Flow does not exist and WDP_PUT_CREATE not specified.
+ * - ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL): Flow
+ * table full.
*
- * - EEXIST: Flow exists and WDP_PUT_MODIFY not specified.
+ * - ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_OUT_PORT): Output to
+ * unsupported output port.
+ *
+ * - ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_UNSUPPORTED): The flow
+ * table supports the supplied actions but not in the supplied order or
+ * combination.
+ *
+ * - OpenFlow lacks appropriate error types and codes for many
+ * situations. Feel free to add a new error vendor extension to
+ * nicira-ext.h to handle these situations with your own vendor ID. If
+ * it is a reasonably generic error and you want to use the Nicira
+ * vendor ID instead of your own, please coordinate with
+ * dev@openvswitch.org.
*
- * - ENOBUFS: Flow table full.
+ * The following specific kinds of failures should instead be reported as
+ * errno values, for the caller to interpret, instead of the controller:
*
- * - EINVAL: Flow table cannot accept flow of this form.
+ * - ENOENT: Flow does not exist and WDP_PUT_CREATE not specified.
+ *
+ * - EEXIST: Flow exists and WDP_PUT_MODIFY not specified.
*/
int (*flow_put)(struct wdp *wdp, const struct wdp_flow_put *put,
struct wdp_flow_stats *old_stats,
struct wdp_rule **rulep);
- /* Deletes 'rule' from 'wdp'. Returns 0 if successful, otherwise a
- * positive errno value.
+ /* Deletes 'rule' from 'wdp'. Returns 0 if successful, otherwise an
+ * OpenFlow error code.
*
* If successful and 'final_stats' is non-null, stores the flow's
* statistics just before it is deleted into '*final_stats'. */
/* Performs the actions for 'rule' on the Ethernet frame specified in
* 'packet'. Pretends that the frame was originally received on the port
* numbered 'in_port'. Packets and bytes sent should be credited to
- * 'rule'. */
+ * 'rule'.
+ *
+ * Returns 0 if successful, otherwise an OpenFlow error code. */
int (*flow_inject)(struct wdp *wdp, struct wdp_rule *rule,
uint16_t in_port, const struct ofpbuf *packet);
ofp_table_id = put->flow->wildcards ? TABLEID_CLASSIFIER : TABLEID_HASH;
if (put->ofp_table_id != 0xff && put->ofp_table_id != ofp_table_id) {
- return EINVAL;
+ return ofp_mkerr_nicira(OFPET_FLOW_MOD_FAILED, NXFMFC_BAD_TABLE_ID);
}
rule = wx_rule_cast(classifier_find_rule_exactly(&wx->cls, put->flow));
? classifier_count_wild(&wx->cls) >= WX_MAX_WILD
: classifier_count_exact(&wx->cls) >= WX_MAX_EXACT)) {
/* XXX subrules should not count against exact-match limit */
- return ENOBUFS;
+ return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL);
}
}
if (error) {
return error;
}
- xfif_execute(wx->xfif, ofp_port_to_xflow_port(in_port),
- xflow_actions.actions, xflow_actions.n_actions, packet);
- return 0;
+ return xfif_execute(wx->xfif, ofp_port_to_xflow_port(in_port),
+ xflow_actions.actions, xflow_actions.n_actions,
+ packet);
}
static int