ofp-util: Allow encoding Open Flow 1.2 Flow Stats Request Messages
[sliver-openvswitch.git] / lib / ofp-util.c
index 64eb5ca..2e52d53 100644 (file)
@@ -1482,6 +1482,23 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
     enum ofpraw raw;
 
     switch (protocol) {
+    case OFPUTIL_P_OF12: {
+        struct ofp11_flow_stats_request *ofsr;
+
+        raw = (fsr->aggregate
+               ? OFPRAW_OFPST_AGGREGATE_REQUEST
+               : OFPRAW_OFPST_FLOW_REQUEST);
+        msg = ofpraw_alloc(raw, OFP12_VERSION, NXM_TYPICAL_LEN);
+        ofsr = ofpbuf_put_zeros(msg, sizeof *ofsr);
+        ofsr->table_id = fsr->table_id;
+        ofsr->out_port = ofputil_port_to_ofp11(fsr->out_port);
+        ofsr->out_group = htonl(OFPG11_ANY);
+        ofsr->cookie = fsr->cookie;
+        ofsr->cookie_mask = fsr->cookie_mask;
+        oxm_put_match(msg, &fsr->match);
+        break;
+    }
+
     case OFPUTIL_P_OF10:
     case OFPUTIL_P_OF10_TID: {
         struct ofp10_flow_stats_request *ofsr;
@@ -1505,7 +1522,7 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
         raw = (fsr->aggregate
                ? OFPRAW_NXST_AGGREGATE_REQUEST
                : OFPRAW_NXST_FLOW_REQUEST);
-        msg = ofpraw_alloc(raw, OFP10_VERSION, 0);
+        msg = ofpraw_alloc(raw, OFP10_VERSION, NXM_TYPICAL_LEN);
         ofpbuf_put_zeros(msg, sizeof *nfsr);
         match_len = nx_put_match(msg, &fsr->match,
                                  fsr->cookie, fsr->cookie_mask);
@@ -1517,7 +1534,6 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
         break;
     }
 
-    case OFPUTIL_P_OF12:
     default:
         NOT_REACHED();
     }
@@ -1861,6 +1877,26 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
     struct ofpbuf *msg;
 
     switch (protocol) {
+    case OFPUTIL_P_OF12: {
+        struct ofp12_flow_removed *ofr;
+
+        msg = ofpraw_alloc_xid(OFPRAW_OFPT11_FLOW_REMOVED,
+                               ofputil_protocol_to_ofp_version(protocol),
+                               htonl(0), NXM_TYPICAL_LEN);
+        ofr = ofpbuf_put_zeros(msg, sizeof *ofr);
+        ofr->cookie = fr->cookie;
+        ofr->priority = htons(fr->rule.priority);
+        ofr->reason = fr->reason;
+        ofr->table_id = 0;
+        ofr->duration_sec = htonl(fr->duration_sec);
+        ofr->duration_nsec = htonl(fr->duration_nsec);
+        ofr->idle_timeout = htons(fr->idle_timeout);
+        ofr->packet_count = htonll(fr->packet_count);
+        ofr->byte_count = htonll(fr->byte_count);
+        oxm_put_match(msg, &fr->rule);
+        break;
+    }
+
     case OFPUTIL_P_OF10:
     case OFPUTIL_P_OF10_TID: {
         struct ofp_flow_removed *ofr;
@@ -1903,7 +1939,6 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
         break;
     }
 
-    case OFPUTIL_P_OF12:
     default:
         NOT_REACHED();
     }
@@ -2149,13 +2184,31 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
                           const struct ofp_header *oh,
                           struct ofpbuf *ofpacts)
 {
+    enum ofperr bad_in_port_err;
     enum ofpraw raw;
     struct ofpbuf b;
 
     ofpbuf_use_const(&b, oh, ntohs(oh->length));
     raw = ofpraw_pull_assert(&b);
 
-    if (raw == OFPRAW_OFPT10_PACKET_OUT) {
+    if (raw == OFPRAW_OFPT11_PACKET_OUT) {
+        enum ofperr error;
+        const struct ofp11_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
+
+        po->buffer_id = ntohl(opo->buffer_id);
+        error = ofputil_port_from_ofp11(opo->in_port, &po->in_port);
+        if (error) {
+            return error;
+        }
+
+        error = ofpacts_pull_openflow11_actions(&b, ntohs(opo->actions_len),
+                                                ofpacts);
+        if (error) {
+            return error;
+        }
+
+        bad_in_port_err = OFPERR_OFPBMC_BAD_VALUE;
+    } else if (raw == OFPRAW_OFPT10_PACKET_OUT) {
         enum ofperr error;
         const struct ofp_packet_out *opo = ofpbuf_pull(&b, sizeof *opo);
 
@@ -2166,6 +2219,8 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
         if (error) {
             return error;
         }
+
+        bad_in_port_err = OFPERR_NXBRC_BAD_IN_PORT;
     } else {
         NOT_REACHED();
     }
@@ -2174,7 +2229,7 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
         && po->in_port != OFPP_NONE && po->in_port != OFPP_CONTROLLER) {
         VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out has bad input port %#"PRIx16,
                      po->in_port);
-        return OFPERR_NXBRC_BAD_IN_PORT;
+        return bad_in_port_err;
     }
 
     po->ofpacts = ofpacts->data;