pin.packet_len = packet->size;
pin.total_len = packet->size;
pin.reason = OFPR_NO_MATCH;
+ pin.controller_id = 0;
pin.table_id = 0;
pin.cookie = 0;
static void
execute_controller_action(struct action_xlate_ctx *ctx, int len,
- enum ofp_packet_in_reason reason)
+ enum ofp_packet_in_reason reason,
+ uint16_t controller_id)
{
struct ofputil_packet_in pin;
struct ofpbuf *packet;
pin.packet = packet->data;
pin.packet_len = packet->size;
pin.reason = reason;
+ pin.controller_id = controller_id;
pin.table_id = ctx->table_id;
pin.cookie = ctx->rule ? ctx->rule->up.flow_cookie : 0;
ctx->flow.nw_ttl--;
return false;
} else {
- execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL);
+ execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL, 0);
/* Stop processing for current table. */
return true;
flood_packets(ctx, true);
break;
case OFPP_CONTROLLER:
- execute_controller_action(ctx, max_len, OFPR_ACTION);
+ execute_controller_action(ctx, max_len, OFPR_ACTION, 0);
break;
case OFPP_NONE:
break;
const struct nx_action_autopath *naa;
const struct nx_action_bundle *nab;
const struct nx_action_output_reg *naor;
+ const struct nx_action_controller *nac;
enum ofputil_action_code code;
ovs_be64 tun_id;
ctx->has_fin_timeout = true;
xlate_fin_timeout(ctx, (const struct nx_action_fin_timeout *) ia);
break;
+
+ case OFPUTIL_NXAST_CONTROLLER:
+ nac = (const struct nx_action_controller *) ia;
+ execute_controller_action(ctx, ntohs(nac->max_len), nac->reason,
+ ntohs(nac->controller_id));
+ break;
}
}
if (argc > 1) {
ofproto = ofproto_dpif_lookup(argv[1]);
if (!ofproto) {
- unixctl_command_reply(conn, 501, "no such bridge");
+ unixctl_command_reply_error(conn, "no such bridge");
return;
}
mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
}
}
- unixctl_command_reply(conn, 200, "table successfully flushed");
+ unixctl_command_reply(conn, "table successfully flushed");
}
static void
ofproto = ofproto_dpif_lookup(argv[1]);
if (!ofproto) {
- unixctl_command_reply(conn, 501, "no such bridge");
+ unixctl_command_reply_error(conn, "no such bridge");
return;
}
e->vlan, ETH_ADDR_ARGS(e->mac),
mac_entry_age(ofproto->ml, e));
}
- unixctl_command_reply(conn, 200, ds_cstr(&ds));
+ unixctl_command_reply(conn, ds_cstr(&ds));
ds_destroy(&ds);
}
ds_put_char(result, '\n');
}
+static void
+trace_format_odp(struct ds *result, int level, const char *title,
+ struct ofproto_trace *trace)
+{
+ struct ofpbuf *odp_actions = trace->ctx.odp_actions;
+
+ ds_put_char_multiple(result, '\t', level);
+ ds_put_format(result, "%s: ", title);
+ format_odp_actions(result, odp_actions->data, odp_actions->size);
+ ds_put_char(result, '\n');
+}
+
static void
trace_resubmit(struct action_xlate_ctx *ctx, struct rule_dpif *rule)
{
ds_put_char(result, '\n');
trace_format_flow(result, ctx->recurse + 1, "Resubmitted flow", trace);
trace_format_regs(result, ctx->recurse + 1, "Resubmitted regs", trace);
+ trace_format_odp(result, ctx->recurse + 1, "Resubmitted odp", trace);
trace_format_rule(result, ctx->table_id, ctx->recurse + 1, rule);
}
ofproto = ofproto_dpif_lookup(dpname);
if (!ofproto) {
- unixctl_command_reply(conn, 501, "Unknown ofproto (use ofproto/list "
- "for help)");
+ unixctl_command_reply_error(conn, "Unknown ofproto (use ofproto/list "
+ "for help)");
goto exit;
}
if (argc == 3 || (argc == 4 && !strcmp(argv[3], "-generate"))) {
ofpbuf_init(&odp_key, 0);
error = odp_flow_key_from_string(flow_s, NULL, &odp_key);
if (error) {
- unixctl_command_reply(conn, 501, "Bad flow syntax");
+ unixctl_command_reply_error(conn, "Bad flow syntax");
goto exit;
}
odp_key.size, &flow,
&initial_tci, NULL);
if (error == ODP_FIT_ERROR) {
- unixctl_command_reply(conn, 501, "Invalid flow");
+ unixctl_command_reply_error(conn, "Invalid flow");
goto exit;
}
msg = eth_from_hex(packet_s, &packet);
if (msg) {
- unixctl_command_reply(conn, 501, msg);
+ unixctl_command_reply_error(conn, msg);
goto exit;
}
flow_extract(packet, priority, tun_id, in_port, &flow);
initial_tci = flow.vlan_tci;
} else {
- unixctl_command_reply(conn, 501, "Bad command syntax");
+ unixctl_command_reply_error(conn, "Bad command syntax");
goto exit;
}
}
}
- unixctl_command_reply(conn, 200, ds_cstr(&result));
+ unixctl_command_reply(conn, ds_cstr(&result));
exit:
ds_destroy(&result);
const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
{
clogged = true;
- unixctl_command_reply(conn, 200, NULL);
+ unixctl_command_reply(conn, NULL);
}
static void
const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
{
clogged = false;
- unixctl_command_reply(conn, 200, NULL);
+ unixctl_command_reply(conn, NULL);
}
/* Runs a self-check of flow translations in 'ofproto'. Appends a message to
if (argc > 1) {
ofproto = ofproto_dpif_lookup(argv[1]);
if (!ofproto) {
- unixctl_command_reply(conn, 501, "Unknown ofproto (use "
- "ofproto/list for help)");
+ unixctl_command_reply_error(conn, "Unknown ofproto (use "
+ "ofproto/list for help)");
return;
}
ofproto_dpif_self_check__(ofproto, &reply);
}
}
- unixctl_command_reply(conn, 200, ds_cstr(&reply));
+ unixctl_command_reply(conn, ds_cstr(&reply));
ds_destroy(&reply);
}