Bug 15703 - Getting "MD5 Hash failed for" for fragmented IP packets.
Summary: Getting "MD5 Hash failed for" for fragmented IP packets.
Status: RESOLVED OBSOLETE
Alias: None
Product: Networking
Classification: Unclassified
Component: IPV4 (show other bugs)
Hardware: All Linux
: P1 high
Assignee: Stephen Hemminger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-04-06 09:52 UTC by Vishal Swarankar
Modified: 2012-07-11 14:55 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.31-14-generic
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Vishal Swarankar 2010-04-06 09:52:38 UTC
I am using Ubuntu 9.10 with a kernel 2.6.31-14-generic.

At my linux box I am receiving IP packets with TCP as payload with TCP-MD5 option as its a BGP update.

If I am getting fragmented IP packets on my Linux box then I am receiving only one fragment of the IP packet and I don't receive the second fragments because of some settings at my firewall ( I discard small packets, and the second fragment has only 20 bytes of data, so I consider it as small packet and always discard it).

I have ensured that I am not receiving the second fragment of the packet all the time ( in all further retransmission ) using sniffers.

Now for a IP fragmented packet I keep on getting messages 
"MD5 hash failed for IP(src)--> IP(Dst)". I receive this message for all fragmented packets. The message is in tcp_ipv4.c - >tcp_v4_inbound_md5_hash method.

I hope I should not be getting these message because the fragmented packets should not be pushed to the upper layer( TCP) for further sanity checks( MD5-check sum verification), until all fragments are assembled together.

I tried to look at the ip_rcv code and found that ip_local_deliver(struct sk_buff* skb) is calling ip_defrag() function to check if the fragmentation task is still in progress or not.

I tried to dig down more into ip_defrag function and the return values from ip_defrag function and I hope that the check in the ip_local_deliver function is not correct.

int ip_local_deliver(struct sk_buff *skb)
{
	/*
	 *	Reassemble IP fragments.
	 */

	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
		if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
			return 0;
	}

	return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
		       ip_local_deliver_finish);
}


I think the check for ip_defrag should be like this 
------>>>>if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER) < 0) 

we should check the negative return to avoid ip_local_deliver_finish, instead of checking the null return.

thanks
Vishal
Comment 1 Vishal Swarankar 2010-04-07 13:07:44 UTC
this is type of creating issues for my customer as he is getting lots of MD5 hash failures.
Need help.
Comment 2 Stephen Hemminger 2010-04-07 17:05:52 UTC
On Tue, 6 Apr 2010 09:52:46 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:

> https://bugzilla.kernel.org/show_bug.cgi?id=15703
> 
>            Summary: Getting "MD5 Hash failed for" for fragmented IP
>                     packets.
>            Product: Networking
>            Version: 2.5
>     Kernel Version: 2.6.31-14-generic
>           Platform: All
>         OS/Version: Linux
>               Tree: Mainline
>             Status: NEW
>           Severity: normal
>           Priority: P1
>          Component: IPV4
>         AssignedTo: shemminger@linux-foundation.org
>         ReportedBy: vishal.swarnkar@gmail.com
>                 CC: vishal.swarnkar@gmail.com
>         Regression: No
> 
> 
> I am using Ubuntu 9.10 with a kernel 2.6.31-14-generic.
> 
> At my linux box I am receiving IP packets with TCP as payload with TCP-MD5
> option as its a BGP update.
> 
> If I am getting fragmented IP packets on my Linux box then I am receiving
> only
> one fragment of the IP packet and I don't receive the second fragments
> because
> of some settings at my firewall ( I discard small packets, and the second
> fragment has only 20 bytes of data, so I consider it as small packet and
> always
> discard it).
> 
> I have ensured that I am not receiving the second fragment of the packet all
> the time ( in all further retransmission ) using sniffers.
> 
> Now for a IP fragmented packet I keep on getting messages 
> "MD5 hash failed for IP(src)--> IP(Dst)". I receive this message for all
> fragmented packets. The message is in tcp_ipv4.c - >tcp_v4_inbound_md5_hash
> method.
> 
> I hope I should not be getting these message because the fragmented packets
> should not be pushed to the upper layer( TCP) for further sanity checks(
> MD5-check sum verification), until all fragments are assembled together.
> 
> I tried to look at the ip_rcv code and found that ip_local_deliver(struct
> sk_buff* skb) is calling ip_defrag() function to check if the fragmentation
> task is still in progress or not.
> 
> I tried to dig down more into ip_defrag function and the return values from
> ip_defrag function and I hope that the check in the ip_local_deliver function
> is not correct.
> 
> int ip_local_deliver(struct sk_buff *skb)
> {
>     /*
>      *    Reassemble IP fragments.
>      */
> 
>     if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
>         if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
>             return 0;
>     }
> 
>     return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
>                ip_local_deliver_finish);
> }
> 
> 
> I think the check for ip_defrag should be like this 
> ------>>>>if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER) < 0) 
> 
> we should check the negative return to avoid ip_local_deliver_finish, instead
> of checking the null return.

Maybe path MTU discovery can help with this.
Comment 3 Andrew Morton 2010-04-07 21:30:34 UTC
Did you try making that change to ip_local_deliver()?  I can't see any path whereby ip_defrag() returns anything other than 0 or a -ve errno.
Comment 4 Vishal Swarankar 2010-04-08 05:52:41 UTC
@Stephen Hemminger:
I am not looking for methods to avoid Defragmentation. Because of some X reasons, I cant use Path MTU discovery, can't increase TCP MSS for my sockets and cant set static path with a certain MTU.

Anyway I am not worried that why fragmentation? I am ok with fragmented packets. But I think the code in ip_local_deliver function should be changed 

From

if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))

To

if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER) < 0)


@Andrew Morton : No I dint try to change the code. Yes you are right, it returns 0 and -ve values only and ip_frag_queue returns a value -EINPROGRESS.

I hope that condition says there are more packets to come, so this packet should not be delivered further and we should quit from ip_local_delivery function. ??
Comment 5 Vishal Swarankar 2010-04-28 11:00:05 UTC
Hi,

Any help on this?

Note You need to log in before you can comment on or make changes to this bug.