X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=91a39efe9a90814f0afa0eec1fe5aa5ccb11e149;hb=a72687af3a2ab1600ca9e87c00d4e7d138ecdc1a;hp=402b38d01c829f9b272e6e1854074734e3dbfcce;hpb=8621547cc94ad91018ac0b662427a6fa20165a8d;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 402b38d01..91a39efe9 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2824,14 +2824,14 @@ static enum ofperr ofproto_check_ofpacts(struct ofproto *ofproto, const struct ofpact ofpacts[], size_t ofpacts_len, struct flow *flow, uint8_t table_id, - bool enforce_consistency) + const struct ofp_header *oh) { enum ofperr error; uint32_t mid; error = ofpacts_check(ofpacts, ofpacts_len, flow, u16_to_ofp(ofproto->max_ports), table_id, - enforce_consistency); + oh && oh->version > OFP10_VERSION); if (error) { return error; } @@ -2889,8 +2889,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh) /* 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, - oh->version > OFP10_VERSION); + error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len, &flow, 0, oh); if (!error) { error = p->ofproto_class->packet_out(p, payload, &flow, po.ofpacts, po.ofpacts_len); @@ -3940,8 +3939,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, /* Verify actions. */ error = ofproto_check_ofpacts(ofproto, fm->ofpacts, fm->ofpacts_len, - &fm->match.flow, table_id, - request && request->version > OFP10_VERSION); + &fm->match.flow, table_id, request); if (error) { cls_rule_destroy(&cr); return error; @@ -4045,6 +4043,19 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn, enum ofperr error; size_t i; + /* Verify actions before we start to modify any rules, to avoid partial + * flow table modifications. */ + for (i = 0; i < rules->n; i++) { + struct rule *rule = rules->rules[i]; + + error = ofproto_check_ofpacts(ofproto, fm->ofpacts, fm->ofpacts_len, + &fm->match.flow, rule->table_id, + request); + if (error) { + return error; + } + } + type = fm->command == OFPFC_ADD ? OFOPERATION_REPLACE : OFOPERATION_MODIFY; group = ofopgroup_create(ofproto, ofconn, request, fm->buffer_id); error = OFPERR_OFPBRC_EPERM; @@ -4063,14 +4074,6 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn, continue; } - /* 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, - request && request->version > OFP10_VERSION); - if (error) { - return error; - } - actions_changed = !ofpacts_equal(fm->ofpacts, fm->ofpacts_len, rule->actions->ofpacts, rule->actions->ofpacts_len); @@ -5677,6 +5680,13 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) 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. */ @@ -5790,7 +5800,7 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) /* 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: @@ -5821,7 +5831,11 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg) 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; + } } }