/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "nx-match.h"
#include "ofp-util.h"
#include "ofpbuf.h"
+#include "util.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(ofp_actions);
static inline const struct STRUCT * \
instruction_get_##ENUM(const struct ofp11_instruction *inst)\
{ \
- assert(inst->type == htons(ENUM)); \
+ ovs_assert(inst->type == htons(ENUM)); \
return (struct STRUCT *)inst; \
} \
\
ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len)
{
const struct ofpact *a;
- const struct ofpact_metadata *om = NULL;
+ enum ovs_instruction_type inst;
+ inst = OVSINST_OFPIT11_APPLY_ACTIONS;
OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
- if (om) {
- if (a->type == OFPACT_WRITE_METADATA) {
- VLOG_WARN("duplicate write_metadata instruction specified");
- return OFPERR_OFPBAC_UNSUPPORTED_ORDER;
+ enum ovs_instruction_type next;
+
+ if (a->type == OFPACT_CLEAR_ACTIONS) {
+ next = OVSINST_OFPIT11_CLEAR_ACTIONS;
+ } else if (a->type == OFPACT_WRITE_METADATA) {
+ next = OVSINST_OFPIT11_WRITE_METADATA;
+ } else if (a->type == OFPACT_GOTO_TABLE) {
+ next = OVSINST_OFPIT11_GOTO_TABLE;
+ } else {
+ next = OVSINST_OFPIT11_APPLY_ACTIONS;
+ }
+
+ if (inst != OVSINST_OFPIT11_APPLY_ACTIONS && next <= inst) {
+ const char *name = ofpact_instruction_name_from_type(inst);
+ const char *next_name = ofpact_instruction_name_from_type(next);
+
+ if (next == inst) {
+ VLOG_WARN("duplicate %s instruction not allowed, for OpenFlow "
+ "1.1+ compatibility", name);
} else {
- VLOG_WARN("write_metadata instruction must be specified after "
- "other instructions/actions");
- return OFPERR_OFPBAC_UNSUPPORTED_ORDER;
+ VLOG_WARN("invalid instruction ordering: %s must appear "
+ "before %s, for OpenFlow 1.1+ compatibility",
+ next_name, name);
}
+ return OFPERR_OFPBAC_UNSUPPORTED_ORDER;
}
- if (a->type == OFPACT_WRITE_METADATA) {
- om = (const struct ofpact_metadata *) a;
- }
+ inst = next;
}
return 0;
void
ofpact_update_len(struct ofpbuf *ofpacts, struct ofpact *ofpact)
{
- assert(ofpact == ofpacts->l2);
+ ovs_assert(ofpact == ofpacts->l2);
ofpact->len = (char *) ofpbuf_tail(ofpacts) - (char *) ofpact;
}