aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r--net/ipv4/icmp.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index ac4dec132735..d65e9215bcd7 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -331,9 +331,10 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
331 if (ip_append_data(sk, icmp_glue_bits, icmp_param, 331 if (ip_append_data(sk, icmp_glue_bits, icmp_param,
332 icmp_param->data_len+icmp_param->head_len, 332 icmp_param->data_len+icmp_param->head_len,
333 icmp_param->head_len, 333 icmp_param->head_len,
334 ipc, rt, MSG_DONTWAIT) < 0) 334 ipc, rt, MSG_DONTWAIT) < 0) {
335 ICMP_INC_STATS_BH(sock_net(sk), ICMP_MIB_OUTERRORS);
335 ip_flush_pending_frames(sk); 336 ip_flush_pending_frames(sk);
336 else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { 337 } else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
337 struct icmphdr *icmph = icmp_hdr(skb); 338 struct icmphdr *icmph = icmp_hdr(skb);
338 __wsum csum = 0; 339 __wsum csum = 0;
339 struct sk_buff *skb1; 340 struct sk_buff *skb1;
@@ -586,20 +587,20 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
586 err = __ip_route_output_key(net, &rt2, &fl); 587 err = __ip_route_output_key(net, &rt2, &fl);
587 else { 588 else {
588 struct flowi fl2 = {}; 589 struct flowi fl2 = {};
589 struct dst_entry *odst; 590 unsigned long orefdst;
590 591
591 fl2.fl4_dst = fl.fl4_src; 592 fl2.fl4_dst = fl.fl4_src;
592 if (ip_route_output_key(net, &rt2, &fl2)) 593 if (ip_route_output_key(net, &rt2, &fl2))
593 goto relookup_failed; 594 goto relookup_failed;
594 595
595 /* Ugh! */ 596 /* Ugh! */
596 odst = skb_dst(skb_in); 597 orefdst = skb_in->_skb_refdst; /* save old refdst */
597 err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, 598 err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src,
598 RT_TOS(tos), rt2->u.dst.dev); 599 RT_TOS(tos), rt2->u.dst.dev);
599 600
600 dst_release(&rt2->u.dst); 601 dst_release(&rt2->u.dst);
601 rt2 = skb_rtable(skb_in); 602 rt2 = skb_rtable(skb_in);
602 skb_dst_set(skb_in, odst); 603 skb_in->_skb_refdst = orefdst; /* restore old refdst */
603 } 604 }
604 605
605 if (err) 606 if (err)