dpif-netdev: Fix memory leak in tunnel header pop action.
authorPravin B Shelar <pshelar@ovn.org>
Wed, 18 May 2016 00:32:37 +0000 (17:32 -0700)
committerPravin B Shelar <pshelar@ovn.org>
Thu, 19 May 2016 02:39:18 +0000 (19:39 -0700)
The tunnel header pop action can leak batch of packet
in case of error. Following patch fixex the error code path.

Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
Acked-by: Jesse Gross <jesse@kernel.org>
lib/dpif-netdev.c
lib/netdev.c
lib/netdev.h

index 8bb18bc..e33a3db 100644 (file)
@@ -3751,30 +3751,25 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
             p = dp_netdev_lookup_port(dp, portno);
             if (p) {
                 struct dp_packet_batch tnl_pkt;
-                int err;
+                int i;
 
                 if (!may_steal) {
                    dp_packet_batch_clone(&tnl_pkt, packets_);
                    packets_ = &tnl_pkt;
                 }
 
-                err = netdev_pop_header(p->netdev, packets_);
+                netdev_pop_header(p->netdev, packets_);
                 if (!packets_->count) {
                     return;
                 }
-                if (!err) {
-                    int i;
 
-                    for (i = 0; i < packets_->count; i++) {
-                        packets_->packets[i]->md.in_port.odp_port = portno;
-                    }
-
-                    (*depth)++;
-                    dp_netdev_recirculate(pmd, packets_);
-                    (*depth)--;
-                } else {
-                    dp_packet_delete_batch(&tnl_pkt, !may_steal);
+                for (i = 0; i < packets_->count; i++) {
+                    packets_->packets[i]->md.in_port.odp_port = portno;
                 }
+
+                (*depth)++;
+                dp_netdev_recirculate(pmd, packets_);
+                (*depth)--;
                 return;
             }
         }
index 911e7c8..9d40a22 100644 (file)
@@ -730,14 +730,16 @@ netdev_send(struct netdev *netdev, int qid, struct dp_packet_batch *batch,
     return error;
 }
 
-int
+void
 netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *batch)
 {
     int i, n_cnt = 0;
     struct dp_packet **buffers = batch->packets;
 
     if (!netdev->netdev_class->pop_header) {
-        return EOPNOTSUPP;
+        dp_packet_delete_batch(batch, true);
+        batch->count = 0;
+        return;
     }
 
     for (i = 0; i < batch->count; i++) {
@@ -747,7 +749,6 @@ netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *batch)
         }
     }
     batch->count = n_cnt;
-    return 0;
 }
 
 int
index 22e4209..a292167 100644 (file)
@@ -158,7 +158,7 @@ int netdev_build_header(const struct netdev *, struct ovs_action_push_tnl *data,
 int netdev_push_header(const struct netdev *netdev,
                        struct dp_packet_batch *,
                        const struct ovs_action_push_tnl *data);
-int netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *);
+void netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *);
 
 /* Hardware address. */
 int netdev_set_etheraddr(struct netdev *, const struct eth_addr mac);