datpath: Fix memory leak when a loop is detected.
authorJesse Gross <jesse@nicira.com>
Fri, 10 Dec 2010 00:40:15 +0000 (16:40 -0800)
committerJesse Gross <jesse@nicira.com>
Sat, 11 Dec 2010 23:19:47 +0000 (15:19 -0800)
If we detect a packet that is looping we kill the flow but then
don't do anything with the packet that caused the problem in the
first place, so this frees the packet.  This isn't a very serious
leak because we try to shut off the flow that lead to the loop
as early as possible.  Once this happens, packets will no longer
hit the loop detector and will be freed just as any other packet
that should be dropped.

It also fixes an issue where the offset to the stats counter is
uninitialized after a loop is detected.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
datapath/datapath.c

index cc76720..634ac1b 100644 (file)
@@ -501,6 +501,7 @@ void dp_process_received_packet(struct vport *p, struct sk_buff *skb)
                OVS_CB(skb)->flow = flow_cast(flow_node);
        }
 
+       stats_counter_off = offsetof(struct dp_stats_percpu, n_hit);
        flow_used(OVS_CB(skb)->flow, skb);
 
        acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
@@ -511,13 +512,13 @@ void dp_process_received_packet(struct vport *p, struct sk_buff *skb)
                loop->looping = true;
        if (unlikely(loop->looping)) {
                loop_suppress(dp, acts);
+               kfree_skb(skb);
                goto out_loop;
        }
 
        /* Execute actions. */
        execute_actions(dp, skb, &OVS_CB(skb)->flow->key, acts->actions,
                        acts->actions_len);
-       stats_counter_off = offsetof(struct dp_stats_percpu, n_hit);
 
        /* Check whether sub-actions looped too much. */
        if (unlikely(loop->looping))