aboutsummaryrefslogtreecommitdiff
path: root/net/ipv4/ip_fragment.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-10 17:39:01 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-10 17:39:01 -0700
commit9f381a61f58bb6487c93ce2233bb9992f8ea9211 (patch)
tree579baf2e2893ea97599db9da807ed334d11f11d5 /net/ipv4/ip_fragment.c
parent21a43e397e7f66d3be44e09b54045f1a67838cc0 (diff)
parent9bbc052d5e63512b0ce4e201ea97e12fba9fda82 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (27 commits) slcan: fix ldisc->open retval net/usb: mark LG VL600 LTE modem ethernet interface as WWAN xfrm: Don't allow esn with disabled anti replay detection xfrm: Assign the inner mode output function to the dst entry net: dev_close() should check IFF_UP vlan: fix GVRP at dismantle time netfilter: revert a2361c8735e07322023aedc36e4938b35af31eb0 netfilter: IPv6: fix DSCP mangle code netfilter: IPv6: initialize TOS field in REJECT target module IPVS: init and cleanup restructuring IPVS: Change of socket usage to enable name space exit. netfilter: ebtables: only call xt_compat_add_offset once per rule netfilter: fix ebtables compat support netfilter: ctnetlink: fix timestamp support for new conntracks pch_gbe: support ML7223 IOH PCH_GbE : Fixed the issue of checksum judgment PCH_GbE : Fixed the issue of collision detection NET: slip, fix ldisc->open retval be2net: Fixed bugs related to PVID. ehea: fix wrongly reported speed and port ...
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r--net/ipv4/ip_fragment.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index a1151b8adf3..b1d282f11be 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -223,31 +223,30 @@ static void ip_expire(unsigned long arg)
if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) {
struct sk_buff *head = qp->q.fragments;
+ const struct iphdr *iph;
+ int err;
rcu_read_lock();
head->dev = dev_get_by_index_rcu(net, qp->iif);
if (!head->dev)
goto out_rcu_unlock;
+ /* skb dst is stale, drop it, and perform route lookup again */
+ skb_dst_drop(head);
+ iph = ip_hdr(head);
+ err = ip_route_input_noref(head, iph->daddr, iph->saddr,
+ iph->tos, head->dev);
+ if (err)
+ goto out_rcu_unlock;
+
/*
- * Only search router table for the head fragment,
- * when defraging timeout at PRE_ROUTING HOOK.
+ * Only an end host needs to send an ICMP
+ * "Fragment Reassembly Timeout" message, per RFC792.
*/
- if (qp->user == IP_DEFRAG_CONNTRACK_IN && !skb_dst(head)) {
- const struct iphdr *iph = ip_hdr(head);
- int err = ip_route_input(head, iph->daddr, iph->saddr,
- iph->tos, head->dev);
- if (unlikely(err))
- goto out_rcu_unlock;
-
- /*
- * Only an end host needs to send an ICMP
- * "Fragment Reassembly Timeout" message, per RFC792.
- */
- if (skb_rtable(head)->rt_type != RTN_LOCAL)
- goto out_rcu_unlock;
+ if (qp->user == IP_DEFRAG_CONNTRACK_IN &&
+ skb_rtable(head)->rt_type != RTN_LOCAL)
+ goto out_rcu_unlock;
- }
/* Send an ICMP "Fragment Reassembly Timeout" message. */
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);