netdev: Abstract "features" interface away from OpenFlow 1.0.
[sliver-openvswitch.git] / ofproto / ofproto.c
index ce36d95..0d10691 100644 (file)
@@ -1402,7 +1402,7 @@ reinit_ports(struct ofproto *p)
 static struct netdev *
 ofport_open(const struct ofproto_port *ofproto_port, struct ofp_phy_port *opp)
 {
-    uint32_t curr, advertised, supported, peer;
+    enum netdev_features curr, advertised, supported, peer;
     enum netdev_flags flags;
     struct netdev *netdev;
     int error;
@@ -1424,10 +1424,10 @@ ofport_open(const struct ofproto_port *ofproto_port, struct ofp_phy_port *opp)
     ovs_strzcpy(opp->name, ofproto_port->name, sizeof opp->name);
     opp->config = flags & NETDEV_UP ? 0 : htonl(OFPPC_PORT_DOWN);
     opp->state = netdev_get_carrier(netdev) ? 0 : htonl(OFPPS_LINK_DOWN);
-    opp->curr = htonl(curr);
-    opp->advertised = htonl(advertised);
-    opp->supported = htonl(supported);
-    opp->peer = htonl(peer);
+    opp->curr = ofputil_netdev_port_features_to_ofp10(curr);
+    opp->advertised = ofputil_netdev_port_features_to_ofp10(advertised);
+    opp->supported = ofputil_netdev_port_features_to_ofp10(supported);
+    opp->peer = ofputil_netdev_port_features_to_ofp10(peer);
 
     return netdev;
 }
@@ -2037,7 +2037,10 @@ handle_port_mod(struct ofconn *ofconn, const struct ofp_header *oh)
     } else {
         update_port_config(port, opm->config, opm->mask);
         if (opm->advertise) {
-            netdev_set_advertisements(port->netdev, ntohl(opm->advertise));
+            enum netdev_features adv;
+
+            adv = ofputil_netdev_port_features_from_ofp10(opm->advertise);
+            netdev_set_advertisements(port->netdev, adv);
         }
     }
     return 0;
@@ -2981,8 +2984,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 +3069,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 +3083,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;
 }
 
@@ -3162,7 +3170,7 @@ handle_barrier_request(struct ofconn *ofconn, const struct ofp_header *oh)
         return OFPROTO_POSTPONE;
     }
 
-    ob = make_openflow_xid(sizeof *ob, OFPT_BARRIER_REPLY, oh->xid, &buf);
+    ob = make_openflow_xid(sizeof *ob, OFPT10_BARRIER_REPLY, oh->xid, &buf);
     ofconn_send_reply(ofconn, buf);
     return 0;
 }
@@ -3279,11 +3287,10 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
     case OFPUTIL_NXST_FLOW_REPLY:
     case OFPUTIL_NXST_AGGREGATE_REPLY:
     default:
-        if (oh->type == OFPT_STATS_REQUEST || oh->type == OFPT_STATS_REPLY) {
-            return OFPERR_OFPBRC_BAD_STAT;
-        } else {
-            return OFPERR_OFPBRC_BAD_TYPE;
-        }
+        return (oh->type == OFPT10_STATS_REQUEST ||
+                oh->type == OFPT10_STATS_REPLY
+                ? OFPERR_OFPBRC_BAD_STAT
+                : OFPERR_OFPBRC_BAD_TYPE);
     }
 }