aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Dong <weid@nanjing-fnst.com>2006-08-02 16:41:21 -0400
committerDavid S. Miller <davem@davemloft.net>2006-08-02 16:41:21 -0400
commitdafee490858f79e144c5e6cdd84ceb9efa20a3f1 (patch)
treeb14c78f41845026fd2ab161a7348d898a2fa6d3e
parent32c524d1c48b62be49fa1b1dd93fed10792debc0 (diff)
[IPV6]: SNMPv2 "ipv6IfStatsOutFragCreates" counter error
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". Signed-off-by: Wei Dong <weid@nanjing-fnst.com> Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/ip_output.c7
-rw-r--r--net/ipv6/ip6_output.c8
2 files changed, 9 insertions, 6 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7c9f9a6421b8..9bf307a29783 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -526,6 +526,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
526 526
527 err = output(skb); 527 err = output(skb);
528 528
529 if (!err)
530 IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
529 if (err || !frag) 531 if (err || !frag)
530 break; 532 break;
531 533
@@ -649,9 +651,6 @@ slow_path:
649 /* 651 /*
650 * Put this fragment into the sending queue. 652 * Put this fragment into the sending queue.
651 */ 653 */
652
653 IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
654
655 iph->tot_len = htons(len + hlen); 654 iph->tot_len = htons(len + hlen);
656 655
657 ip_send_check(iph); 656 ip_send_check(iph);
@@ -659,6 +658,8 @@ slow_path:
659 err = output(skb2); 658 err = output(skb2);
660 if (err) 659 if (err)
661 goto fail; 660 goto fail;
661
662 IP_INC_STATS(IPSTATS_MIB_FRAGCREATES);
662 } 663 }
663 kfree_skb(skb); 664 kfree_skb(skb);
664 IP_INC_STATS(IPSTATS_MIB_FRAGOKS); 665 IP_INC_STATS(IPSTATS_MIB_FRAGOKS);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 70c9234b70e7..69451af6abe7 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -596,6 +596,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
596 } 596 }
597 597
598 err = output(skb); 598 err = output(skb);
599 if(!err)
600 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
601
599 if (err || !frag) 602 if (err || !frag)
600 break; 603 break;
601 604
@@ -707,12 +710,11 @@ slow_path:
707 /* 710 /*
708 * Put this fragment into the sending queue. 711 * Put this fragment into the sending queue.
709 */ 712 */
710
711 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
712
713 err = output(frag); 713 err = output(frag);
714 if (err) 714 if (err)
715 goto fail; 715 goto fail;
716
717 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES);
716 } 718 }
717 kfree_skb(skb); 719 kfree_skb(skb);
718 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); 720 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);