Introduce ofputil_protocol, to abstract the protocol in use on a connection.
[sliver-openvswitch.git] / ofproto / ofproto.c
index 92744a2..25303ad 100644 (file)
@@ -2981,8 +2981,7 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh)
         return error;
     }
 
-    error = ofputil_decode_flow_mod(&fm, oh,
-                                    ofconn_get_flow_mod_table_id(ofconn));
+    error = ofputil_decode_flow_mod(&fm, oh, ofconn_get_protocol(ofconn));
     if (error) {
         return error;
     }
@@ -3067,8 +3066,12 @@ handle_nxt_flow_mod_table_id(struct ofconn *ofconn,
 {
     const struct nx_flow_mod_table_id *msg
         = (const struct nx_flow_mod_table_id *) oh;
+    enum ofputil_protocol cur, next;
+
+    cur = ofconn_get_protocol(ofconn);
+    next = ofputil_protocol_set_tid(cur, msg->set != 0);
+    ofconn_set_protocol(ofconn, next);
 
-    ofconn_set_flow_mod_table_id(ofconn, msg->set != 0);
     return 0;
 }
 
@@ -3077,20 +3080,22 @@ handle_nxt_set_flow_format(struct ofconn *ofconn, const struct ofp_header *oh)
 {
     const struct nx_set_flow_format *msg
         = (const struct nx_set_flow_format *) oh;
-    uint32_t format;
+    enum ofputil_protocol cur, next;
+    enum ofputil_protocol next_base;
 
-    format = ntohl(msg->format);
-    if (format != NXFF_OPENFLOW10 && format != NXFF_NXM) {
+    next_base = ofputil_nx_flow_format_to_protocol(ntohl(msg->format));
+    if (!next_base) {
         return OFPERR_OFPBRC_EPERM;
     }
 
-    if (format != ofconn_get_flow_format(ofconn)
-        && ofconn_has_pending_opgroups(ofconn)) {
-        /* Avoid sending async messages in surprising flow format. */
+    cur = ofconn_get_protocol(ofconn);
+    next = ofputil_protocol_set_base(cur, next_base);
+    if (cur != next && ofconn_has_pending_opgroups(ofconn)) {
+        /* Avoid sending async messages in surprising protocol. */
         return OFPROTO_POSTPONE;
     }
 
-    ofconn_set_flow_format(ofconn, format);
+    ofconn_set_protocol(ofconn, next);
     return 0;
 }
 
@@ -3117,6 +3122,41 @@ handle_nxt_set_packet_in_format(struct ofconn *ofconn,
     return 0;
 }
 
+static enum ofperr
+handle_nxt_set_async_config(struct ofconn *ofconn, const struct ofp_header *oh)
+{
+    const struct nx_async_config *msg = (const struct nx_async_config *) oh;
+    uint32_t master[OAM_N_TYPES];
+    uint32_t slave[OAM_N_TYPES];
+
+    master[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[0]);
+    master[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[0]);
+    master[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[0]);
+
+    slave[OAM_PACKET_IN] = ntohl(msg->packet_in_mask[1]);
+    slave[OAM_PORT_STATUS] = ntohl(msg->port_status_mask[1]);
+    slave[OAM_FLOW_REMOVED] = ntohl(msg->flow_removed_mask[1]);
+
+    ofconn_set_async_config(ofconn, master, slave);
+
+    return 0;
+}
+
+static enum ofperr
+handle_nxt_set_controller_id(struct ofconn *ofconn,
+                             const struct ofp_header *oh)
+{
+    const struct nx_controller_id *nci;
+
+    nci = (const struct nx_controller_id *) oh;
+    if (!is_all_zeros(nci->zero, sizeof nci->zero)) {
+        return OFPERR_NXBRC_MUST_BE_ZERO;
+    }
+
+    ofconn_set_controller_id(ofconn, ntohs(nci->controller_id));
+    return 0;
+}
+
 static enum ofperr
 handle_barrier_request(struct ofconn *ofconn, const struct ofp_header *oh)
 {
@@ -3187,6 +3227,9 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
     case OFPUTIL_NXT_SET_PACKET_IN_FORMAT:
         return handle_nxt_set_packet_in_format(ofconn, oh);
 
+    case OFPUTIL_NXT_SET_CONTROLLER_ID:
+        return handle_nxt_set_controller_id(ofconn, oh);
+
     case OFPUTIL_NXT_FLOW_MOD:
         return handle_flow_mod(ofconn, oh);
 
@@ -3194,6 +3237,9 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
         /* Nothing to do. */
         return 0;
 
+    case OFPUTIL_NXT_SET_ASYNC_CONFIG:
+        return handle_nxt_set_async_config(ofconn, oh);
+
         /* Statistics requests. */
     case OFPUTIL_OFPST_DESC_REQUEST:
         return handle_desc_stats_request(ofconn, msg->data);
@@ -3942,7 +3988,7 @@ ofproto_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
     HMAP_FOR_EACH (ofproto, hmap_node, &all_ofprotos) {
         ds_put_format(&results, "%s\n", ofproto->name);
     }
-    unixctl_command_reply(conn, 200, ds_cstr(&results));
+    unixctl_command_reply(conn, ds_cstr(&results));
     ds_destroy(&results);
 }