diff options
author | David S. Miller <davem@davemloft.net> | 2015-05-19 00:15:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-19 00:15:50 -0400 |
commit | 76d7c457659dfc05d5a23cd0b21fea333d1788cd (patch) | |
tree | 446c416b396c4561bd5616f6fba2ef52c43c8d06 /net/ipv4/ip_fragment.c | |
parent | a2ad5d2ad96e8d5b3b8f33583a82eae78dce4d49 (diff) | |
parent | 49d16b23cd1e61c028ee088c5a64e9ac6a9c6147 (diff) |
Merge branch 'icmp_frag'
Andy Zhou says:
====================
fragmentation ICMP
Currently, we send ICMP packets when errors occur during fragmentation or
de-fragmentation. However, it is a bug when sending those ICMP packets
in the context of using netfilter for bridging.
Those ICMP packets are only expected in the context of routing, not in
bridging mode.
The local stack is not involved in bridging forward decisions, thus
should be not used for deciding the reverse path for those ICMP messages.
This bug only affects IPV4, not in IPv6.
v1->v2: restructure the patches into two patches that fix defragmentation and
fragmentation respectively.
A bit is add in IPCB to control whether ICMP packet should be
generated for defragmentation.
Fragmentation ICMP is now removed by restructuring the
ip_fragment() API.
v2->v3: Add droping icmp for bridging contrack users
drop exporting ip_fragment() API.
v3->v4: Remove unnecessary parentheses in 'return' statements
v4->v5: Drop the patch that sets and checks a bit in IPCB
that prevents ip_defrag to send ICMP.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_fragment.c')
-rw-r--r-- | net/ipv4/ip_fragment.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index cc1da6d9cb35..47fa64ee82b1 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -173,6 +173,15 @@ static void ipq_kill(struct ipq *ipq) inet_frag_kill(&ipq->q, &ip4_frags); } +static bool frag_expire_skip_icmp(u32 user) +{ + return user == IP_DEFRAG_AF_PACKET || + ip_defrag_user_in_between(user, IP_DEFRAG_CONNTRACK_IN, + __IP_DEFRAG_CONNTRACK_IN_END) || + ip_defrag_user_in_between(user, IP_DEFRAG_CONNTRACK_BRIDGE_IN, + __IP_DEFRAG_CONNTRACK_BRIDGE_IN); +} + /* * Oops, a fragment queue timed out. Kill it and send an ICMP reply. */ @@ -217,10 +226,8 @@ static void ip_expire(unsigned long arg) /* Only an end host needs to send an ICMP * "Fragment Reassembly Timeout" message, per RFC792. */ - if (qp->user == IP_DEFRAG_AF_PACKET || - ((qp->user >= IP_DEFRAG_CONNTRACK_IN) && - (qp->user <= __IP_DEFRAG_CONNTRACK_IN_END) && - (skb_rtable(head)->rt_type != RTN_LOCAL))) + if (frag_expire_skip_icmp(qp->user) && + (skb_rtable(head)->rt_type != RTN_LOCAL)) goto out_rcu_unlock; /* Send an ICMP "Fragment Reassembly Timeout" message. */ |