@@ -43,7 +43,7 @@ static void send_reset(struct net *net,
int tcphoff, needs_ack;
const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
struct ipv6hdr *ip6h;
- struct dst_entry *dst = NULL;
+ struct dst_entry *dst;
u8 proto;
struct flowi fl;
@@ -97,8 +97,10 @@ static void send_reset(struct net *net,
dst = ip6_route_output(net, NULL, &fl);
if (dst == NULL)
return;
- if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0))
+ if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0)) {
+ dst_release(dst);
return;
+ }
hh_len = (dst->dev->hard_header_len + 15)&~15;
nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
@@ -25,6 +25,12 @@ int ip6_route_me_harder(struct sk_buff *
};
dst = ip6_route_output(net, skb->sk, &fl);
+ if (dst->error) {
+ IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+ LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
+ dst_release(dst);
+ return -EINVAL;
+ }
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -32,6 +38,7 @@ int ip6_route_me_harder(struct sk_buff *
struct dst_entry *dst2 = skb_dst(skb);
if (xfrm_lookup(net, &dst2, &fl, skb->sk, 0)) {
+ dst_release(dst);
skb_dst_set(skb, NULL);
return -1;
}
@@ -39,12 +46,6 @@ int ip6_route_me_harder(struct sk_buff *
}
#endif
- if (dst->error) {
- IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
- LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
- dst_release(dst);
- return -EINVAL;
- }
/* Drop old route. */
skb_dst_drop(skb);