[ovs-dev] [PATCH 3/5] ofproto-dpif: Fix memory leak in port_dump_next().

Ben Pfaff blp at nicira.com
Thu Jan 24 19:47:58 UTC 2013


The caller of port_query_by_name() is responsible for freeing the
ofproto_port that it returns on success, but ofproto-dpif did not do this.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 ofproto/ofproto-dpif.c |   22 +++++++++++++++++++---
 1 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 2c216fe..38e6db1 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1537,8 +1537,10 @@ port_construct(struct ofport *port_)
     if (odp_port_to_ofp_port(ofproto, port->odp_port) != OFPP_NONE) {
         VLOG_ERR("port %s already has an OpenFlow port number\n",
                  dpif_port.name);
+        dpif_port_destroy(&dpif_port);
         return EBUSY;
     }
+    dpif_port_destroy(&dpif_port);
 
     hmap_insert(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node,
                 hash_int(port->odp_port, 0));
@@ -2983,6 +2985,8 @@ ofproto_update_local_port_stats(const struct ofproto *ofproto_,
 struct port_dump_state {
     uint32_t bucket;
     uint32_t offset;
+    struct ofproto_port port;
+    bool has_port;
 };
 
 static int
@@ -2993,6 +2997,7 @@ port_dump_start(const struct ofproto *ofproto_ OVS_UNUSED, void **statep)
     *statep = state = xmalloc(sizeof *state);
     state->bucket = 0;
     state->offset = 0;
+    state->has_port = false;
     return 0;
 }
 
@@ -3004,12 +3009,20 @@ port_dump_next(const struct ofproto *ofproto_ OVS_UNUSED, void *state_,
     struct port_dump_state *state = state_;
     struct sset_node *node;
 
+    if (state->has_port) {
+        ofproto_port_destroy(&state->port);
+        state->has_port = false;
+    }
     while ((node = sset_at_position(&ofproto->ports, &state->bucket,
-                               &state->offset))) {
+                                    &state->offset))) {
         int error;
 
-        error = port_query_by_name(ofproto_, node->name, port);
-        if (error != ENODEV) {
+        error = port_query_by_name(ofproto_, node->name, &state->port);
+        if (!error) {
+            *port = state->port;
+            state->has_port = true;
+            return 0;
+        } else if (error != ENODEV) {
             return error;
         }
     }
@@ -3022,6 +3035,9 @@ port_dump_done(const struct ofproto *ofproto_ OVS_UNUSED, void *state_)
 {
     struct port_dump_state *state = state_;
 
+    if (state->has_port) {
+        ofproto_port_destroy(&state->port);
+    }
     free(state);
     return 0;
 }
-- 
1.7.2.5




More information about the dev mailing list