Skip to contentSkip to conversation

Fix bug of update IPv4 PMTU when received ICMP Fragmentation Needed message

PATCH In review Wei Yongjun 3 participants 10 messages Jun 1, 2007 – Mar 21, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix bug of update IPv4 PMTU when received ICMP Fragmentation Needed message

When received ICMP Fragmentation Needed message, PATH MTU is always set to the 576 even if MTU in ICMP message is lager then 576. This is because of error condition in function ip_rt_frag_needed(), now if packet size of that ICMP message is less then new MTU, packet size will be used ,but RFC says ICMP error message return as much as we can without exceeding 576 bytes.

This patch has Fixed this BUG.

ipv4/route.c renamed from ipv4/route.c.orig +0 -0
@@ -1424,7 +1424,7 @@ unsigned short ip_rt_frag_needed(struct 
			    !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
				unsigned short mtu = new_mtu;

- if (new_mtu < 68 || new_mtu >= old_mtu) {
+ if (new_mtu < 68) {

					/* BSD 4.2 compatibility hack :-( */
					if (mtu == 0 &&
#1 lore raw
Quoted 14 lines · Wei Yongjun

When received ICMP Fragmentation Needed message, PATH MTU is always set to the 576 even if MTU in ICMP message is lager then 576. This is because of error condition in function ip_rt_frag_needed(), now if packet size of that ICMP message is less then new MTU, packet size will be used ,but RFC says ICMP error message return as much as we can without exceeding 576 bytes.

This patch has Fixed this BUG.

ipv4/route.c 2007-06-01 11:42:55.000000000 +0800 unsigned short ip_rt_frag_needed(struct · line 1429

Quoted 7 lines
ipv4/route.c 2007-06-01 11:42:55.000000000 +0800 renamed from ipv4/route.c.orig 2007-05-25 05:22:47.000000000 +0800 +1 -1
@@ -1424,7 +1424,7 @@ unsigned short ip_rt_frag_needed(struct 
                           !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
                               unsigned short mtu = new_mtu;
 
-                               if (new_mtu < 68 || new_mtu >= old_mtu) {
+                               if (new_mtu < 68) {
 
                                       /* BSD 4.2 compatibility hack :-( */

Huh? The test new_mtu >= old_mtu should only hold if the sending router is buggy which is what the hack is for.

Cheers,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#2 lore raw
Quoted 12 lines
Quoted 6 lines

When received ICMP Fragmentation Needed message, PATH MTU is always set to the 576 even if MTU in ICMP message is lager then 576. This is because of error condition in function ip_rt_frag_needed(), now if packet size of that ICMP message is less then new MTU, packet size will be used ,but RFC says ICMP error message return as much as we can without exceeding 576 bytes.

This patch has Fixed this BUG.

Huh? The test new_mtu >= old_mtu should only hold if the sending router is buggy which is what the hack is for.

Cheers,

Note here old_mtu is not the real old mtu, is the received message's size:
unsigned short old_mtu = ntohs(iph->tot_len);
So maybe the patch would like following.

ipv4/route.c renamed from ipv4/route.c.orig +0 -0
@@ -1424,7 +1424,7 @@ unsigned short ip_rt_frag_needed(struct 
			    !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
				unsigned short mtu = new_mtu;
-				if (new_mtu < 68 || new_mtu >= old_mtu) {
+				if (new_mtu < 68 || new_mtu >= rth->u.dst.metrics[RTAX_MTU-1]) {
					/* BSD 4.2 compatibility hack :-( */
					if (mtu == 0 &&
#3 lore raw
Quoted 7 lines · Wei Yongjun
Quoted 3 lines

Huh? The test new_mtu >= old_mtu should only hold if the sending router is buggy which is what the hack is for.

Note here old_mtu is not the real old mtu, is the received message's size:
unsigned short old_mtu = ntohs(iph->tot_len);
So maybe the patch would like following.

The size of the packet that caused the ICMP is what we want here. That's why the router must be buggy.

Cheers,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#4 lore raw
Quoted 6 lines · Wei Yongjun
Quoted 4 lines
Quoted 4 lines

Huh? The test new_mtu >= old_mtu should only hold if the sending router is buggy which is what the hack is for.

Quoted 9 lines
Quoted 4 lines

Note here old_mtu is not the real old mtu, is the received message's size:
unsigned short old_mtu = ntohs(iph->tot_len);
So maybe the patch would like following.

The size of the packet that caused the ICMP is what we want here. That's why the router must be buggy.

So I want to know how the route announce a MTU larger then 576, such as 1280? RFC says ICMP error message return as much as we can without exceeding 576 bytes. And ipv4 router alaways return as a packet size 576 because of this.
If MTU is greater then 576, HOST will used "mtu = guess_mtu(old_mtu)" to get a MTU. Method of send ICMP Fragmentation Needed message is difference from receive, how can this resolve? Change the method of send ICMP Fragmentation Needed message? I do not think so, the only think we can do is to change the method of receive ICMP message. Do you agree this?

Signature · 12 lines
A new email address of FJWAN is launched from Apr.1 2007.
The updated address is: [email protected] --------------------------------------------------
Wei Yongjun
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
8/F., Civil Defense Building, No.189 Guangzhou Road,
Nanjing, 210029, China
TEL: +86+25-86630523-858
COINS: 79955-858
FAX: +86+25-83317685
MAIL: [email protected]
--------------------------------------------------
#5 lore raw
Quoted 4 lines · Wei Yongjun

So I want to know how the route announce a MTU larger then 576, such as 1280? RFC says ICMP error message return as much as we can without exceeding 576 bytes.

I think there is a misunderstanding here. The RFC is talking about how much of the payload may be included in the ICMP packet. It is not talking about the length field in the original IP header. That must be left untouched.

Quoted 4 lines

And ipv4 router alaways return as a packet size 576 because of this. If MTU is greater then 576, HOST will used "mtu = guess_mtu(old_mtu)" to get a MTU. Method of send ICMP Fragmentation Needed message is difference from receive,

Which router is doing that?

Cheers,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#6 lore raw
Quoted 12 lines · Wei Yongjun
Quoted 3 lines

So I want to know how the route announce a MTU larger then 576, such as 1280? RFC says ICMP error message return as much as we can without exceeding 576 bytes.

I think there is a misunderstanding here. The RFC is talking about how much of the payload may be included in the ICMP packet. It is not talking about the length field in the original IP header. That must be left untouched.

As you said, the RFC is talking about the payload of ICMP packet, it's not greater then 576, if router announce a MTU larger then 1280, the original IP header must be a size of 704? The format of ICMP message is like this:
IPv4 header
ICMP header
payload

Quoted 8 lines
Quoted 3 lines

And ipv4 router alaways return as a packet size 576 because of this.
If MTU is greater then 576, HOST will used "mtu = guess_mtu(old_mtu)" to get a MTU. Method of send ICMP Fragmentation Needed message is difference from receive,

Which router is doing that?

The latest kernel 2.6.21.3 also doing so. The rule to send ICMP message limit this. Ref to net/ipv4/icmp.c
line 433 void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) line 434 {
...
line 572 /* RFC says return as much as we can without exceeding 576 bytes. */
line 573
line 574 room = dst_mtu(&rt->u.dst);
line 575 if (room > 576)
line 576 room = 576;
line 577 room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen;
line 578 room -= sizeof(struct icmphdr);
line 579
line 560 icmp_param.data_len = skb_in->len - icmp_param.offset;
line 561 if (icmp_param.data_len > room)
line 562 icmp_param.data_len = room;
line 563 icmp_param.head_len = sizeof(struct icmphdr);

line 576 do this.

Signature · 12 lines
A new email address of FJWAN is launched from Apr.1 2007.
The updated address is: [email protected] --------------------------------------------------
Wei Yongjun
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
8/F., Civil Defense Building, No.189 Guangzhou Road,
Nanjing, 210029, China
TEL: +86+25-86630523-858
COINS: 79955-858
FAX: +86+25-83317685
MAIL: [email protected]
--------------------------------------------------
#7 lore raw
Quoted 22 lines · Wei Yongjun

The latest kernel 2.6.21.3 also doing so. The rule to send ICMP message limit this.
Ref to net/ipv4/icmp.c
line 433 void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
line 434 {
...
line 572 /* RFC says return as much as we can without exceeding 576
bytes. */
line 573
line 574 room = dst_mtu(&rt->u.dst);
line 575 if (room > 576)
line 576 room = 576;
line 577 room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen;
line 578 room -= sizeof(struct icmphdr);
line 579
line 560 icmp_param.data_len = skb_in->len - icmp_param.offset;
line 561 if (icmp_param.data_len > room)
line 562 icmp_param.data_len = room;
line 563 icmp_param.head_len = sizeof(struct icmphdr);

Quoted 1 line

line 576 do this.

But this is not the old_mtu field that we were talking about. The old_mtu field comes from iph->tot_len which is the length of field in the *original* IP header. We're certainly not allowed touch that field.

Cheers,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
#8 lore raw

I know, I misunderstand the iph->tot_len, the ICMP payload is not contained a valid ipv4 packet. I do this under IPv6, it has no problem because IPv6 does not check this. ^_^

Thank you very much.

Quoted 7 lines

But this is not the old_mtu field that we were talking about. The old_mtu field comes from iph->tot_len which is the length of field in the *original* IP header. We're certainly not allowed touch that field.

Cheers,

Signature · 12 lines
A new email address of FJWAN is launched from Apr.1 2007.
The updated address is: [email protected] --------------------------------------------------
Wei Yongjun
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
8/F., Civil Defense Building, No.189 Guangzhou Road,
Nanjing, 210029, China
TEL: +86+25-86630523-858
COINS: 79955-858
FAX: +86+25-83317685
MAIL: [email protected]
--------------------------------------------------
#9 lore raw

Hello,

I have a new query regarding the jumbo frames support in ICMP.

I am supporting jumbo frame support for self tx/rx.

So I need to handle the icmp reply and request for size of 9000.

i was able to ping upto max 3000 size. more than that icmp echo response is not generated????

why is this???

any limitation?