From: Kazunori Miyazawa <kazunori@xxxxxxxxxxxx>
Date: Fri, 6 Jun 2003 14:49:25 +0900
In dst_pop refernce cound of dsts except for last are incremented in
dst_clone and decremented in next call dst_pop but last dst refernce
count will be never decremented.
All dst are held by xfrm_policy and there is no need to touch the
refernce count here.
Ok, there is problem with this logic.
Final dst is set to skb->dst, and when SKB is freed then
we do dst_release(skb->dst). Therefore it _IS_ decremented.
(see net/core/skbuff.c:__kfree_skb(), it is where this final
DST reference is decremented).
Something is going wrong in ipv6 code if this is not happening.
If you modify skb->dst, it is your job to maintain reference
properly.
Look at how ipv4 works, we do all the work in the route lookup
and furthermore we never pass &skb->dst into these lookups.
What ipv6 output does looks really really strange. It is silly
to do flow lookups in places like ip6_xmit(). And this is where
all the refcount bugs are really coming from. Like ipv4, flow lookups
should be occuring at end of ip6_route_output() processing.
As far as I can tell, ip6_xmit() makes calculations based upon "dst"
and this is wrong. It updates only skb->dst, but this is not what
that function uses to make decisions. 'dst' is old copy :(
|