classifier: Change type used for priorities from 'unsigned int' to 'int'.
[cascardo/ovs.git] / ofproto / ofproto.c
index 127d8c3..1233164 100644 (file)
@@ -153,8 +153,7 @@ struct rule_criteria {
 };
 
 static void rule_criteria_init(struct rule_criteria *, uint8_t table_id,
-                               const struct match *match,
-                               unsigned int priority,
+                               const struct match *match, int priority,
                                ovs_be64 cookie, ovs_be64 cookie_mask,
                                ofp_port_t out_port, uint32_t out_group);
 static void rule_criteria_require_rw(struct rule_criteria *,
@@ -1357,10 +1356,17 @@ ofproto_flush__(struct ofproto *ofproto)
 {
     struct oftable *table;
 
+    /* This will flush all datapath flows. */
     if (ofproto->ofproto_class->flush) {
         ofproto->ofproto_class->flush(ofproto);
     }
 
+    /* XXX: There is a small race window here, where new datapath flows can be
+     * created by upcall handlers based on the existing flow table.  We can not
+     * call ofproto class flush while holding 'ofproto_mutex' to prevent this,
+     * as then we could deadlock on syncing with the handler threads waiting on
+     * the same mutex. */
+
     ovs_mutex_lock(&ofproto_mutex);
     OFPROTO_FOR_EACH_TABLE (table, ofproto) {
         struct rule *rule;
@@ -1373,6 +1379,9 @@ ofproto_flush__(struct ofproto *ofproto)
             ofproto_rule_delete__(rule, OFPRR_DELETE);
         }
     }
+    /* XXX: Concurrent handler threads may insert new learned flows based on
+     * learn actions of the now deleted flows right after we release
+     * 'ofproto_mutex'. */
     ovs_mutex_unlock(&ofproto_mutex);
 }
 
@@ -1872,7 +1881,7 @@ ofproto_port_del(struct ofproto *ofproto, ofp_port_t ofp_port)
 
 static void
 flow_mod_init(struct ofputil_flow_mod *fm,
-              const struct match *match, unsigned int priority,
+              const struct match *match, int priority,
               const struct ofpact *ofpacts, size_t ofpacts_len,
               enum ofp_flow_mod_command command)
 {
@@ -1897,7 +1906,7 @@ flow_mod_init(struct ofputil_flow_mod *fm,
 
 static int
 simple_flow_mod(struct ofproto *ofproto,
-                const struct match *match, unsigned int priority,
+                const struct match *match, int priority,
                 const struct ofpact *ofpacts, size_t ofpacts_len,
                 enum ofp_flow_mod_command command)
 {
@@ -1921,7 +1930,7 @@ simple_flow_mod(struct ofproto *ofproto,
  * This is a helper function for in-band control and fail-open. */
 void
 ofproto_add_flow(struct ofproto *ofproto, const struct match *match,
-                 unsigned int priority,
+                 int priority,
                  const struct ofpact *ofpacts, size_t ofpacts_len)
     OVS_EXCLUDED(ofproto_mutex)
 {
@@ -2008,7 +2017,7 @@ ofproto_flow_mod(struct ofproto *ofproto, struct ofputil_flow_mod *fm)
  * This is a helper function for in-band control and fail-open. */
 void
 ofproto_delete_flow(struct ofproto *ofproto,
-                    const struct match *target, unsigned int priority)
+                    const struct match *target, int priority)
     OVS_EXCLUDED(ofproto_mutex)
 {
     struct classifier *cls = &ofproto->tables[0].cls;
@@ -2895,28 +2904,14 @@ query_tables(struct ofproto *ofproto,
              struct ofputil_table_features **featuresp,
              struct ofputil_table_stats **statsp)
 {
-    struct mf_bitmap rw_fields = MF_BITMAP_INITIALIZER;
-    struct mf_bitmap match = MF_BITMAP_INITIALIZER;
-    struct mf_bitmap mask = MF_BITMAP_INITIALIZER;
+    struct mf_bitmap rw_fields = oxm_writable_fields();
+    struct mf_bitmap match = oxm_matchable_fields();
+    struct mf_bitmap mask = oxm_maskable_fields();
 
     struct ofputil_table_features *features;
     struct ofputil_table_stats *stats;
     int i;
 
-    for (i = 0; i < MFF_N_IDS; i++) {
-        const struct mf_field *mf = mf_from_id(i);
-
-        if (mf->writable) {
-            bitmap_set1(rw_fields.bm, i);
-        }
-        if (mf->oxm_header || mf->nxm_header) {
-            bitmap_set1(match.bm, i);
-            if (mf->maskable == MFM_FULLY) {
-                bitmap_set1(mask.bm, i);
-            }
-        }
-    }
-
     features = *featuresp = xcalloc(ofproto->n_tables, sizeof *features);
     for (i = 0; i < ofproto->n_tables; i++) {
         struct ofputil_table_features *f = &features[i];
@@ -3011,7 +3006,8 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh)
     features.n_buffers = pktbuf_capacity();
     features.n_tables = ofproto_get_n_visible_tables(ofproto);
     features.capabilities = (OFPUTIL_C_FLOW_STATS | OFPUTIL_C_TABLE_STATS |
-                             OFPUTIL_C_PORT_STATS | OFPUTIL_C_QUEUE_STATS);
+                             OFPUTIL_C_PORT_STATS | OFPUTIL_C_QUEUE_STATS |
+                             OFPUTIL_C_GROUP_STATS);
     if (arp_match_ip) {
         features.capabilities |= OFPUTIL_C_ARP_MATCH_IP;
     }
@@ -3513,7 +3509,7 @@ next_matching_table(const struct ofproto *ofproto,
  * supplied as 0. */
 static void
 rule_criteria_init(struct rule_criteria *criteria, uint8_t table_id,
-                   const struct match *match, unsigned int priority,
+                   const struct match *match, int priority,
                    ovs_be64 cookie, ovs_be64 cookie_mask,
                    ofp_port_t out_port, uint32_t out_group)
 {
@@ -4349,8 +4345,6 @@ modify_flows__(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
 
         long long int now = time_msec();
 
-        /* FIXME: Implement OFPFUTIL_FF_RESET_COUNTS */
-
         if (change_cookie) {
             cookies_remove(ofproto, rule);
         }