for (i = 0; i < ids->n_controllers; i++) {
uint16_t id = ntohs(((ovs_be16 *)(nac_ids + 1))[i]);
ofpbuf_put(out, &id, sizeof id);
+ ids = out->l2;
}
- ids = out->l2;
ofpact_update_len(out, &ids->ofpact);
return 0;
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;
}
return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
case OFPACT_REG_LOAD:
- if (*dl_type != flow->dl_type) {
- struct flow updated_flow = *flow;
- updated_flow.dl_type = *dl_type;
- return nxm_reg_load_check(ofpact_get_REG_LOAD(a), &updated_flow);
- } else {
- return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
- }
+ return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
case OFPACT_STACK_PUSH:
return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow);
{
const struct ofpact *a;
ovs_be16 dl_type = flow->dl_type;
+ struct flow updated_flow;
OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
- enum ofperr error = ofpact_check__(a, flow, max_ports, &dl_type);
+ enum ofperr error;
+
+ /* If the dl_type was changed by an action then its new value
+ * should be present in the flow passed to ofpact_check__(). */
+ if (flow->dl_type != dl_type) {
+ /* Only copy flow at most once */
+ if (flow != &updated_flow) {
+ updated_flow = *flow;
+ flow = &updated_flow;
+ }
+ updated_flow.dl_type = dl_type;
+ }
+
+ error = ofpact_check__(a, flow, max_ports, &dl_type);
if (error) {
return error;
}
ds_put_cstr(s, "controller(");
if (reason != OFPR_ACTION) {
+ char reasonbuf[OFPUTIL_PACKET_IN_REASON_BUFSIZE];
+
ds_put_format(s, "reason=%s,",
- ofputil_packet_in_reason_to_string(reason));
+ ofputil_packet_in_reason_to_string(
+ reason, reasonbuf, sizeof reasonbuf));
}
if (controller->max_len != UINT16_MAX) {
ds_put_format(s, "max_len=%"PRIu16",", controller->max_len);