static enum ofperr
ofproto_check_ofpacts(struct ofproto *ofproto,
const struct ofpact ofpacts[], size_t ofpacts_len,
- struct flow *flow, uint8_t table_id)
+ struct flow *flow, uint8_t table_id,
+ bool enforce_consistency)
{
enum ofperr error;
uint32_t mid;
error = ofpacts_check(ofpacts, ofpacts_len, flow,
- u16_to_ofp(ofproto->max_ports), table_id);
+ u16_to_ofp(ofproto->max_ports), table_id,
+ enforce_consistency);
if (error) {
return error;
}
/* Verify actions against packet, then send packet if successful. */
in_port_.ofp_port = po.in_port;
flow_extract(payload, 0, 0, NULL, &in_port_, &flow);
- error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len, &flow, 0);
+ error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len, &flow, 0,
+ oh->version > OFP10_VERSION);
if (!error) {
error = p->ofproto_class->packet_out(p, payload, &flow,
po.ofpacts, po.ofpacts_len);
/* Verify actions. */
error = ofproto_check_ofpacts(ofproto, fm->ofpacts, fm->ofpacts_len,
- &fm->match.flow, table_id);
+ &fm->match.flow, table_id,
+ request && request->version > OFP10_VERSION);
if (error) {
cls_rule_destroy(&cr);
return error;
continue;
}
- /* Verify actions. */
+ /* Verify actions, enforce consistency check on OF1.1+. */
error = ofpacts_check(fm->ofpacts, fm->ofpacts_len, &fm->match.flow,
- u16_to_ofp(ofproto->max_ports), rule->table_id);
+ u16_to_ofp(ofproto->max_ports), rule->table_id,
+ request && request->version > OFP10_VERSION);
if (error) {
return error;
}
if (error) {
return error;
}
+ if (oh->version >= OFP13_VERSION && ofpmsg_is_stat_request(oh)
+ && ofpmp_more(oh)) {
+ /* We have no buffer implementation for multipart requests.
+ * Report overflow for requests which consists of multiple
+ * messages. */
+ return OFPERR_OFPBRC_MULTIPART_BUFFER_OVERFLOW;
+ }
switch (type) {
/* OpenFlow requests. */
/* FIXME: Change the following once they are implemented: */
case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
- return OFPERR_OFPBRC_BAD_TYPE;
+ /* fallthrough */
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_METER_FEATURES_STATS_REPLY:
case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
default:
- return OFPERR_OFPBRC_BAD_TYPE;
+ if (ofpmsg_is_stat_request(oh)) {
+ return OFPERR_OFPBRC_BAD_STAT;
+ } else {
+ return OFPERR_OFPBRC_BAD_TYPE;
+ }
}
}