ofproto: Support OF version-specific table-miss behaviours
[sliver-openvswitch.git] / ofproto / ofproto.c
index c2f9c8b..677da8c 100644 (file)
@@ -3192,8 +3192,7 @@ handle_port_desc_stats_request(struct ofconn *ofconn,
 static uint32_t
 hash_cookie(ovs_be64 cookie)
 {
-    return hash_2words((OVS_FORCE uint64_t)cookie >> 32,
-                       (OVS_FORCE uint64_t)cookie);
+    return hash_uint64((OVS_FORCE uint64_t)cookie);
 }
 
 static void
@@ -5787,11 +5786,21 @@ handle_group_mod(struct ofconn *ofconn, const struct ofp_header *oh)
     }
 }
 
+enum ofproto_table_config
+ofproto_table_get_config(const struct ofproto *ofproto, uint8_t table_id)
+{
+    unsigned int value;
+    atomic_read(&ofproto->tables[table_id].config, &value);
+    return (enum ofproto_table_config)value;
+}
+
 static enum ofperr
 table_mod(struct ofproto *ofproto, const struct ofputil_table_mod *tm)
 {
-    /* XXX Reject all configurations because none are currently supported */
-    return OFPERR_OFPTMFC_BAD_CONFIG;
+    /* Only accept currently supported configurations */
+    if (tm->config & ~OFPTC11_TABLE_MISS_MASK) {
+        return OFPERR_OFPTMFC_BAD_CONFIG;
+    }
 
     if (tm->table_id == OFPTT_ALL) {
         int i;
@@ -5833,7 +5842,7 @@ static enum ofperr
 handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
     OVS_EXCLUDED(ofproto_mutex)
 {
-    const struct ofp_header *oh = msg->data;
+    const struct ofp_header *oh = ofpbuf_data(msg);
     enum ofptype type;
     enum ofperr error;
 
@@ -6006,7 +6015,7 @@ handle_openflow(struct ofconn *ofconn, const struct ofpbuf *ofp_msg)
 {
     int error = handle_openflow__(ofconn, ofp_msg);
     if (error && error != OFPROTO_POSTPONE) {
-        ofconn_send_error(ofconn, ofp_msg->data, error);
+        ofconn_send_error(ofconn, ofpbuf_data(ofp_msg), error);
     }
     COVERAGE_INC(ofproto_recv_openflow);
     return error != OFPROTO_POSTPONE;
@@ -6669,7 +6678,7 @@ oftable_init(struct oftable *table)
     memset(table, 0, sizeof *table);
     classifier_init(&table->cls, flow_segment_u32s);
     table->max_flows = UINT_MAX;
-    atomic_init(&table->config, (unsigned int)OFPTC11_TABLE_MISS_CONTROLLER);
+    atomic_init(&table->config, (unsigned int)OFPROTO_TABLE_MISS_DEFAULT);
 }
 
 /* Destroys 'table', including its classifier and eviction groups.