enum ofperr
ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
unsigned int instructions_len,
- uint8_t table_id,
struct ofpbuf *ofpacts)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
oigt = instruction_get_OFPIT11_GOTO_TABLE(
insts[OVSINST_OFPIT11_GOTO_TABLE]);
- if (table_id >= oigt->table_id) {
- error = OFPERR_OFPBRC_BAD_TABLE_ID;
- goto exit;
- }
ogt = ofpact_put_GOTO_TABLE(ofpacts);
ogt->table_id = oigt->table_id;
}
\f
/* May modify flow->dl_type, caller must restore it. */
static enum ofperr
-ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports)
+ofpact_check__(const struct ofpact *a, struct flow *flow, ofp_port_t max_ports,
+ uint8_t table_id)
{
const struct ofpact_enqueue *enqueue;
case OFPACT_CLEAR_ACTIONS:
case OFPACT_WRITE_METADATA:
- case OFPACT_GOTO_TABLE:
return 0;
case OFPACT_METER: {
}
return 0;
}
+
+ case OFPACT_GOTO_TABLE:
+ if (ofpact_get_GOTO_TABLE(a)->table_id <= table_id) {
+ return OFPERR_OFPBRC_BAD_TABLE_ID;
+ }
+ return 0;
+
default:
NOT_REACHED();
}
* May temporarily modify 'flow', but restores the changes before returning. */
enum ofperr
ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len,
- struct flow *flow, ofp_port_t max_ports)
+ struct flow *flow, ofp_port_t max_ports, uint8_t table_id)
{
const struct ofpact *a;
ovs_be16 dl_type = flow->dl_type;
enum ofperr error = 0;
OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
- error = ofpact_check__(a, flow, max_ports);
+ error = ofpact_check__(a, flow, max_ports, table_id);
if (error) {
break;
}