diff --git a/[refs] b/[refs] index 49f0d07ae5ee..082bb96042cc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4a94445c9a5cf5461fb41d80040033b9a8e2a85a +refs/heads/master: ab6e3feba1f1bc3b9418b854da6f481408d243de diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 252897443ef9..9a4a6c96cb0d 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -318,10 +318,12 @@ int ip_queue_xmit(struct sk_buff *skb) struct ip_options *opt = inet->opt; struct rtable *rt; struct iphdr *iph; + int res; /* Skip all of this if the packet is already routed, * f.e. by something like SCTP. */ + rcu_read_lock(); rt = skb_rtable(skb); if (rt != NULL) goto packet_routed; @@ -359,7 +361,7 @@ int ip_queue_xmit(struct sk_buff *skb) } sk_setup_caps(sk, &rt->u.dst); } - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb_dst_set_noref(skb, &rt->u.dst); packet_routed: if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) @@ -391,9 +393,12 @@ int ip_queue_xmit(struct sk_buff *skb) skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - return ip_local_out(skb); + res = ip_local_out(skb); + rcu_read_unlock(); + return res; no_route: + rcu_read_unlock(); IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); kfree_skb(skb); return -EHOSTUNREACH;