hash_string(ofproto->name, 0));
ofproto->datapath_id = 0;
ofproto_set_flow_eviction_threshold(ofproto,
- OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT);
+ OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT);
ofproto->forward_bpdu = false;
ofproto->fallback_dpid = pick_fallback_dpid();
ofproto->mfr_desc = xstrdup(DEFAULT_MFR_DESC);
put_queue_stats(struct queue_stats_cbdata *cbdata, uint32_t queue_id,
const struct netdev_queue_stats *stats)
{
- struct ofp10_queue_stats *reply;
- reply = ofpmp_append(&cbdata->replies, sizeof *reply);
- reply->port_no = htons(cbdata->ofport->pp.port_no);
- memset(reply->pad, 0, sizeof reply->pad);
- reply->queue_id = htonl(queue_id);
- put_32aligned_be64(&reply->tx_bytes, htonll(stats->tx_bytes));
- put_32aligned_be64(&reply->tx_packets, htonll(stats->tx_packets));
- put_32aligned_be64(&reply->tx_errors, htonll(stats->tx_errors));
+ struct ofputil_queue_stats oqs = {
+ .port_no = cbdata->ofport->pp.port_no,
+ .queue_id = queue_id,
+ .stats = *stats,
+ };
+ ofputil_append_queue_stat(&cbdata->replies, &oqs);
}
static void
const struct ofp_header *rq)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
- const struct ofp10_queue_stats_request *qsr = ofpmsg_body(rq);
struct queue_stats_cbdata cbdata;
- unsigned int port_no;
struct ofport *port;
- uint32_t queue_id;
enum ofperr error;
+ struct ofputil_queue_stats_request oqsr;
COVERAGE_INC(ofproto_queue_req);
ofpmp_init(&cbdata.replies, rq);
- port_no = ntohs(qsr->port_no);
- queue_id = ntohl(qsr->queue_id);
- if (port_no == OFPP_ALL) {
+ error = ofputil_decode_queue_stats_request(rq, &oqsr);
+ if (error) {
+ return error;
+ }
+
+ if (oqsr.port_no == OFPP_ALL) {
error = OFPERR_OFPQOFC_BAD_QUEUE;
HMAP_FOR_EACH (port, hmap_node, &ofproto->ports) {
- if (!handle_queue_stats_for_port(port, queue_id, &cbdata)) {
+ if (!handle_queue_stats_for_port(port, oqsr.queue_id, &cbdata)) {
error = 0;
}
}
} else {
- port = ofproto_get_port(ofproto, port_no);
+ port = ofproto_get_port(ofproto, oqsr.port_no);
error = (port
- ? handle_queue_stats_for_port(port, queue_id, &cbdata)
+ ? handle_queue_stats_for_port(port, oqsr.queue_id, &cbdata)
: OFPERR_OFPQOFC_BAD_PORT);
}
if (!error) {
rule->evictable = was_evictable;
if (!evict) {
- error = OFPERR_OFPFMFC_ALL_TABLES_FULL;
+ error = OFPERR_OFPFMFC_TABLE_FULL;
goto exit;
} else if (evict->pending) {
error = OFPROTO_POSTPONE;
return error;
}
+static enum ofperr
+modify_flows_add(struct ofproto *ofproto, struct ofconn *ofconn,
+ const struct ofputil_flow_mod *fm,
+ const struct ofp_header *request)
+{
+ if (fm->cookie_mask != htonll(0) || fm->new_cookie == htonll(UINT64_MAX)) {
+ return 0;
+ }
+ return add_flow(ofproto, ofconn, fm, request);
+}
+
/* Implements OFPFC_MODIFY. Returns 0 on success or an OpenFlow error code on
* failure.
*
if (error) {
return error;
} else if (list_is_empty(&rules)) {
- return fm->cookie_mask ? 0 : add_flow(ofproto, ofconn, fm, request);
+ return modify_flows_add(ofproto, ofconn, fm, request);
} else {
return modify_flows__(ofproto, ofconn, fm, request, &rules);
}
if (error) {
return error;
} else if (list_is_empty(&rules)) {
- return fm->cookie_mask ? 0 : add_flow(ofproto, ofconn, fm, request);
+ return modify_flows_add(ofproto, ofconn, fm, request);
} else {
return list_is_singleton(&rules) ? modify_flows__(ofproto, ofconn,
fm, request, &rules)
* is not required in OpenFlow 1.0.1 and removed from OpenFlow 1.1.
* There is no good error code, so just state that the flow table
* is full. */
- error = OFPERR_OFPFMFC_ALL_TABLES_FULL;
+ error = OFPERR_OFPFMFC_TABLE_FULL;
}
if (!error) {
error = ofpacts_check(fm.ofpacts, fm.ofpacts_len,