Skip to contentSkip to conversation

SNMPv2 "ipv6IfStatsOutFragCreates" counter error

PATCH In review weidong 3 participants 3 messages Jul 31, 2006 – Aug 2, 2006

Subsystems (3)
lore
Share & tools
lore

weidong

author
#0 lore raw

PATCH 1/1 SNMPv2 "ipv6IfStatsOutFragCreates" counter error

Hi, All
When I tested linux kernel 2.6.71.7 about statistics
"ipv6IfStatsOutFragCreates", and found that it couldn't increase correctly. The criteria is RFC 2465:

ipv6IfStatsOutFragCreates OBJECT-TYPE

      SYNTAX      Counter32
      MAX-ACCESS  read-only
      STATUS      current

DESCRIPTION
"The number of output datagram fragments that have been generated as a result of fragmentation at this output interface."
::= { ipv6IfStatsEntry 15 }

I think there are two issues in Linux kernel.
1st:
RFC2465 specifies the counter is "The number of output datagram fragments...". I think increasing this counter after output a fragment successfully is better. And it should not be increased even though a fragment is created but failed to output.

2nd:
If we send a big ICMP/ICMPv6 echo request to a host, and receive ICMP/ICMPv6 echo reply consisted of some fragments. As we know that in Linux kernel first fragmentation occurs in ICMP layer(maybe saying transport layer is better), but this is not the "real" fragmentation,just do some "pre-fragment" -- allocate space for date, and form a frag_list, etc. The "real" fragmentation happens in IP layer -- set offset and MF flag and so on. So I think in "fast path" for ip_fragment/ip6_fragment, if we send a fragment which "pre-fragment" by upper layer we should also increase "ipv6IfStatsOutFragCreates".

The following is the patch for the issues mentioned above:

net/ipv4/ip_output.c +4 -3
diff -ruN old/net/ipv4/ip_output.c new/net/ipv4/ip_output.c
@@ -527,6 +527,8 @@
 
 			err = output(skb);
 
+			if (!err)
+				IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
 			if (err || !frag)
 				break;
 
@@ -650,9 +652,6 @@
 		/*
 		 *	Put this fragment into the sending queue.
 		 */
-
-		IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
-
 		iph->tot_len = htons(len + hlen);
 
 		ip_send_check(iph);
@@ -660,6 +659,8 @@
 		err = output(skb2);
 		if (err)
 			goto fail;
+
+		IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
 	}
 	kfree_skb(skb);
 	IP_INC_STATS(IPSTATS_MIB_FRAGOKS);
net/ipv6/ip6_output.c +5 -3
diff -ruN old/net/ipv6/ip6_output.c new/net/ipv6/ip6_output.c
@@ -593,6 +593,9 @@
 			}
 			
 			err = output(skb);
+			if(!err)
+				IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
+	
 			if (err || !frag)
 				break;
 
@@ -704,12 +707,11 @@
 		/*
 		 *	Put this fragment into the sending queue.
 		 */
-
-		IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
-
 		err = output(frag);
 		if (err)
 			goto fail;
+
+		IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
 	}
 	kfree_skb(skb);
 	IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);

Regards
Wei Dong