[ovs-dev] [PATCH 12/32] ofproto: Use list when handling monitor requests

Simon Horman horms at verge.net.au
Mon Jun 9 03:54:08 UTC 2014


Use a list rather than an array to track monitor requests
in handle_flow_monitor_request().

This is in preparation for supporting OpenFlow1.4 flow monitor requests
with delete and modify commands.

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 ofproto/connmgr.c |  2 ++
 ofproto/connmgr.h |  3 +++
 ofproto/ofproto.c | 27 ++++++++++-----------------
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
index 07576b6..896a0a1 100644
--- a/ofproto/connmgr.c
+++ b/ofproto/connmgr.c
@@ -2113,6 +2113,7 @@ ofmonitor_create(const struct ofputil_flow_monitor_request *request,
     m->out_group = request->out_group;
     m->table_id = request->table_id;
     minimatch_init(&m->match, &request->match);
+    list_init(&m->list_node);
 
     *monitorp = m;
     return 0;
@@ -2140,6 +2141,7 @@ ofmonitor_destroy(struct ofmonitor *m)
     if (m) {
         minimatch_destroy(&m->match);
         hmap_remove(&m->ofconn->monitors, &m->ofconn_node);
+        list_remove(&m->list_node);
         free(m);
     }
 }
diff --git a/ofproto/connmgr.h b/ofproto/connmgr.h
index 44f1ebd..87e4d3a 100644
--- a/ofproto/connmgr.h
+++ b/ofproto/connmgr.h
@@ -209,6 +209,9 @@ struct ofmonitor {
     uint32_t out_group;
     uint8_t table_id;
     struct minimatch match;
+
+    /* Used temporarily when handling flow monitor requests */
+    struct list list_node;
 };
 
 struct ofputil_flow_monitor_request;
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 5cb61d7..d5cc996 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -4919,24 +4919,20 @@ static enum ofperr
 handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
     OVS_EXCLUDED(ofproto_mutex)
 {
+    struct list monitor_list = LIST_INITIALIZER(&monitor_list);
     struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
-    struct ofmonitor **monitors;
-    size_t n_monitors, allocated_monitors;
     struct rule_collection rules;
     struct list replies;
+    struct ofmonitor *m, *next;
     enum ofperr error;
     struct ofpbuf b;
-    size_t i;
 
     error = 0;
     ofpbuf_use_const(&b, oh, ntohs(oh->length));
-    monitors = NULL;
-    n_monitors = allocated_monitors = 0;
 
     ovs_mutex_lock(&ofproto_mutex);
     for (;;) {
         struct ofputil_flow_monitor_request request;
-        struct ofmonitor *m;
         int retval;
 
         retval = ofputil_decode_flow_monitor_request(&request, &b);
@@ -4958,16 +4954,15 @@ handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
             goto error;
         }
 
-        if (n_monitors >= allocated_monitors) {
-            monitors = x2nrealloc(monitors, &allocated_monitors,
-                                  sizeof *monitors);
-        }
-        monitors[n_monitors++] = m;
+        list_insert(&monitor_list, &m->list_node);
     }
 
     rule_collection_init(&rules);
-    for (i = 0; i < n_monitors; i++) {
-        ofproto_collect_ofmonitor_initial_rules(monitors[i], &rules);
+    LIST_FOR_EACH_SAFE(m, next, list_node, &monitor_list) {
+        ofproto_collect_ofmonitor_initial_rules(m, &rules);
+        /* This is the last use of monitor_list but m will persist
+         * so detach m from monitor_list. */
+        list_init(&m->list_node);
     }
 
     ofpmp_init(&replies, oh);
@@ -4977,15 +4972,13 @@ handle_flow_monitor_request(struct ofconn *ofconn, const struct ofp_header *oh)
     rule_collection_destroy(&rules);
 
     ofconn_send_replies(ofconn, &replies);
-    free(monitors);
 
     return 0;
 
 error:
-    for (i = 0; i < n_monitors; i++) {
-        ofmonitor_destroy(monitors[i]);
+    LIST_FOR_EACH(m, list_node, &monitor_list) {
+        ofmonitor_destroy(m);
     }
-    free(monitors);
     ovs_mutex_unlock(&ofproto_mutex);
 
     return error;
-- 
2.0.0.rc2




More information about the dev mailing list