2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

Add ability to direct "packet-in"s to particular controllers.

Nicira's controllers are somewhat heterogeneous, so that particular
"packet-in" messages should be directed to particular controllers.  This
new Nicira extension action allows designating a controller or controllers
to receive the "packet-in" using a 16-bit integer ID.

The new NXAST_CONTROLLER action also specifies the "reason" code to include
in the "packet-in" message.  This is particularly useful for simulating a
"no-match" "packet-in" using a rule.

Feature #8946.
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff
2012-02-09 14:17:33 -08:00
parent 7c1a76a467
commit a7349929fb
18 changed files with 254 additions and 23 deletions

View File

@@ -267,6 +267,48 @@ parse_fin_timeout(struct ofpbuf *b, char *arg)
}
}
static void
parse_controller(struct ofpbuf *b, char *arg)
{
enum ofp_packet_in_reason reason = OFPR_ACTION;
uint16_t controller_id = 0;
uint16_t max_len = UINT16_MAX;
if (!arg[0]) {
/* Use defaults. */
} else if (strspn(arg, "0123456789") == strlen(arg)) {
max_len = str_to_u16(arg, "max_len");
} else {
char *name, *value;
while (ofputil_parse_key_value(&arg, &name, &value)) {
if (!strcmp(name, "reason")) {
if (!ofputil_packet_in_reason_from_string(value, &reason)) {
ovs_fatal(0, "unknown reason \"%s\"", value);
}
} else if (!strcmp(name, "max_len")) {
max_len = str_to_u16(value, "max_len");
} else if (!strcmp(name, "id")) {
controller_id = str_to_u16(value, "id");
} else {
ovs_fatal(0, "unknown key \"%s\" parsing controller action",
name);
}
}
}
if (reason == OFPR_ACTION && controller_id == 0) {
put_output_action(b, OFPP_CONTROLLER)->max_len = htons(max_len);
} else {
struct nx_action_controller *nac;
nac = ofputil_put_NXAST_CONTROLLER(b);
nac->max_len = htons(max_len);
nac->reason = reason;
nac->controller_id = htons(controller_id);
}
}
static void
parse_named_action(enum ofputil_action_code code, const struct flow *flow,
struct ofpbuf *b, char *arg)
@@ -389,6 +431,10 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow,
case OFPUTIL_NXAST_FIN_TIMEOUT:
parse_fin_timeout(b, arg);
break;
case OFPUTIL_NXAST_CONTROLLER:
parse_controller(b, arg);
break;
}
}
@@ -418,17 +464,6 @@ str_to_action(const struct flow *flow, char *str, struct ofpbuf *b)
"actions");
}
break;
} else if (!strcasecmp(act, "CONTROLLER")) {
struct ofp_action_output *oao;
oao = put_output_action(b, OFPP_CONTROLLER);
/* Unless a numeric argument is specified, we send the whole
* packet to the controller. */
if (arg[0] && (strspn(arg, "0123456789") == strlen(arg))) {
oao->max_len = htons(str_to_u32(arg));
} else {
oao->max_len = htons(UINT16_MAX);
}
} else if (ofputil_port_from_string(act, &port)) {
put_output_action(b, port);
} else {