netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
@ 2004-03-17 19:30 Shirley Ma
  2004-03-19  6:06 ` David S. Miller
                   ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: Shirley Ma @ 2004-03-17 19:30 UTC (permalink / raw)
  To: davem; +Cc: netdev, xma

[-- Attachment #1: Type: text/plain, Size: 172 bytes --]

This patch is against Linux 2.6.4 kernel. It has been tested, 'ip' utility 
works fine. This patch is used by IPv6 MIBs.


-- 
Thanks
Shirley Ma
IBM Linux Technology Center

[-- Attachment #2: linux-2.6.4-ipv6mib.patch --]
[-- Type: text/x-diff, Size: 5702 bytes --]

diff -urN linux-2.6.4/include/linux/rtnetlink.h linux-2.6.4-ipv6mib/include/linux/rtnetlink.h
--- linux-2.6.4/include/linux/rtnetlink.h	2004-03-10 18:55:42.000000000 -0800
+++ linux-2.6.4-ipv6mib/include/linux/rtnetlink.h	2004-03-16 16:41:26.000000000 -0800
@@ -47,7 +47,13 @@
 #define RTM_NEWPREFIX	(RTM_BASE+36)
 #define RTM_GETPREFIX	(RTM_BASE+38)
 
-#define	RTM_MAX		(RTM_BASE+39)
+#define	RTM_NEWMULTICAST (RTM_BASE+40)
+#define	RTM_GETMULTICAST (RTM_BASE+42)
+
+#define	RTM_NEWANYCAST	(RTM_BASE+44)
+#define	RTM_GETANYCAST	(RTM_BASE+46)
+
+#define	RTM_MAX		(RTM_BASE+47)
 
 /* 
    Generic structure for encapsulation of optional route information.
@@ -339,6 +345,7 @@
 	IFA_LOCAL,
 	IFA_LABEL,
 	IFA_BROADCAST,
+	IFA_MULTICAST,
 	IFA_ANYCAST,
 	IFA_CACHEINFO
 };
@@ -350,6 +357,10 @@
 #define IFA_F_SECONDARY		0x01
 #define IFA_F_TEMPORARY		IFA_F_SECONDARY
 
+#define IFA_F_ADDRESS		0x02
+#define IFA_F_MULTICAST 	0x04
+#define IFA_F_ANYCAST		0x08
+
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
 #define IFA_F_PERMANENT		0x80
diff -urN linux-2.6.4/net/ipv6/addrconf.c linux-2.6.4-ipv6mib/net/ipv6/addrconf.c
--- linux-2.6.4/net/ipv6/addrconf.c	2004-03-10 18:55:44.000000000 -0800
+++ linux-2.6.4-ipv6mib/net/ipv6/addrconf.c	2004-03-17 10:09:45.000000000 -0800
@@ -2571,7 +2571,7 @@
 	if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifmca->idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifmca->mca_addr);
+	RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2608,7 +2608,7 @@
 	if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifaca->aca_addr);
+	RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2627,7 +2627,8 @@
 	return -1;
 }
 
-static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+			   unsigned char flags)
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
@@ -2651,28 +2652,54 @@
 		if ((idev = in6_dev_get(dev)) == NULL)
 			continue;
 		read_lock_bh(&idev->lock);
-		/* unicast address */
-		for (ifa = idev->addr_list; ifa;
-		     ifa = ifa->if_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
-				goto done;
-		}
-		/* temp addr */
+		if (flags & IFA_F_ADDRESS) {
+			/* unicast address */
+			for (ifa = idev->addr_list; ifa;
+			     ifa = ifa->if_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+					goto done;
+			}
+			/* temp addr */
 #ifdef CONFIG_IPV6_PRIVACY
-		for (ifa = idev->tempaddr_list; ifa; 
-		     ifa = ifa->tmp_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
-				goto done;
-		}
+			for (ifa = idev->tempaddr_list; ifa; 
+			     ifa = ifa->tmp_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
+					goto done;
+			}
 #endif
+		}
+		if (flags & IFA_F_MULTICAST) {
+			/* multicast address */
+			for (ifmca = idev->mc_list; ifmca; 
+			     ifmca = ifmca->next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWMULTICAST)) <= 0)
+					goto done;
+			}
+		}
+		if (flags & IFA_F_ANYCAST) {
+			/* anycast address */
+			for (ifaca = idev->ac_list; ifaca;
+			     ifaca = ifaca->aca_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWANYCAST)) <= 0) 
+					goto done;
+			}
+		}
 		read_unlock_bh(&idev->lock);
 		in6_dev_put(idev);
 	}
@@ -2687,6 +2714,25 @@
 	return skb->len;
 }
 
+static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_ADDRESS;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
+static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_MULTICAST;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
+
+static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_ANYCAST;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
 {
 	struct sk_buff *skb;
@@ -2911,6 +2957,8 @@
 	[RTM_NEWADDR - RTM_BASE] = { .doit	= inet6_rtm_newaddr, },
 	[RTM_DELADDR - RTM_BASE] = { .doit	= inet6_rtm_deladdr, },
 	[RTM_GETADDR - RTM_BASE] = { .dumpit	= inet6_dump_ifaddr, },
+	[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
+	[RTM_GETANYCAST - RTM_BASE] = { .dumpit	= inet6_dump_ifacaddr, },
 	[RTM_NEWROUTE - RTM_BASE] = { .doit	= inet6_rtm_newroute, },
 	[RTM_DELROUTE - RTM_BASE] = { .doit	= inet6_rtm_delroute, },
 	[RTM_GETROUTE - RTM_BASE] = { .doit	= inet6_rtm_getroute,

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-17 19:30 [PATCH]dump interface IPv6 multicast/anycast addresses through netlink Shirley Ma
@ 2004-03-19  6:06 ` David S. Miller
  2004-03-19  6:52   ` YOSHIFUJI Hideaki / 吉藤英明
  2004-03-19  6:55 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 20:19 ` [PATCH] pmtu check conditions error in IPv6 Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-03-19  6:06 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, xma

On Wed, 17 Mar 2004 11:30:30 -0800
Shirley Ma <mashirle@us.ibm.com> wrote:

> This patch is against Linux 2.6.4 kernel. It has been tested, 'ip' utility 
> works fine. This patch is used by IPv6 MIBs.

Are we really going to support adding anycast/multicast addresses using
RTM_NEW{MULTI,ANY}CAST rtmsgs?  If not, let's not add them.

Otherwise I like your patch.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-19  6:06 ` David S. Miller
@ 2004-03-19  6:52   ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 0 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-03-19  6:52 UTC (permalink / raw)
  To: davem; +Cc: mashirle, netdev, xma, yoshfuji

In article <20040318220647.3dbb9c43.davem@redhat.com> (at Thu, 18 Mar 2004 22:06:47 -0800), "David S. Miller" <davem@redhat.com> says:

> On Wed, 17 Mar 2004 11:30:30 -0800
> Shirley Ma <mashirle@us.ibm.com> wrote:
> 
> > This patch is against Linux 2.6.4 kernel. It has been tested, 'ip' utility 
> > works fine. This patch is used by IPv6 MIBs.
> 
> Are we really going to support adding anycast/multicast addresses using
> RTM_NEW{MULTI,ANY}CAST rtmsgs?  If not, let's not add them.
> 
> Otherwise I like your patch.

I think we'd like to do so (for anycast at least).

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-17 19:30 [PATCH]dump interface IPv6 multicast/anycast addresses through netlink Shirley Ma
  2004-03-19  6:06 ` David S. Miller
@ 2004-03-19  6:55 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-03-19  7:16   ` Shirley Ma
  2004-05-26 20:19 ` [PATCH] pmtu check conditions error in IPv6 Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-03-19  6:55 UTC (permalink / raw)
  To: mashirle; +Cc: davem, netdev, xma, yoshfuji

In article <200403171130.30282.mashirle@us.ibm.com> (at Wed, 17 Mar 2004 11:30:30 -0800), Shirley Ma <mashirle@us.ibm.com> says:

> @@ -339,6 +345,7 @@
>  	IFA_LOCAL,
>  	IFA_LABEL,
>  	IFA_BROADCAST,
> +	IFA_MULTICAST,
>  	IFA_ANYCAST,
>  	IFA_CACHEINFO
>  };

Please, please do not change IFA_XXX values.
You should put "IFA_MULTICAST" next to IFA_CACHEINFO.

--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-19  6:55 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-03-19  7:16   ` Shirley Ma
  2004-03-19  7:32     ` David S. Miller
                       ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: Shirley Ma @ 2004-03-19  7:16 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, mashirle, netdev, netdev-bounce, yoshfuji


[-- Attachment #1.1: Type: text/plain, Size: 2482 bytes --]






Thanks for your comments.

I am going to modify the patch,
removing RTM_NEWMULTICAST replaced by RTM_GETMULTICAST,
removing RTM_NEWANYCAST replaced by RTM_GETANYCAST.
IFA_MULTICAST must be added last!

RTM_NEWANYCAST could be added later for adding anycast
addresses through netlink as a seperate patch.

I will resubmit the patch after I come back from my vacation one week
later.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228




                                                                       
             YOSHIFUJI Hideaki                                         
             / 吉藤英明                                      
             <yoshfuji@linux-i                                          To
             pv6.org>                  mashirle@us.ltcfwd.linux.ibm.com
             Sent by:                                                   cc
             netdev-bounce@oss         davem@redhat.com,               
             .sgi.com                  netdev@oss.sgi.com, Shirley     
                                       Ma/Beaverton/IBM@IBMUS,         
                                       yoshfuji@linux-ipv6.org         
             03/18/2004 10:55                                      Subject
             PM                        Re: [PATCH]dump interface IPv6  
                                       multicast/anycast addresses through
                                       netlink                         
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       




In article <200403171130.30282.mashirle@us.ibm.com> (at Wed, 17 Mar 2004
11:30:30 -0800), Shirley Ma <mashirle@us.ibm.com> says:

> @@ -339,6 +345,7 @@
>            IFA_LOCAL,
>            IFA_LABEL,
>            IFA_BROADCAST,
> +          IFA_MULTICAST,
>            IFA_ANYCAST,
>            IFA_CACHEINFO
>  };

Please, please do not change IFA_XXX values.
You should put "IFA_MULTICAST" next to IFA_CACHEINFO.

--yoshfuji


[-- Attachment #1.2: Type: text/html, Size: 3740 bytes --]

[-- Attachment #2: graycol.gif --]
[-- Type: image/gif, Size: 105 bytes --]

[-- Attachment #3: pic12001.gif --]
[-- Type: image/gif, Size: 1255 bytes --]

[-- Attachment #4: ecblank.gif --]
[-- Type: image/gif, Size: 45 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-19  7:16   ` Shirley Ma
@ 2004-03-19  7:32     ` David S. Miller
  2004-03-19  8:03       ` Shirley Ma
  2004-03-31 18:07     ` Shirley Ma
  2004-03-31 21:26     ` [PATCH]Add IPv6 MIBs counters in MLD (mcast.c) Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-03-19  7:32 UTC (permalink / raw)
  To: Shirley Ma; +Cc: YOSHIFUJI.Hideaki/mashirle, netdev, netdev-bounce, yoshfuji

On Thu, 18 Mar 2004 23:16:52 -0800
Shirley Ma <xma@us.ibm.com> wrote:

> I am going to modify the patch,
> removing RTM_NEWMULTICAST replaced by RTM_GETMULTICAST,
> removing RTM_NEWANYCAST replaced by RTM_GETANYCAST.

Please remember to number the RTM_* values correctly, the low
order bits tell if the operation does a read or write
operation.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-19  7:32     ` David S. Miller
@ 2004-03-19  8:03       ` Shirley Ma
  0 siblings, 0 replies; 47+ messages in thread
From: Shirley Ma @ 2004-03-19  8:03 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, netdev-bounce, yoshfuji, YOSHIFUJI.Hideaki

[-- Attachment #1: Type: text/plain, Size: 158 bytes --]





Yes. I will.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228

[-- Attachment #2: Type: text/html, Size: 225 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-19  7:16   ` Shirley Ma
  2004-03-19  7:32     ` David S. Miller
@ 2004-03-31 18:07     ` Shirley Ma
  2004-04-01  4:50       ` YOSHIFUJI Hideaki / 吉藤英明
  2004-03-31 21:26     ` [PATCH]Add IPv6 MIBs counters in MLD (mcast.c) Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-03-31 18:07 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji, xma

[-- Attachment #1: Type: text/plain, Size: 118 bytes --]

Here is the new patch. It has been tested against linux 2.6.4 kernel.

Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.4-ipv6mib.patch.new --]
[-- Type: text/x-diff, Size: 5660 bytes --]

diff -urN linux-2.6.4/include/linux/rtnetlink.h linux-2.6.4-ipv6mib/include/linux/rtnetlink.h
--- linux-2.6.4/include/linux/rtnetlink.h	2004-03-10 18:55:42.000000000 -0800
+++ linux-2.6.4-ipv6mib/include/linux/rtnetlink.h	2004-03-31 09:39:42.003799768 -0800
@@ -47,7 +47,11 @@
 #define RTM_NEWPREFIX	(RTM_BASE+36)
 #define RTM_GETPREFIX	(RTM_BASE+38)
 
-#define	RTM_MAX		(RTM_BASE+39)
+#define	RTM_GETMULTICAST (RTM_BASE+42)
+
+#define	RTM_GETANYCAST	(RTM_BASE+46)
+
+#define	RTM_MAX		(RTM_BASE+47)
 
 /* 
    Generic structure for encapsulation of optional route information.
@@ -340,7 +344,8 @@
 	IFA_LABEL,
 	IFA_BROADCAST,
 	IFA_ANYCAST,
-	IFA_CACHEINFO
+	IFA_CACHEINFO,
+	IFA_MULTICAST
 };
 
 #define IFA_MAX IFA_CACHEINFO
@@ -350,6 +355,10 @@
 #define IFA_F_SECONDARY		0x01
 #define IFA_F_TEMPORARY		IFA_F_SECONDARY
 
+#define IFA_F_ADDRESS		0x02
+#define IFA_F_MULTICAST 	0x04
+#define IFA_F_ANYCAST		0x08
+
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
 #define IFA_F_PERMANENT		0x80
diff -urN linux-2.6.4/net/ipv6/addrconf.c linux-2.6.4-ipv6mib/net/ipv6/addrconf.c
--- linux-2.6.4/net/ipv6/addrconf.c	2004-03-10 18:55:44.000000000 -0800
+++ linux-2.6.4-ipv6mib/net/ipv6/addrconf.c	2004-03-31 09:39:04.975428936 -0800
@@ -2571,7 +2571,7 @@
 	if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifmca->idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifmca->mca_addr);
+	RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2608,7 +2608,7 @@
 	if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifaca->aca_addr);
+	RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2627,7 +2627,8 @@
 	return -1;
 }
 
-static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+			   unsigned char flags)
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
@@ -2651,28 +2652,54 @@
 		if ((idev = in6_dev_get(dev)) == NULL)
 			continue;
 		read_lock_bh(&idev->lock);
-		/* unicast address */
-		for (ifa = idev->addr_list; ifa;
-		     ifa = ifa->if_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
-				goto done;
-		}
-		/* temp addr */
+		if (flags & IFA_F_ADDRESS) {
+			/* unicast address */
+			for (ifa = idev->addr_list; ifa;
+			     ifa = ifa->if_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+					goto done;
+			}
+			/* temp addr */
 #ifdef CONFIG_IPV6_PRIVACY
-		for (ifa = idev->tempaddr_list; ifa; 
-		     ifa = ifa->tmp_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
-				goto done;
-		}
+			for (ifa = idev->tempaddr_list; ifa; 
+			     ifa = ifa->tmp_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
+					goto done;
+			}
 #endif
+		}
+		if (flags & IFA_F_MULTICAST) {
+			/* multicast address */
+			for (ifmca = idev->mc_list; ifmca; 
+			     ifmca = ifmca->next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
+					goto done;
+			}
+		}
+		if (flags & IFA_F_ANYCAST) {
+			/* anycast address */
+			for (ifaca = idev->ac_list; ifaca;
+			     ifaca = ifaca->aca_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
+					goto done;
+			}
+		}
 		read_unlock_bh(&idev->lock);
 		in6_dev_put(idev);
 	}
@@ -2687,6 +2714,25 @@
 	return skb->len;
 }
 
+static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_ADDRESS;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
+static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_MULTICAST;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
+
+static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	unsigned char flag = IFA_F_ANYCAST;
+	return inet6_dump_addr(skb, cb, flag);
+}
+
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
 {
 	struct sk_buff *skb;
@@ -2911,6 +2957,8 @@
 	[RTM_NEWADDR - RTM_BASE] = { .doit	= inet6_rtm_newaddr, },
 	[RTM_DELADDR - RTM_BASE] = { .doit	= inet6_rtm_deladdr, },
 	[RTM_GETADDR - RTM_BASE] = { .dumpit	= inet6_dump_ifaddr, },
+	[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
+	[RTM_GETANYCAST - RTM_BASE] = { .dumpit	= inet6_dump_ifacaddr, },
 	[RTM_NEWROUTE - RTM_BASE] = { .doit	= inet6_rtm_newroute, },
 	[RTM_DELROUTE - RTM_BASE] = { .doit	= inet6_rtm_delroute, },
 	[RTM_GETROUTE - RTM_BASE] = { .doit	= inet6_rtm_getroute,

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH]Add IPv6 MIBs counters in MLD (mcast.c)
  2004-03-19  7:16   ` Shirley Ma
  2004-03-19  7:32     ` David S. Miller
  2004-03-31 18:07     ` Shirley Ma
@ 2004-03-31 21:26     ` Shirley Ma
  2004-04-03 22:30       ` David S. Miller
  2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
  2 siblings, 2 replies; 47+ messages in thread
From: Shirley Ma @ 2004-03-31 21:26 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji, xma

[-- Attachment #1: Type: text/plain, Size: 112 bytes --]

Here is the patch against linux 2.6.4 kernel. Please review it.

Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.4-mld-ipv6mib.patch --]
[-- Type: text/x-diff, Size: 1627 bytes --]

diff -urN linux-2.6.4/net/ipv6/mcast.c linux-2.6.4-mld/net/ipv6/mcast.c
--- linux-2.6.4/net/ipv6/mcast.c	2004-03-10 18:55:43.000000000 -0800
+++ linux-2.6.4-mld/net/ipv6/mcast.c	2004-03-31 12:05:11.767673936 -0800
@@ -1317,6 +1317,7 @@
 	struct inet6_dev *idev = in6_dev_get(skb->dev);
 	int err;
 
+	IP6_INC_STATS(Ip6OutRequests);
 	payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
 		sizeof(struct ipv6hdr);
 	mldlen = skb->tail - skb->h.raw;
@@ -1326,8 +1327,12 @@
 		IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
 		dev_queue_xmit);
-	if (!err)
+	if (!err) {
 		ICMP6_INC_STATS(idev,Icmp6OutMsgs);
+		IP6_INC_STATS(Ip6OutMcastPkts);
+	} else
+		IP6_INC_STATS(Ip6OutDiscards);
+
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 }
@@ -1608,6 +1613,7 @@
 		     IPV6_TLV_ROUTERALERT, 2, 0, 0,
 		     IPV6_TLV_PADN, 0 };
 
+	IP6_INC_STATS(Ip6OutRequests);
 	snd_addr = addr;
 	if (type == ICMPV6_MGM_REDUCTION) {
 		snd_addr = &all_routers;
@@ -1620,8 +1626,10 @@
 
 	skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
 
-	if (skb == NULL)
+	if (skb == NULL) {
+		IP6_INC_STATS(Ip6OutDiscards);
 		return;
+	}
 
 	skb_reserve(skb, LL_RESERVED_SPACE(dev));
 	if (dev->hard_header) {
@@ -1664,13 +1672,16 @@
 		else
 			ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
 		ICMP6_INC_STATS(idev, Icmp6OutMsgs);
-	}
+		IP6_INC_STATS(Ip6OutMcastPkts);
+	} else
+		IP6_INC_STATS(Ip6OutDiscards);
 
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 	return;
 
 out:
+	IP6_INC_STATS(Ip6OutDiscards);
 	kfree_skb(skb);
 }
 

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-03-31 18:07     ` Shirley Ma
@ 2004-04-01  4:50       ` YOSHIFUJI Hideaki / 吉藤英明
  2004-04-01  5:18         ` Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-04-01  4:50 UTC (permalink / raw)
  To: mashirle; +Cc: davem, netdev, xma, yoshfuji

Hello.

In article <200403311007.01702.mashirle@us.ibm.com> (at Wed, 31 Mar 2004 10:07:01 -0800), Shirley Ma <mashirle@us.ibm.com> says:

> @@ -350,6 +355,10 @@
>  #define IFA_F_SECONDARY		0x01
>  #define IFA_F_TEMPORARY		IFA_F_SECONDARY
>  
> +#define IFA_F_ADDRESS		0x02
> +#define IFA_F_MULTICAST 	0x04
> +#define IFA_F_ANYCAST		0x08
> +
>  #define IFA_F_DEPRECATED	0x20
>  #define IFA_F_TENTATIVE		0x40
>  #define IFA_F_PERMANENT		0x80

Why do we need IFA_F_MULTICAST?
This is waste of flags.

> -static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
> +			   unsigned char flags)
                           unsigned char type)


> +		if (flags & IFA_F_ADDRESS) {

                    type == 0

> +			/* unicast address */
> +			for (ifa = idev->addr_list; ifa;
> +			     ifa = ifa->if_next, ip_idx++) {
> +				if (ip_idx < s_ip_idx)
> +					continue;
> +				if ((err = inet6_fill_ifaddr(skb, ifa, 
> +				    NETLINK_CB(cb->skb).pid, 
> +				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
> +					goto done;
> +			}
> +			/* temp addr */
>  #ifdef CONFIG_IPV6_PRIVACY
> -		for (ifa = idev->tempaddr_list; ifa; 
> -		     ifa = ifa->tmp_next, ip_idx++) {
> -			if (ip_idx < s_ip_idx)
> -				continue;
> -			if ((err = inet6_fill_ifaddr(skb, ifa, 
> -			    NETLINK_CB(cb->skb).pid, 
> -			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
> -				goto done;
> -		}
> +			for (ifa = idev->tempaddr_list; ifa; 
> +			     ifa = ifa->tmp_next, ip_idx++) {
> +				if (ip_idx < s_ip_idx)
> +					continue;
> +				if ((err = inet6_fill_ifaddr(skb, ifa, 
> +				    NETLINK_CB(cb->skb).pid, 
> +				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
> +					goto done;
> +			}
>  #endif
> +		}
> +		if (flags & IFA_F_MULTICAST) {
                    type == IFA_MULTICAST
> +			/* multicast address */
> +			for (ifmca = idev->mc_list; ifmca; 
> +			     ifmca = ifmca->next, ip_idx++) {
> +				if (ip_idx < s_ip_idx)
> +					continue;
> +				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
> +				    NETLINK_CB(cb->skb).pid, 
> +				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
> +					goto done;
> +			}
> +		}
> +		if (flags & IFA_F_ANYCAST) {
                    type == IFA_ANYCAST
> +			/* anycast address */
> +			for (ifaca = idev->ac_list; ifaca;
> +			     ifaca = ifaca->aca_next, ip_idx++) {
> +				if (ip_idx < s_ip_idx)
> +					continue;
> +				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
> +				    NETLINK_CB(cb->skb).pid, 
> +				    cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
> +					goto done;
> +			}
> +		}
>  		read_unlock_bh(&idev->lock);
>  		in6_dev_put(idev);
>  	}
> @@ -2687,6 +2714,25 @@
>  	return skb->len;
>  }
>  
> +static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> +	unsigned char flag = IFA_F_ADDRESS;
> +	return inet6_dump_addr(skb, cb, flag);
                                        0
> +}
> +
> +static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> +	unsigned char flag = IFA_F_MULTICAST;
> +	return inet6_dump_addr(skb, cb, flag);
                                        IFA_MULTICAST
> +}
> +
> +
> +static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> +	unsigned char flag = IFA_F_ANYCAST;
> +	return inet6_dump_addr(skb, cb, flag);
                                        IFA_ANYCAST
> +}
> +
>  static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
>  {
>  	struct sk_buff *skb;


Of course, we can use switch-case.

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-04-01  4:50       ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-04-01  5:18         ` Shirley Ma
  2004-04-01 18:28           ` Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-04-01  5:18 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, mashirle, netdev, Hideaki YOSHIFUJI, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 383 bytes --]





The reason to add these flags was for rtnetlink MATCH request through
RTM_GETADDRESS. Since here we use RTM_GETMULTICAST,
RTM_GETANYCAST for getting multicast/anycast addresses, it's not
necessary to have these flags. I will remove them.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228

[-- Attachment #2: Type: text/html, Size: 465 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-04-01  5:18         ` Shirley Ma
@ 2004-04-01 18:28           ` Shirley Ma
  2004-04-03 22:45             ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-04-01 18:28 UTC (permalink / raw)
  To: Shirley Ma, YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, netdev, Hideaki YOSHIFUJI, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 118 bytes --]

Here is the new patch. It has been tested against linux 2.6.4 kernel.

Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.4-ipv6mib.patch.new1 --]
[-- Type: text/x-diff, Size: 5499 bytes --]

diff -urN linux-2.6.4/include/linux/rtnetlink.h linux-2.6.4-ipv6mib/include/linux/rtnetlink.h
--- linux-2.6.4/include/linux/rtnetlink.h	2004-03-10 18:55:42.000000000 -0800
+++ linux-2.6.4-ipv6mib/include/linux/rtnetlink.h	2004-04-01 09:18:16.165353048 -0800
@@ -47,7 +47,11 @@
 #define RTM_NEWPREFIX	(RTM_BASE+36)
 #define RTM_GETPREFIX	(RTM_BASE+38)
 
-#define	RTM_MAX		(RTM_BASE+39)
+#define	RTM_GETMULTICAST (RTM_BASE+42)
+
+#define	RTM_GETANYCAST	(RTM_BASE+46)
+
+#define	RTM_MAX		(RTM_BASE+47)
 
 /* 
    Generic structure for encapsulation of optional route information.
@@ -340,7 +344,8 @@
 	IFA_LABEL,
 	IFA_BROADCAST,
 	IFA_ANYCAST,
-	IFA_CACHEINFO
+	IFA_CACHEINFO,
+	IFA_MULTICAST
 };
 
 #define IFA_MAX IFA_CACHEINFO
diff -urN linux-2.6.4/net/ipv6/addrconf.c linux-2.6.4-ipv6mib/net/ipv6/addrconf.c
--- linux-2.6.4/net/ipv6/addrconf.c	2004-03-10 18:55:44.000000000 -0800
+++ linux-2.6.4-ipv6mib/net/ipv6/addrconf.c	2004-04-01 09:56:16.340713704 -0800
@@ -2571,7 +2571,7 @@
 	if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifmca->idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifmca->mca_addr);
+	RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2608,7 +2608,7 @@
 	if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
 		ifm->ifa_scope = RT_SCOPE_SITE;
 	ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
-	RTA_PUT(skb, IFA_ADDRESS, 16, &ifaca->aca_addr);
+	RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
 	ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
 		    * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
 		    * 100 / HZ);
@@ -2627,7 +2627,14 @@
 	return -1;
 }
 
-static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+enum addr_type_t
+{
+	UNICAST_ADDR,
+	MULTICAST_ADDR,
+	ANYCAST_ADDR,
+};
+static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+			   enum addr_type_t type)
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
@@ -2651,28 +2658,58 @@
 		if ((idev = in6_dev_get(dev)) == NULL)
 			continue;
 		read_lock_bh(&idev->lock);
-		/* unicast address */
-		for (ifa = idev->addr_list; ifa;
-		     ifa = ifa->if_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
-				goto done;
-		}
-		/* temp addr */
+		switch (type) {
+		case UNICAST_ADDR:
+			/* unicast address */
+			for (ifa = idev->addr_list; ifa;
+			     ifa = ifa->if_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+					goto done;
+			}
+			/* temp addr */
 #ifdef CONFIG_IPV6_PRIVACY
-		for (ifa = idev->tempaddr_list; ifa; 
-		     ifa = ifa->tmp_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
-				goto done;
-		}
+			for (ifa = idev->tempaddr_list; ifa; 
+			     ifa = ifa->tmp_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
+					goto done;
+			}
 #endif
+			break;
+		case MULTICAST_ADDR:
+			/* multicast address */
+			for (ifmca = idev->mc_list; ifmca; 
+			     ifmca = ifmca->next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
+					goto done;
+			}
+			break;
+		case ANYCAST_ADDR:
+			/* anycast address */
+			for (ifaca = idev->ac_list; ifaca;
+			     ifaca = ifaca->aca_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
+					goto done;
+			}
+			break;
+		default:
+			break;
+		}
 		read_unlock_bh(&idev->lock);
 		in6_dev_put(idev);
 	}
@@ -2687,6 +2724,25 @@
 	return skb->len;
 }
 
+static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = UNICAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
+static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = MULTICAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
+
+static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = ANYCAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
 {
 	struct sk_buff *skb;
@@ -2911,6 +2967,8 @@
 	[RTM_NEWADDR - RTM_BASE] = { .doit	= inet6_rtm_newaddr, },
 	[RTM_DELADDR - RTM_BASE] = { .doit	= inet6_rtm_deladdr, },
 	[RTM_GETADDR - RTM_BASE] = { .dumpit	= inet6_dump_ifaddr, },
+	[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
+	[RTM_GETANYCAST - RTM_BASE] = { .dumpit	= inet6_dump_ifacaddr, },
 	[RTM_NEWROUTE - RTM_BASE] = { .doit	= inet6_rtm_newroute, },
 	[RTM_DELROUTE - RTM_BASE] = { .doit	= inet6_rtm_delroute, },
 	[RTM_GETROUTE - RTM_BASE] = { .doit	= inet6_rtm_getroute,

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add IPv6 MIBs counters in MLD (mcast.c)
  2004-03-31 21:26     ` [PATCH]Add IPv6 MIBs counters in MLD (mcast.c) Shirley Ma
@ 2004-04-03 22:30       ` David S. Miller
  2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
  1 sibling, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-04-03 22:30 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, yoshfuji, xma

On Wed, 31 Mar 2004 13:26:43 -0800
Shirley Ma <mashirle@us.ibm.com> wrote:

> Here is the patch against linux 2.6.4 kernel. Please review it.

Patch applied, thanks Shirley.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-04-01 18:28           ` Shirley Ma
@ 2004-04-03 22:45             ` David S. Miller
  2004-04-05 20:51               ` Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-04-03 22:45 UTC (permalink / raw)
  To: Shirley Ma; +Cc: xma, yoshfuji, netdev, yoshfuji

On Thu, 1 Apr 2004 10:28:12 -0800
Shirley Ma <mashirle@us.ibm.com> wrote:

> Here is the new patch. It has been tested against linux 2.6.4 kernel.

I'm Ok with this patch and I believe Yoshfuji et al. are too.

But this patch will not apply cleanly to current 2.6.x sources,
please rediff.

Thanks.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-04-03 22:45             ` David S. Miller
@ 2004-04-05 20:51               ` Shirley Ma
  2004-04-05 21:42                 ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-04-05 20:51 UTC (permalink / raw)
  To: David S. Miller; +Cc: xma, yoshfuji, netdev, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 180 bytes --]

Dumping multicast/anycast api was removed in Linux 2.6.5 kernel, so it
couldn't be applied cleanly.
I recreated the patch. This patch has been tested against linux-2.6.5 kernel.



[-- Attachment #2: linux-2.6.5-ipv6mib.patch --]
[-- Type: text/x-diff, Size: 7426 bytes --]

diff -urN linux-2.6.5/include/linux/rtnetlink.h linux-2.6.5-ipv6mib/include/linux/rtnetlink.h
--- linux-2.6.5/include/linux/rtnetlink.h	2004-04-03 19:37:42.000000000 -0800
+++ linux-2.6.5-ipv6mib/include/linux/rtnetlink.h	2004-04-05 13:13:27.000000000 -0700
@@ -47,7 +47,11 @@
 #define RTM_NEWPREFIX	(RTM_BASE+36)
 #define RTM_GETPREFIX	(RTM_BASE+38)
 
-#define	RTM_MAX		(RTM_BASE+39)
+#define	RTM_GETMULTICAST (RTM_BASE+42)
+
+#define	RTM_GETANYCAST	(RTM_BASE+46)
+
+#define	RTM_MAX		(RTM_BASE+47)
 
 /* 
    Generic structure for encapsulation of optional route information.
@@ -340,7 +344,8 @@
 	IFA_LABEL,
 	IFA_BROADCAST,
 	IFA_ANYCAST,
-	IFA_CACHEINFO
+	IFA_CACHEINFO,
+	IFA_MULTICAST
 };
 
 #define IFA_MAX IFA_CACHEINFO
diff -urN linux-2.6.5/net/ipv6/addrconf.c linux-2.6.5-ipv6mib/net/ipv6/addrconf.c
--- linux-2.6.5/net/ipv6/addrconf.c	2004-04-03 19:38:17.000000000 -0800
+++ linux-2.6.5-ipv6mib/net/ipv6/addrconf.c	2004-04-05 13:20:34.194635432 -0700
@@ -2553,7 +2553,89 @@
 	return -1;
 }
 
-static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
+				u32 pid, u32 seq, int event)
+{
+	struct ifaddrmsg *ifm;
+	struct nlmsghdr  *nlh;
+	struct ifa_cacheinfo ci;
+	unsigned char	 *b = skb->tail;
+
+	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
+	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	ifm = NLMSG_DATA(nlh);
+	ifm->ifa_family = AF_INET6;	
+	ifm->ifa_prefixlen = 128;
+	ifm->ifa_flags = IFA_F_PERMANENT;
+	ifm->ifa_scope = RT_SCOPE_UNIVERSE;
+	if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE)
+		ifm->ifa_scope = RT_SCOPE_SITE;
+	ifm->ifa_index = ifmca->idev->dev->ifindex;
+	RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr);
+	ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ
+		    * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ
+		    * 100 / HZ);
+	ci.tstamp = (__u32)(TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) / HZ
+		    * 100 + TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) % HZ
+		    * 100 / HZ);
+	ci.ifa_prefered = INFINITY_LIFE_TIME;
+	ci.ifa_valid = INFINITY_LIFE_TIME;
+	RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	nlh->nlmsg_len = skb->tail - b;
+	return skb->len;
+
+nlmsg_failure:
+rtattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
+				u32 pid, u32 seq, int event)
+{
+	struct ifaddrmsg *ifm;
+	struct nlmsghdr  *nlh;
+	struct ifa_cacheinfo ci;
+	unsigned char	 *b = skb->tail;
+
+	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
+	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	ifm = NLMSG_DATA(nlh);
+	ifm->ifa_family = AF_INET6;	
+	ifm->ifa_prefixlen = 128;
+	ifm->ifa_flags = IFA_F_PERMANENT;
+	ifm->ifa_scope = RT_SCOPE_UNIVERSE;
+	if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE)
+		ifm->ifa_scope = RT_SCOPE_SITE;
+	ifm->ifa_index = ifaca->aca_idev->dev->ifindex;
+	RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr);
+	ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ
+		    * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ
+		    * 100 / HZ);
+	ci.tstamp = (__u32)(TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) / HZ
+		    * 100 + TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) % HZ
+		    * 100 / HZ);
+	ci.ifa_prefered = INFINITY_LIFE_TIME;
+	ci.ifa_valid = INFINITY_LIFE_TIME;
+	RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	nlh->nlmsg_len = skb->tail - b;
+	return skb->len;
+
+nlmsg_failure:
+rtattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+enum addr_type_t
+{
+	UNICAST_ADDR,
+	MULTICAST_ADDR,
+	ANYCAST_ADDR,
+};
+
+static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+			   enum addr_type_t type)
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
@@ -2561,7 +2643,9 @@
 	struct net_device *dev;
 	struct inet6_dev *idev = NULL;
 	struct inet6_ifaddr *ifa;
-	
+	struct ifmcaddr6 *ifmca;
+	struct ifacaddr6 *ifaca;
+
 	s_idx = cb->args[0];
 	s_ip_idx = ip_idx = cb->args[1];
 	read_lock(&dev_base_lock);
@@ -2575,28 +2659,58 @@
 		if ((idev = in6_dev_get(dev)) == NULL)
 			continue;
 		read_lock_bh(&idev->lock);
-		/* unicast address */
-		for (ifa = idev->addr_list; ifa;
-		     ifa = ifa->if_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
-				goto done;
-		}
-		/* temp addr */
+		switch (type) {
+		case UNICAST_ADDR:
+			/* unicast address */
+			for (ifa = idev->addr_list; ifa;
+			     ifa = ifa->if_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+					goto done;
+			}
+			/* temp addr */
 #ifdef CONFIG_IPV6_PRIVACY
-		for (ifa = idev->tempaddr_list; ifa; 
-		     ifa = ifa->tmp_next, ip_idx++) {
-			if (ip_idx < s_ip_idx)
-				continue;
-			if ((err = inet6_fill_ifaddr(skb, ifa, 
-			    NETLINK_CB(cb->skb).pid, 
-			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
-				goto done;
-		}
+			for (ifa = idev->tempaddr_list; ifa; 
+			     ifa = ifa->tmp_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifaddr(skb, ifa, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
+					goto done;
+			}
 #endif
+			break;
+		case MULTICAST_ADDR:
+			/* multicast address */
+			for (ifmca = idev->mc_list; ifmca; 
+			     ifmca = ifmca->next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
+					goto done;
+			}
+			break;
+		case ANYCAST_ADDR:
+			/* anycast address */
+			for (ifaca = idev->ac_list; ifaca;
+			     ifaca = ifaca->aca_next, ip_idx++) {
+				if (ip_idx < s_ip_idx)
+					continue;
+				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
+				    NETLINK_CB(cb->skb).pid, 
+				    cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
+					goto done;
+			}
+			break;
+		default:
+			break;
+		}
 		read_unlock_bh(&idev->lock);
 		in6_dev_put(idev);
 	}
@@ -2611,6 +2725,25 @@
 	return skb->len;
 }
 
+static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = UNICAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
+static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = MULTICAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
+
+static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	enum addr_type_t type = ANYCAST_ADDR;
+	return inet6_dump_addr(skb, cb, type);
+}
+
 static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
 {
 	struct sk_buff *skb;
@@ -2835,6 +2968,8 @@
 	[RTM_NEWADDR - RTM_BASE] = { .doit	= inet6_rtm_newaddr, },
 	[RTM_DELADDR - RTM_BASE] = { .doit	= inet6_rtm_deladdr, },
 	[RTM_GETADDR - RTM_BASE] = { .dumpit	= inet6_dump_ifaddr, },
+	[RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, },
+	[RTM_GETANYCAST - RTM_BASE] = { .dumpit	= inet6_dump_ifacaddr, },
 	[RTM_NEWROUTE - RTM_BASE] = { .doit	= inet6_rtm_newroute, },
 	[RTM_DELROUTE - RTM_BASE] = { .doit	= inet6_rtm_delroute, },
 	[RTM_GETROUTE - RTM_BASE] = { .doit	= inet6_rtm_getroute,

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]dump interface IPv6 multicast/anycast addresses through netlink
  2004-04-05 20:51               ` Shirley Ma
@ 2004-04-05 21:42                 ` David S. Miller
  2004-04-06  0:11                   ` Fix IPv6 MIBs counters in 2.6.5 kernel Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-04-05 21:42 UTC (permalink / raw)
  To: Shirley Ma; +Cc: xma, yoshfuji, netdev, yoshfuji

On Mon, 5 Apr 2004 13:51:09 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> Dumping multicast/anycast api was removed in Linux 2.6.5 kernel, so it
> couldn't be applied cleanly.
> I recreated the patch. This patch has been tested against linux-2.6.5 kernel.

Applied, thank you.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Fix IPv6 MIBs counters in 2.6.5 kernel
  2004-04-05 21:42                 ` David S. Miller
@ 2004-04-06  0:11                   ` Shirley Ma
  2004-04-09 23:27                     ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-04-06  0:11 UTC (permalink / raw)
  To: David S. Miller; +Cc: xma, yoshfuji, netdev, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 165 bytes --]

I have fixed IPv6 MIBs counters which don't increase under some cases
 in linux-2.6.5 kernel.

Please review it.

-- 
Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.5-oldmibs.patch --]
[-- Type: text/x-diff, Size: 9788 bytes --]

diff -urN linux-2.6.5/net/ipv6/exthdrs.c linux-2.6.5-oldmibs/net/ipv6/exthdrs.c
--- linux-2.6.5/net/ipv6/exthdrs.c	2004-04-03 19:36:15.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/exthdrs.c	2004-04-05 15:34:44.325848720 -0700
@@ -159,6 +159,7 @@
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -171,6 +172,7 @@
 		return 1;
 	}
 
+	IP6_INC_STATS_BH(Ip6InHdrErrors);
 	return -1;
 }
 
@@ -234,6 +236,7 @@
 
 	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
 	    skb->pkt_type != PACKET_HOST) {
+		IP6_INC_STATS_BH(Ip6InAddrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -249,11 +252,13 @@
 	}
 
 	if (hdr->type != IPV6_SRCRT_TYPE_0) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
 		return -1;
 	}
 	
 	if (hdr->hdrlen & 0x01) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
 		return -1;
 	}
@@ -266,6 +271,7 @@
 	n = hdr->hdrlen >> 1;
 
 	if (hdr->segments_left > n) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
 		return -1;
 	}
@@ -276,8 +282,11 @@
 	if (skb_cloned(skb)) {
 		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
 		kfree_skb(skb);
-		if (skb2 == NULL)
+		/* the copy is a forwarded packet */
+		if (skb2 == NULL) {
+			IP6_INC_STATS_BH(Ip6OutDiscards);	
 			return -1;
+		}
 		*skbp = skb = skb2;
 		opt = (struct inet6_skb_parm *)skb2->cb;
 		hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
@@ -293,6 +302,7 @@
 	addr += i - 1;
 
 	if (ipv6_addr_is_multicast(addr)) {
+		IP6_INC_STATS_BH(Ip6InAddrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -309,6 +319,7 @@
 	}
 	if (skb->dst->dev->flags&IFF_LOOPBACK) {
 		if (skb->nh.ipv6h->hop_limit <= 1) {
+			IP6_INC_STATS_BH(Ip6InHdrErrors);
 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 				    0, skb->dev);
 			kfree_skb(skb);
@@ -425,15 +436,18 @@
 	if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
 		if (net_ratelimit())
 			printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]);
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		goto drop;
 	}
 
 	pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
 	if (pkt_len <= IPV6_MAXPLEN) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
 		return 0;
 	}
 	if (skb->nh.ipv6h->payload_len) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
 		return 0;
 	}
diff -urN linux-2.6.5/net/ipv6/ip6_input.c linux-2.6.5-oldmibs/net/ipv6/ip6_input.c
--- linux-2.6.5/net/ipv6/ip6_input.c	2004-04-03 19:37:38.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/ip6_input.c	2004-04-05 15:09:55.000000000 -0700
@@ -79,8 +79,10 @@
 	if (skb->len < sizeof(struct ipv6hdr))
 		goto err;
 
-	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		goto drop;
+	}
 
 	hdr = skb->nh.ipv6h;
 
@@ -94,8 +96,10 @@
 		if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
 			goto truncated;
 		if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
-			if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr)))
+			if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){
+				IP6_INC_STATS_BH(Ip6InHdrErrors);
 				goto drop;
+			}
 			hdr = skb->nh.ipv6h;
 			if (skb->ip_summed == CHECKSUM_HW)
 				skb->ip_summed = CHECKSUM_NONE;
@@ -206,6 +210,7 @@
 	return 0;
 
 discard:
+	IP6_INC_STATS_BH(Ip6InDiscards);
 	rcu_read_unlock();
 	kfree_skb(skb);
 	return 0;
diff -urN linux-2.6.5/net/ipv6/ip6_output.c linux-2.6.5-oldmibs/net/ipv6/ip6_output.c
--- linux-2.6.5/net/ipv6/ip6_output.c	2004-04-03 19:36:16.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/ip6_output.c	2004-04-05 15:09:55.000000000 -0700
@@ -87,6 +87,7 @@
 	} else if (dst->neighbour)
 		return dst->neighbour->output(skb);
 
+	IP6_INC_STATS_BH(Ip6OutNoRoutes);
 	kfree_skb(skb);
 	return -EINVAL;
 
@@ -131,6 +132,7 @@
 					ip6_dev_loopback_xmit);
 
 			if (skb->nh.ipv6h->hop_limit == 0) {
+				IP6_INC_STATS(Ip6OutDiscards);
 				kfree_skb(skb);
 				return 0;
 			}
@@ -167,6 +169,7 @@
 	dst = ip6_route_output(skb->sk, &fl);
 
 	if (dst->error) {
+		IP6_INC_STATS(Ip6OutNoRoutes);
 		if (net_ratelimit())
 			printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
 		dst_release(dst);
@@ -224,8 +227,10 @@
 			struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
 			kfree_skb(skb);
 			skb = skb2;
-			if (skb == NULL)
+			if (skb == NULL) {	
+				IP6_INC_STATS(Ip6OutDiscards);
 				return -ENOBUFS;
+			}
 			if (sk)
 				skb_set_owner_w(skb, sk);
 		}
@@ -265,6 +270,7 @@
 		printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
 	skb->dev = dst->dev;
 	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+	IP6_INC_STATS(Ip6FragFails);
 	kfree_skb(skb);
 	return -EMSGSIZE;
 }
@@ -345,8 +351,10 @@
 	if (ipv6_devconf.forwarding == 0)
 		goto error;
 
-	if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb))
+	if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
+		IP6_INC_STATS(Ip6InDiscards);
 		goto drop;
+	}
 
 	skb->ip_summed = CHECKSUM_NONE;
 
@@ -382,8 +390,10 @@
 		return -ETIMEDOUT;
 	}
 
-	if (!xfrm6_route_forward(skb))
+	if (!xfrm6_route_forward(skb)) {
+		IP6_INC_STATS(Ip6InDiscards);
 		goto drop;
+	}
 
 	/* IPv6 specs say nothing about it, but it is clear that we cannot
 	   send redirects to source routed frames.
@@ -420,12 +430,15 @@
 		skb->dev = dst->dev;
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev);
 		IP6_INC_STATS_BH(Ip6InTooBigErrors);
+		IP6_INC_STATS_BH(Ip6FragFails);
 		kfree_skb(skb);
 		return -EMSGSIZE;
 	}
 
-	if (skb_cow(skb, dst->dev->hard_header_len))
+	if (skb_cow(skb, dst->dev->hard_header_len)) {
+		IP6_INC_STATS(Ip6OutDiscards);
 		goto drop;
+	}
 
 	hdr = skb->nh.ipv6h;
 
@@ -648,6 +661,7 @@
 
 		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n"));
+			IP6_INC_STATS(Ip6FragFails);
 			err = -ENOMEM;
 			goto fail;
 		}
@@ -1062,6 +1076,7 @@
 	ipv6_addr_copy(&hdr->daddr, final_dst);
 
 	skb->dst = dst_clone(&rt->u.dst);
+	IP6_INC_STATS(Ip6OutRequests);	
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
 	if (err) {
 		if (err > 0)
@@ -1092,8 +1107,10 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff *skb;
 
-	while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
+	while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
+		IP6_INC_STATS(Ip6OutDiscards);
 		kfree_skb(skb);
+	}
 
 	inet->cork.flags &= ~IPCORK_OPT;
 
diff -urN linux-2.6.5/net/ipv6/ndisc.c linux-2.6.5-oldmibs/net/ipv6/ndisc.c
--- linux-2.6.5/net/ipv6/ndisc.c	2004-04-03 19:37:23.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/ndisc.c	2004-04-05 15:09:55.000000000 -0700
@@ -452,6 +452,7 @@
 
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
+	IP6_INC_STATS(Ip6OutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements);
@@ -535,6 +536,7 @@
 	/* send it! */
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
+	IP6_INC_STATS(Ip6OutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits);
@@ -607,6 +609,7 @@
 	/* send it! */
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
+	IP6_INC_STATS(Ip6OutRequests);	
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits);
@@ -1332,6 +1335,7 @@
 
 	buff->dst = dst;
 	idev = in6_dev_get(dst->dev);
+	IP6_INC_STATS(Ip6OutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutRedirects);
diff -urN linux-2.6.5/net/ipv6/raw.c linux-2.6.5-oldmibs/net/ipv6/raw.c
--- linux-2.6.5/net/ipv6/raw.c	2004-04-03 19:36:56.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/raw.c	2004-04-05 15:09:55.000000000 -0700
@@ -526,6 +526,7 @@
 	if (err)
 		goto error_fault;
 
+	IP6_INC_STATS(Ip6OutRequests);		
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
diff -urN linux-2.6.5/net/ipv6/reassembly.c linux-2.6.5-oldmibs/net/ipv6/reassembly.c
--- linux-2.6.5/net/ipv6/reassembly.c	2004-04-03 19:36:55.000000000 -0800
+++ linux-2.6.5-oldmibs/net/ipv6/reassembly.c	2004-04-05 15:09:55.000000000 -0700
@@ -426,6 +426,7 @@
 			((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
 
 	if ((unsigned int)end > IPV6_MAXPLEN) {
+		IP6_INC_STATS_BH(Ip6InHdrErrors);
  		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
  		return;
 	}
@@ -452,6 +453,7 @@
 			/* RFC2460 says always send parameter problem in
 			 * this case. -DaveM
 			 */
+			IP6_INC_STATS_BH(Ip6InHdrErrors);
 			icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 
 					  offsetof(struct ipv6hdr, payload_len));
 			return;
@@ -570,6 +572,7 @@
 	return;
 
 err:
+	IP6_INC_STATS(Ip6ReasmFails);
 	kfree_skb(skb);
 }
 
@@ -694,10 +697,12 @@
 
 	/* Jumbo payload inhibits frag. header */
 	if (hdr->payload_len==0) {
+		IP6_INC_STATS(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
+		IP6_INC_STATS(Ip6InHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: Fix IPv6 MIBs counters in 2.6.5 kernel
  2004-04-06  0:11                   ` Fix IPv6 MIBs counters in 2.6.5 kernel Shirley Ma
@ 2004-04-09 23:27                     ` David S. Miller
  0 siblings, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-04-09 23:27 UTC (permalink / raw)
  To: Shirley Ma; +Cc: xma, yoshfuji, netdev, yoshfuji


Looks great Shirley, patch applied.

Thanks.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-03-31 21:26     ` [PATCH]Add IPv6 MIBs counters in MLD (mcast.c) Shirley Ma
  2004-04-03 22:30       ` David S. Miller
@ 2004-05-26 20:10       ` Shirley Ma
  2004-05-26 20:22         ` David S. Miller
                           ` (2 more replies)
  1 sibling, 3 replies; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 20:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji, xma

[-- Attachment #1: Type: text/plain, Size: 373 bytes --]

This patch implements both per interface and global new IPv6 MIBs counters 
through netlink based on new IP MIBs draft, 64 bit counters are not supported 
here because of performance issues. It coexists old IPv6 MIBs counters (which 
are through proc file system) for the compatibility.
This patch is against 2.6.6 kernel. It has been tested for IPv6.
Please review it. 



[-- Attachment #2: linux-2.6.6-newmibs.patch --]
[-- Type: text/x-diff, Size: 42402 bytes --]

diff -urN linux-2.6.6/include/linux/rtnetlink.h linux-2.6.6-newmibs/include/linux/rtnetlink.h
--- linux-2.6.6/include/linux/rtnetlink.h	2004-05-09 19:33:13.000000000 -0700
+++ linux-2.6.6-newmibs/include/linux/rtnetlink.h	2004-05-26 12:05:39.000000000 -0700
@@ -44,6 +44,9 @@
 #define	RTM_DELTFILTER	(RTM_BASE+29)
 #define	RTM_GETTFILTER	(RTM_BASE+30)
 
+#define RTM_NEWIPSTATS (RTM_BASE+32)
+#define RTM_GETIPSTATS (RTM_BASE+34)
+
 #define RTM_NEWPREFIX	(RTM_BASE+36)
 #define RTM_GETPREFIX	(RTM_BASE+38)
 
@@ -637,6 +640,23 @@
 #define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
 
+/********************************************************************
+ *		IP mibs information
+ ****/
+struct ipstatsmsg
+{
+	int	ipstats_family;
+	int	ipstats_ifindex;
+};
+
+enum
+{
+	IPSTATS_IFNAME,
+	IPSTATS_COUNTERS,
+};
+
+#define IPSTATS_MAX IPSTATS_COUNTERS
+
 
 /* SUMMARY: maximal rtattr understood by kernel */
 
diff -urN linux-2.6.6/include/net/if_inet6.h linux-2.6.6-newmibs/include/net/if_inet6.h
--- linux-2.6.6/include/net/if_inet6.h	2004-05-09 19:33:20.000000000 -0700
+++ linux-2.6.6-newmibs/include/net/if_inet6.h	2004-05-26 12:05:39.000000000 -0700
@@ -149,6 +149,7 @@
 struct ipv6_devstat {
 	struct proc_dir_entry	*proc_dir_entry;
 	DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
+	DEFINE_SNMP_STAT(struct ip_stats, ipv6);
 };
 
 struct inet6_dev 
diff -urN linux-2.6.6/include/net/ipv6.h linux-2.6.6-newmibs/include/net/ipv6.h
--- linux-2.6.6/include/net/ipv6.h	2004-05-09 19:33:13.000000000 -0700
+++ linux-2.6.6-newmibs/include/net/ipv6.h	2004-05-26 12:05:39.000000000 -0700
@@ -116,6 +116,44 @@
 #define IP6_INC_STATS_BH(field)		SNMP_INC_STATS_BH(ipv6_statistics, field)
 #define IP6_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(ipv6_statistics, field)
 DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
+/* new IPv6 MIB */
+DECLARE_SNMP_STAT(struct ip_stats, ipv6_stats);
+#define IPV6_INC_STATS(idev, field)		({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_INC_STATS(_idev->stats.ipv6, field);		\
+	SNMP_INC_STATS(ipv6_stats, field);				\
+})
+#define IPV6_INC_STATS_BH(idev, field)		({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_INC_STATS(_idev->stats.ipv6, field);		\
+	SNMP_INC_STATS_BH(ipv6_stats, field);			\
+})
+#define IPV6_INC_STATS_USER(idev, field) 	({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_INC_STATS(_idev->stats.ipv6, field);		\
+	SNMP_INC_STATS_USER(ipv6_stats, field);			\
+})
+#define IPV6_ADD_STATS_BH(idev, field, addend)	({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_ADD_STATS_BH(_idev->stats.ipv6, field, addend);	\
+	SNMP_ADD_STATS_BH(ipv6_stats, field, addend);		\
+})
+#define IPV6_ADD_STATS_USER(idev, field, addend) ({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_ADD_STATS_USER(_idev->stats.ipv6, field, addend);	\
+	SNMP_ADD_STATS_USER(ipv6_stats, field, addend);		\
+})
+#define IPV6_ADD_STATS(idev, field, addend)	({			\
+	struct inet6_dev *_idev = (idev);				\
+	if (likely(_idev != NULL))					\
+		SNMP_ADD_STATS(_idev->stats.ipv6, field, addend);	\
+	SNMP_ADD_STATS(ipv6_stats, field, addend);			\
+})	
 #define ICMP6_INC_STATS(idev, field)		({			\
 	struct inet6_dev *_idev = (idev);				\
 	if (likely(_idev != NULL))					\
diff -urN linux-2.6.6/include/net/snmp.h linux-2.6.6-newmibs/include/net/snmp.h
--- linux-2.6.6/include/net/snmp.h	2004-05-09 19:32:28.000000000 -0700
+++ linux-2.6.6-newmibs/include/net/snmp.h	2004-05-26 12:05:39.000000000 -0700
@@ -98,6 +98,43 @@
  	unsigned long	Ip6OutMcastPkts;
 	unsigned long   __pad[0]; 
 };
+
+/*
+ * New IP MIBs from draft-ietf-ipv6-rfc2011-update-05.txt 
+ */
+struct ip_stats
+{
+	unsigned long	ipStatsInReceives;
+	unsigned long	ipStatsInOctets;
+	unsigned long	ipStatsInHdrErrors;
+	unsigned long	ipStatsInNoRoutes;
+	unsigned long	ipStatsInAddrErrors;
+	unsigned long	ipStatsInUnknownProtos;
+	unsigned long	ipStatsInTruncatedPkts;
+	unsigned long	ipStatsInForwDatagrams;
+	unsigned long	ipStatsReasmReqds;
+	unsigned long	ipStatsReasmOKs;
+	unsigned long	ipStatsReasmFails;
+	unsigned long	ipStatsInDiscards;
+	unsigned long	ipStatsInDelivers;
+	unsigned long	ipStatsOutRequests;
+	unsigned long	ipStatsOutNoRoutes;
+	unsigned long	ipStatsOutForwDatagrams;
+	unsigned long	ipStatsOutDiscards;
+	unsigned long	ipStatsOutFragReqds;
+	unsigned long	ipStatsOutFragOKs;
+	unsigned long	ipStatsOutFragFails;
+	unsigned long	ipStatsOutFragCreates;
+	unsigned long	ipStatsOutTransmits;
+	unsigned long	ipStatsOutOctets;
+	unsigned long	ipStatsInMcastPkts;
+	unsigned long	ipStatsInMcastOctets;
+	unsigned long	ipStatsOutMcastPkts;
+	unsigned long	ipStatsOutMcastOctets;
+	unsigned long	ipStatsInBcastPkts;
+	unsigned long	ipStatsOutBcastPkts;
+	unsigned long   __pad[0]; 
+};
  
 /*
  * RFC 1213:  MIB-II ICMP Group
@@ -335,6 +372,8 @@
 	(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field++)
 #define SNMP_DEC_STATS(mib, field) 	\
 	(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field--)
+#define SNMP_ADD_STATS(mib, field, addend)	\
+	(per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field += addend)
 #define SNMP_ADD_STATS_BH(mib, field, addend) 	\
 	(per_cpu_ptr(mib[0], smp_processor_id())->field += addend)
 #define SNMP_ADD_STATS_USER(mib, field, addend) 	\
diff -urN linux-2.6.6/net/ipv6/addrconf.c linux-2.6.6-newmibs/net/ipv6/addrconf.c
--- linux-2.6.6/net/ipv6/addrconf.c	2004-05-09 19:33:20.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/addrconf.c	2004-05-26 12:05:39.000000000 -0700
@@ -2963,6 +2963,101 @@
 	netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC);
 }
 
+static unsigned long
+fold_field(void *mib[], int offt)
+{
+        unsigned long res = 0;
+        int i;
+ 
+        for (i = 0; i < NR_CPUS; i++) {
+                if (!cpu_possible(i))
+                        continue;
+                res +=
+                    *((unsigned long *) (((void *)per_cpu_ptr(mib[0], i)) +
+                                         offt));
+                res +=
+                    *((unsigned long *) (((void *)per_cpu_ptr(mib[1], i)) +
+                                         offt));
+        }
+        return res;
+}
+
+static int inet6_fill_ipstats(struct sk_buff *skb, struct inet6_dev *idev,
+			       u32 pid, u32 seq, int event)
+{
+	struct ipstatsmsg	*r;
+	struct nlmsghdr 	*nlh;
+	unsigned char		*b = skb->tail;
+	struct ip_stats		ipstats;
+	unsigned long		*array;
+	int 			i, num;
+
+	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
+	if (pid) 
+		nlh->nlmsg_flags |= NLM_F_MULTI;
+	r = NLMSG_DATA(nlh);
+	r->ipstats_family = AF_INET6;
+	r->ipstats_ifindex = 0;
+	num = offsetof(struct ip_stats, __pad) / sizeof(unsigned long);
+	memset(&ipstats , 0, sizeof(struct ip_stats));
+	array = (unsigned long *)&ipstats;
+	if (idev == NULL) {
+		/* fill IP mibs system statistics */
+		RTA_PUT(skb, IPSTATS_IFNAME, 3, "all");
+		for (i = 0; i < num; i++, array++) {
+			*array = fold_field((void **)ipv6_stats, 
+					    i * (sizeof(unsigned long)));
+		}
+	} else {
+		/* fill IP mibs interface statistics */
+		r->ipstats_ifindex = idev->dev->ifindex;
+		RTA_PUT(skb, IPSTATS_IFNAME, strlen(idev->dev->name)+1,
+			idev->dev->name);
+		for (i = 0; i < num; i++, array++) {
+			*array = fold_field((void **)idev->stats.ipv6, 
+					    i * (sizeof(unsigned long)));
+		}
+	}
+	RTA_PUT(skb, IPSTATS_COUNTERS, sizeof(struct ip_stats), &ipstats);
+	nlh->nlmsg_len = skb->tail - b;
+	return skb->len;
+
+nlmsg_failure:
+rtattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+static int inet6_dump_ipstats(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	int err, idx = 0;
+	int s_idx = cb->args[0];
+	struct net_device *dev;
+	struct inet6_dev *idev;
+
+	/* fill IP mibs system statistics */
+	inet6_fill_ipstats(skb, NULL, NETLINK_CB(cb->skb).pid,
+			    cb->nlh->nlmsg_seq, RTM_NEWIPSTATS);
+	idx += 1;
+	/* fill IP mibs interface statistics */
+	read_lock(&dev_base_lock);
+	for (dev=dev_base; dev; dev = dev->next, idx++) {
+		if (idx < s_idx)
+			continue;
+		if ((idev = in6_dev_get(dev)) == NULL)
+			continue;
+		err = inet6_fill_ipstats(skb, idev, NETLINK_CB(cb->skb).pid, 
+				cb->nlh->nlmsg_seq, RTM_NEWIPSTATS);
+		in6_dev_put(idev);
+		if (err <= 0)
+			break;
+	}
+	read_unlock(&dev_base_lock);
+	cb->args[0] = idx;
+
+	return skb->len;
+}
+
 static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
 	[RTM_GETLINK - RTM_BASE] = { .dumpit	= inet6_dump_ifinfo, },
 	[RTM_NEWADDR - RTM_BASE] = { .doit	= inet6_rtm_newaddr, },
@@ -2974,6 +3069,7 @@
 	[RTM_DELROUTE - RTM_BASE] = { .doit	= inet6_rtm_delroute, },
 	[RTM_GETROUTE - RTM_BASE] = { .doit	= inet6_rtm_getroute,
 				      .dumpit	= inet6_dump_fib, },
+	[RTM_GETIPSTATS - RTM_BASE] = { .dumpit = inet6_dump_ipstats, },
 };
 
 static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
diff -urN linux-2.6.6/net/ipv6/af_inet6.c linux-2.6.6-newmibs/net/ipv6/af_inet6.c
--- linux-2.6.6/net/ipv6/af_inet6.c	2004-05-09 19:32:38.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/af_inet6.c	2004-05-26 12:05:39.000000000 -0700
@@ -670,6 +670,9 @@
 	if (snmp6_mib_init((void **)ipv6_statistics, sizeof (struct ipv6_mib),
 			   __alignof__(struct ipv6_mib)) < 0)
 		goto err_ip_mib;
+	if (snmp6_mib_init((void **)ipv6_stats, sizeof (struct ip_stats),
+			   __alignof__(struct ip_stats)) < 0)
+		goto err_ip6_mib;
 	if (snmp6_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
 			   __alignof__(struct ipv6_mib)) < 0)
 		goto err_icmp_mib;
@@ -681,6 +684,8 @@
 err_udp_mib:
 	snmp6_mib_free((void **)icmpv6_statistics);
 err_icmp_mib:
+	snmp6_mib_free((void **)ipv6_stats);
+err_ip6_mib:
 	snmp6_mib_free((void **)ipv6_statistics);
 err_ip_mib:
 	return -ENOMEM;
@@ -690,6 +695,7 @@
 static void cleanup_ipv6_mibs(void)
 {
 	snmp6_mib_free((void **)ipv6_statistics);
+	snmp6_mib_free((void **)ipv6_stats);
 	snmp6_mib_free((void **)icmpv6_statistics);
 	snmp6_mib_free((void **)udp_stats_in6);
 }
diff -urN linux-2.6.6/net/ipv6/exthdrs.c linux-2.6.6-newmibs/net/ipv6/exthdrs.c
--- linux-2.6.6/net/ipv6/exthdrs.c	2004-05-09 19:31:59.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/exthdrs.c	2004-05-26 12:05:39.000000000 -0700
@@ -156,10 +156,15 @@
 {
 	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+	struct inet6_dev *idev = NULL;
+
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -173,6 +178,7 @@
 	}
 
 	IP6_INC_STATS_BH(Ip6InHdrErrors);
+	IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 	return -1;
 }
 
@@ -224,10 +230,15 @@
 
 	struct ipv6_rt_hdr *hdr;
 	struct rt0_hdr *rthdr;
+	struct inet6_dev *idev = NULL;
+
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -237,6 +248,7 @@
 	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
 	    skb->pkt_type != PACKET_HOST) {
 		IP6_INC_STATS_BH(Ip6InAddrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -253,12 +265,14 @@
 
 	if (hdr->type != IPV6_SRCRT_TYPE_0) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
 		return -1;
 	}
 	
 	if (hdr->hdrlen & 0x01) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
 		return -1;
 	}
@@ -272,6 +286,7 @@
 
 	if (hdr->segments_left > n) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
 		return -1;
 	}
@@ -284,7 +299,8 @@
 		kfree_skb(skb);
 		/* the copy is a forwarded packet */
 		if (skb2 == NULL) {
-			IP6_INC_STATS_BH(Ip6OutDiscards);	
+			IP6_INC_STATS_BH(Ip6OutDiscards);
+			IPV6_INC_STATS_BH(idev, ipStatsOutDiscards);
 			return -1;
 		}
 		*skbp = skb = skb2;
@@ -303,6 +319,7 @@
 
 	if (ipv6_addr_is_multicast(addr)) {
 		IP6_INC_STATS_BH(Ip6InAddrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
 		kfree_skb(skb);
 		return -1;
 	}
@@ -320,6 +337,7 @@
 	if (skb->dst->dev->flags&IFF_LOOPBACK) {
 		if (skb->nh.ipv6h->hop_limit <= 1) {
 			IP6_INC_STATS_BH(Ip6InHdrErrors);
+			IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 				    0, skb->dev);
 			kfree_skb(skb);
@@ -432,28 +450,36 @@
 static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
 {
 	u32 pkt_len;
+	struct inet6_dev *idev = NULL;
+
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 
 	if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
 		LIMIT_NETDEBUG(
 			 printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]));
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		goto drop;
 	}
 
 	pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
 	if (pkt_len <= IPV6_MAXPLEN) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
 		return 0;
 	}
 	if (skb->nh.ipv6h->payload_len) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
 		return 0;
 	}
 
 	if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
 		IP6_INC_STATS_BH(Ip6InTruncatedPkts);
+		IPV6_INC_STATS_BH(idev, ipStatsInTruncatedPkts);
 		goto drop;
 	}
 	if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
diff -urN linux-2.6.6/net/ipv6/icmp.c linux-2.6.6-newmibs/net/ipv6/icmp.c
--- linux-2.6.6/net/ipv6/icmp.c	2004-05-09 19:32:27.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/icmp.c	2004-05-26 12:05:39.000000000 -0700
@@ -158,6 +158,7 @@
 {
 	struct dst_entry *dst;
 	int res = 0;
+	struct inet6_dev *idev = NULL;
 
 	/* Informational messages are not limited. */
 	if (type & ICMPV6_INFOMSG_MASK)
@@ -173,8 +174,12 @@
 	 * this lookup should be more aggressive (not longer than timeout).
 	 */
 	dst = ip6_route_output(sk, fl);
+	/* idev reference for IP MIBs */
+	if (likely(dst->dev))
+		idev = in6_dev_get(dst->dev);
 	if (dst->error) {
 		IP6_INC_STATS(Ip6OutNoRoutes);
+		IPV6_INC_STATS(idev, ipStatsOutNoRoutes);
 	} else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
 		res = 1;
 	} else {
@@ -187,6 +192,9 @@
 
 		res = xrlim_allow(dst, tmo);
 	}
+	/* release the idev reference for IP MIBs */
+	if (likely(idev))
+		in6_dev_put(idev);
 	dst_release(dst);
 	return res;
 }
diff -urN linux-2.6.6/net/ipv6/ip6_input.c linux-2.6.6-newmibs/net/ipv6/ip6_input.c
--- linux-2.6.6/net/ipv6/ip6_input.c	2004-05-09 19:32:54.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/ip6_input.c	2004-05-26 12:34:10.000000000 -0700
@@ -60,14 +60,22 @@
 {
 	struct ipv6hdr *hdr;
 	u32 		pkt_len;
+	struct inet6_dev *idev = NULL;
+	int		err = 0;
+	
+	/* idev reference for input IP MIBs */
+	if (likely(skb->dev))
+		idev = in6_dev_get(skb->dev);
 
 	if (skb->pkt_type == PACKET_OTHERHOST)
 		goto drop;
 
 	IP6_INC_STATS_BH(Ip6InReceives);
+	IPV6_INC_STATS_BH(idev, ipStatsInReceives);
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
 		IP6_INC_STATS_BH(Ip6InDiscards);
+		IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
 		goto out;
 	}
 
@@ -81,6 +89,7 @@
 
 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		goto drop;
 	}
 
@@ -90,6 +99,7 @@
 		goto err;
 
 	pkt_len = ntohs(hdr->payload_len);
+	IPV6_ADD_STATS_BH(idev, ipStatsInOctets, skb->len);
 
 	/* pkt_len may be zero if Jumbo payload option is present */
 	if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
@@ -98,6 +108,7 @@
 		if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
 			if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){
 				IP6_INC_STATS_BH(Ip6InHdrErrors);
+				IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 				goto drop;
 			}
 			hdr = skb->nh.ipv6h;
@@ -110,20 +121,26 @@
 		skb->h.raw = (u8*)(hdr+1);
 		if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) {
 			IP6_INC_STATS_BH(Ip6InHdrErrors);
-			return 0;
+			IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
+			goto out;
 		}
 		hdr = skb->nh.ipv6h;
 	}
 
-	return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
+	err = NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
+	goto out;
 truncated:
 	IP6_INC_STATS_BH(Ip6InTruncatedPkts);
+	IPV6_INC_STATS_BH(idev, ipStatsInTruncatedPkts);
 err:
 	IP6_INC_STATS_BH(Ip6InHdrErrors);
+	IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 drop:
 	kfree_skb(skb);
 out:
-	return 0;
+	if (likely(idev))
+		in6_dev_put(idev);
+	return err;
 }
 
 /*
@@ -139,6 +156,10 @@
 	int nexthdr;
 	u8 hash;
 	int cksum_sub = 0;
+	struct inet6_dev *idev = NULL;
+
+	if (skb->dev)
+		idev = __in6_dev_get(skb->dev);
 
 	skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
 
@@ -193,16 +214,20 @@
 		ret = ipprot->handler(&skb, &nhoff);
 		if (ret > 0)
 			goto resubmit;
-		else if (ret == 0)
+		else if (ret == 0) {
 			IP6_INC_STATS_BH(Ip6InDelivers);
+			IPV6_INC_STATS_BH(idev, ipStatsInDelivers);
+		}
 	} else {
 		if (!raw_sk) {
 			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				IP6_INC_STATS_BH(Ip6InUnknownProtos);
+				IPV6_INC_STATS_BH(idev, ipStatsInUnknownProtos);
 				icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
 			}
 		} else {
 			IP6_INC_STATS_BH(Ip6InDelivers);
+			IPV6_INC_STATS_BH(idev, ipStatsInDelivers);
 			kfree_skb(skb);
 		}
 	}
@@ -211,6 +236,7 @@
 
 discard:
 	IP6_INC_STATS_BH(Ip6InDiscards);
+	IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
 	rcu_read_unlock();
 	kfree_skb(skb);
 	return 0;
@@ -226,8 +252,13 @@
 {
 	struct ipv6hdr *hdr;
 	int deliver;
+	struct inet6_dev *idev = NULL;
 
+	if (skb->dev)
+		idev = __in6_dev_get(skb->dev);
 	IP6_INC_STATS_BH(Ip6InMcastPkts);
+	IPV6_INC_STATS_BH(idev, ipStatsInMcastPkts);
+	IPV6_ADD_STATS_BH(idev, ipStatsInMcastOctets, skb->len);
 
 	hdr = skb->nh.ipv6h;
 	deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
diff -urN linux-2.6.6/net/ipv6/ip6_output.c linux-2.6.6-newmibs/net/ipv6/ip6_output.c
--- linux-2.6.6/net/ipv6/ip6_output.c	2004-05-09 19:31:59.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/ip6_output.c	2004-05-26 12:13:36.000000000 -0700
@@ -74,6 +74,10 @@
 
 	struct dst_entry *dst = skb->dst;
 	struct hh_cache *hh = dst->hh;
+	struct inet6_dev *idev = NULL;
+
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 
 	if (hh) {
 		int hh_alen;
@@ -83,11 +87,15 @@
 		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
 		read_unlock_bh(&hh->hh_lock);
 	        skb_push(skb, hh->hh_len);
+		IPV6_INC_STATS_BH(idev, ipStatsOutTransmits);
 		return hh->hh_output(skb);
-	} else if (dst->neighbour)
+	} else if (dst->neighbour) {
+		IPV6_INC_STATS_BH(idev, ipStatsOutTransmits);
 		return dst->neighbour->output(skb);
+	}
 
 	IP6_INC_STATS_BH(Ip6OutNoRoutes);
+	IPV6_INC_STATS_BH(idev, ipStatsOutDiscards);
 	kfree_skb(skb);
 	return -EINVAL;
 
@@ -111,9 +119,12 @@
 {
 	struct dst_entry *dst = skb->dst;
 	struct net_device *dev = dst->dev;
+	struct inet6_dev *idev = NULL;
 
 	skb->protocol = htons(ETH_P_IPV6);
 	skb->dev = dev;
+	if (likely(dev)) 
+		idev = __in6_dev_get(dev);
 
 	if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
 		struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
@@ -133,12 +144,15 @@
 
 			if (skb->nh.ipv6h->hop_limit == 0) {
 				IP6_INC_STATS(Ip6OutDiscards);
+				IPV6_INC_STATS(idev, ipStatsOutDiscards);
 				kfree_skb(skb);
 				return 0;
 			}
 		}
 
 		IP6_INC_STATS(Ip6OutMcastPkts);
+		IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
+		IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
 	}
 
 	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
@@ -157,6 +171,7 @@
 {
 	struct ipv6hdr *iph = skb->nh.ipv6h;
 	struct dst_entry *dst;
+	struct inet6_dev *idev = NULL;
 	struct flowi fl = {
 		.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
 		.nl_u =
@@ -167,18 +182,26 @@
 	};
 
 	dst = ip6_route_output(skb->sk, &fl);
-
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 	if (dst->error) {
 		IP6_INC_STATS(Ip6OutNoRoutes);
+		IPV6_INC_STATS_BH(idev, ipStatsOutNoRoutes);
 		LIMIT_NETDEBUG(
 			printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n"));
 		dst_release(dst);
 		return -EINVAL;
 	}
 
+	/* drop the IP MIBs reference for old idev */
+	if (likely(skb->dst))
+		in6_dev_put(__in6_dev_get(skb->dst->dev));
 	/* Drop old route. */
 	dst_release(skb->dst);
 
+	/* IP MIBs refer to the new dst idev */
+	if (likely(dst->dev))
+		idev = in6_dev_get(dst->dev);
 	skb->dst = dst;
 	return 0;
 }
@@ -212,7 +235,13 @@
 	int seg_len = skb->len;
 	int hlimit;
 	u32 mtu;
-
+	struct inet6_dev *idev = NULL;
+	int errno = 0;
+	
+	/* idev reference for IP MIBs */
+	if (likely(skb->dst))
+		idev = in6_dev_get(skb->dst->dev);
+	
 	if (opt) {
 		int head_room;
 
@@ -229,7 +258,9 @@
 			skb = skb2;
 			if (skb == NULL) {	
 				IP6_INC_STATS(Ip6OutDiscards);
-				return -ENOBUFS;
+				IPV6_INC_STATS(idev, ipStatsOutDiscards);
+				errno = -ENOBUFS;
+				goto out;
 			}
 			if (sk)
 				skb_set_owner_w(skb, sk);
@@ -263,7 +294,10 @@
 	mtu = dst_pmtu(dst);
 	if ((skb->len <= mtu) || ipfragok) {
 		IP6_INC_STATS(Ip6OutRequests);
-		return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
+		IPV6_INC_STATS(idev, ipStatsOutRequests);
+		IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
+		errno = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
+		goto out;
 	}
 
 	if (net_ratelimit())
@@ -271,8 +305,13 @@
 	skb->dev = dst->dev;
 	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
 	IP6_INC_STATS(Ip6FragFails);
+	IPV6_INC_STATS(idev, ipStatsOutDiscards);
 	kfree_skb(skb);
-	return -EMSGSIZE;
+	errno = -EMSGSIZE;
+out:
+	if (likely(idev))
+		in6_dev_put(idev);
+	return errno;
 }
 
 /*
@@ -347,12 +386,22 @@
 	struct dst_entry *dst = skb->dst;
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
+	struct inet6_dev *idev = NULL;
+	int errno = 0;
+	
+	/* idev reference for IP MIBs*/
+	if (likely(dst))
+		idev = in6_dev_get(dst->dev);
 	
-	if (ipv6_devconf.forwarding == 0)
+	if (ipv6_devconf.forwarding == 0) {
+		errno = -EINVAL;
 		goto error;
+	}
 
 	if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
 		IP6_INC_STATS(Ip6InDiscards);
+		IPV6_INC_STATS(idev, ipStatsInDiscards);
+		errno = -EINVAL;
 		goto drop;
 	}
 
@@ -374,7 +423,7 @@
 	if (opt->ra) {
 		u8 *ptr = skb->nh.raw + opt->ra;
 		if (ip6_call_ra_chain(skb, (ptr[2]<<8) + ptr[3]))
-			return 0;
+			goto out;
 	}
 
 	/*
@@ -385,13 +434,17 @@
 		skb->dev = dst->dev;
 		icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 			    0, skb->dev);
-
+		IP6_INC_STATS(Ip6InDiscards);
+		IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
 		kfree_skb(skb);
-		return -ETIMEDOUT;
+		errno = -ETIMEDOUT;
+		goto out;
 	}
 
 	if (!xfrm6_route_forward(skb)) {
 		IP6_INC_STATS(Ip6InDiscards);
+		IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
+		errno = -EINVAL;
 		goto drop;
 	}
 
@@ -422,6 +475,7 @@
 	} else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
 						|IPV6_ADDR_LINKLOCAL)) {
 		/* This check is security critical. */
+		errno = -EINVAL;
 		goto error;
 	}
 
@@ -431,12 +485,16 @@
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev);
 		IP6_INC_STATS_BH(Ip6InTooBigErrors);
 		IP6_INC_STATS_BH(Ip6FragFails);
+		IPV6_INC_STATS_BH(idev, ipStatsOutFragFails);
 		kfree_skb(skb);
-		return -EMSGSIZE;
+		errno = -EMSGSIZE;
+		goto out;
 	}
 
 	if (skb_cow(skb, dst->dev->hard_header_len)) {
 		IP6_INC_STATS(Ip6OutDiscards);
+		IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
+		errno = -EINVAL;
 		goto drop;
 	}
 
@@ -447,13 +505,18 @@
 	hdr->hop_limit--;
 
 	IP6_INC_STATS_BH(Ip6OutForwDatagrams);
-	return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
-
+	IPV6_INC_STATS_BH(idev, ipStatsOutForwDatagrams);
+	errno = NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
+	goto out;
 error:
 	IP6_INC_STATS_BH(Ip6InAddrErrors);
+	IPV6_INC_STATS_BH(idev, ipStatsInAddrErrors);
 drop:
 	kfree_skb(skb);
-	return -EINVAL;
+out:
+	if (likely(idev))
+		in6_dev_put(idev);
+	return errno;
 }
 
 static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
@@ -524,8 +587,11 @@
 	u32 frag_id = 0;
 	int ptr, offset = 0, err=0;
 	u8 *prevhdr, nexthdr = 0;
+	struct inet6_dev *idev = NULL;
 
 	dev = rt->u.dst.dev;
+	if (likely(dev))
+		idev = __in6_dev_get(dev);	
 	hlen = ip6_find_1stfragopt(skb, &prevhdr);
 	nexthdr = *prevhdr;
 
@@ -564,6 +630,7 @@
 		tmp_hdr = kmalloc(hlen, GFP_ATOMIC);
 		if (!tmp_hdr) {
 			IP6_INC_STATS(Ip6FragFails);
+			IPV6_INC_STATS(idev, ipStatsOutFragFails);
 			return -ENOMEM;
 		}
 
@@ -619,6 +686,7 @@
 
 		if (err == 0) {
 			IP6_INC_STATS(Ip6FragOKs);
+			IPV6_INC_STATS(idev, ipStatsOutFragOKs);
 			return 0;
 		}
 
@@ -629,6 +697,7 @@
 		}
 
 		IP6_INC_STATS(Ip6FragFails);
+		IPV6_INC_STATS(idev, ipStatsOutFragFails);
 		return err;
 	}
 
@@ -662,6 +731,7 @@
 		if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n"));
 			IP6_INC_STATS(Ip6FragFails);
+			IPV6_INC_STATS(idev, ipStatsOutFragFails);
 			err = -ENOMEM;
 			goto fail;
 		}
@@ -720,6 +790,7 @@
 		 */
 
 		IP6_INC_STATS(Ip6FragCreates);
+		IPV6_INC_STATS(idev, ipStatsOutFragCreates);
 
 		err = output(frag);
 		if (err)
@@ -727,11 +798,13 @@
 	}
 	kfree_skb(skb);
 	IP6_INC_STATS(Ip6FragOKs);
+	IPV6_INC_STATS(idev, ipStatsOutFragOKs);
 	return err;
 
 fail:
 	kfree_skb(skb); 
 	IP6_INC_STATS(Ip6FragFails);
+	IPV6_INC_STATS(idev, ipStatsOutFragFails);
 	return err;
 }
 
@@ -822,6 +895,7 @@
 	int err;
 	int offset = 0;
 	int csummode = CHECKSUM_NONE;
+	struct inet6_dev *idev = NULL;
 
 	if (flags&MSG_PROBE)
 		return 0;
@@ -1016,7 +1090,10 @@
 	return 0;
 error:
 	inet->cork.length -= length;
+	if (likely(skb->dev))
+		idev = __in6_dev_get(skb->dev);
 	IP6_INC_STATS(Ip6OutDiscards);
+	IPV6_INC_STATS(idev, ipStatsOutDiscards);
 	return err;
 }
 
@@ -1033,6 +1110,7 @@
 	struct flowi *fl = &inet->cork.fl;
 	unsigned char proto = fl->proto;
 	int err = 0;
+	struct inet6_dev *idev = NULL;
 
 	if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
 		goto out;
@@ -1076,7 +1154,12 @@
 	ipv6_addr_copy(&hdr->daddr, final_dst);
 
 	skb->dst = dst_clone(&rt->u.dst);
-	IP6_INC_STATS(Ip6OutRequests);	
+	/* idev reference for IP MIBs */
+	if (likely(skb->dst))
+		idev = in6_dev_get(skb->dst->dev);
+	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
+	IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
 	if (err) {
 		if (err > 0)
@@ -1096,6 +1179,8 @@
 		np->cork.rt = NULL;
 	}
 	memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+	if (likely(idev))
+		in6_dev_put(idev);
 	return err;
 error:
 	goto out;
@@ -1106,11 +1191,22 @@
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff *skb;
+	struct inet6_dev *idev = NULL;
 
 	while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
+		if (skb->dst) {
+			if (!idev || skb->dst->dev != idev->dev) {
+				if (idev)
+					in6_dev_put(idev);
+				idev = in6_dev_get(skb->dst->dev);
+			}
+		}
 		IP6_INC_STATS(Ip6OutDiscards);
+		IPV6_INC_STATS(idev, ipStatsOutDiscards);
 		kfree_skb(skb);
 	}
+	if (idev)
+		in6_dev_put(idev);
 
 	inet->cork.flags &= ~IPCORK_OPT;
 
diff -urN linux-2.6.6/net/ipv6/ipv6_sockglue.c linux-2.6.6-newmibs/net/ipv6/ipv6_sockglue.c
--- linux-2.6.6/net/ipv6/ipv6_sockglue.c	2004-05-09 19:32:00.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/ipv6_sockglue.c	2004-05-26 12:05:39.000000000 -0700
@@ -56,6 +56,7 @@
 #include <asm/uaccess.h>
 
 DEFINE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
+DEFINE_SNMP_STAT(struct ip_stats, ipv6_stats);
 
 static struct packet_type ipv6_packet_type = {
 	.type = __constant_htons(ETH_P_IPV6), 
diff -urN linux-2.6.6/net/ipv6/mcast.c linux-2.6.6-newmibs/net/ipv6/mcast.c
--- linux-2.6.6/net/ipv6/mcast.c	2004-05-09 19:33:13.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/mcast.c	2004-05-26 12:35:27.000000000 -0700
@@ -1318,6 +1318,8 @@
 	int err;
 
 	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
+	IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
 	payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
 		sizeof(struct ipv6hdr);
 	mldlen = skb->tail - skb->h.raw;
@@ -1330,10 +1332,13 @@
 	if (!err) {
 		ICMP6_INC_STATS(idev,Icmp6OutMsgs);
 		IP6_INC_STATS(Ip6OutMcastPkts);
-	} else
+		IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
+		IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
+	} else {
 		IP6_INC_STATS(Ip6OutDiscards);
-
-	if (likely(idev != NULL))
+		IPV6_INC_STATS(idev, ipStatsOutDiscards);
+	}
+	if (idev)
 		in6_dev_put(idev);
 }
 
@@ -1613,7 +1618,9 @@
 		     IPV6_TLV_ROUTERALERT, 2, 0, 0,
 		     IPV6_TLV_PADN, 0 };
 
+	idev = in6_dev_get(dev);
 	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
 	snd_addr = addr;
 	if (type == ICMPV6_MGM_REDUCTION) {
 		snd_addr = &all_routers;
@@ -1628,9 +1635,13 @@
 
 	if (skb == NULL) {
 		IP6_INC_STATS(Ip6OutDiscards);
+		IPV6_INC_STATS(idev, ipStatsOutDiscards);
+		if (idev)
+			in6_dev_put(idev);
 		return;
 	}
 
+	IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
 	skb_reserve(skb, LL_RESERVED_SPACE(dev));
 	if (dev->hard_header) {
 		unsigned char ha[MAX_ADDR_LEN];
@@ -1662,8 +1673,6 @@
 					   IPPROTO_ICMPV6,
 					   csum_partial((__u8 *) hdr, len, 0));
 
-	idev = in6_dev_get(skb->dev);
-
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
 		dev_queue_xmit);
 	if (!err) {
@@ -1673,16 +1682,22 @@
 			ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses);
 		ICMP6_INC_STATS(idev, Icmp6OutMsgs);
 		IP6_INC_STATS(Ip6OutMcastPkts);
-	} else
+		IPV6_INC_STATS(idev, ipStatsOutMcastPkts);
+		IPV6_ADD_STATS(idev, ipStatsOutMcastOctets, skb->len);
+	} else {
 		IP6_INC_STATS(Ip6OutDiscards);
-
+		IPV6_INC_STATS(idev, ipStatsOutDiscards);
+	}
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 	return;
 
 out:
 	IP6_INC_STATS(Ip6OutDiscards);
+	IPV6_INC_STATS(idev, ipStatsOutDiscards);
 	kfree_skb(skb);
+	if (likely(idev != NULL))
+		in6_dev_put(idev);
 }
 
 static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
diff -urN linux-2.6.6/net/ipv6/ndisc.c linux-2.6.6-newmibs/net/ipv6/ndisc.c
--- linux-2.6.6/net/ipv6/ndisc.c	2004-05-09 19:32:39.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/ndisc.c	2004-05-26 12:05:40.000000000 -0700
@@ -453,6 +453,7 @@
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
 	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements);
@@ -537,6 +538,7 @@
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
 	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits);
@@ -609,7 +611,8 @@
 	/* send it! */
 	skb->dst = dst;
 	idev = in6_dev_get(dst->dev);
-	IP6_INC_STATS(Ip6OutRequests);	
+	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits);
@@ -1336,6 +1339,7 @@
 	buff->dst = dst;
 	idev = in6_dev_get(dst->dev);
 	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
 	if (!err) {
 		ICMP6_INC_STATS(idev, Icmp6OutRedirects);
diff -urN linux-2.6.6/net/ipv6/proc.c linux-2.6.6-newmibs/net/ipv6/proc.c
--- linux-2.6.6/net/ipv6/proc.c	2004-05-09 19:32:28.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/proc.c	2004-05-26 12:05:40.000000000 -0700
@@ -227,6 +227,9 @@
 	if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
 			   __alignof__(struct icmpv6_mib)) < 0)
 		goto err_icmp;
+	if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ip_stats),
+			   __alignof__(struct ip_stats)) < 0)
+		goto err_ip;
 
 	if (!proc_net_devsnmp6) {
 		err = -ENOENT;
@@ -242,8 +245,11 @@
 	return 0;
 
 err_proc:
+	snmp6_mib_free((void **)idev->stats.ipv6);
+err_ip:
 	snmp6_mib_free((void **)idev->stats.icmpv6);
 err_icmp:
+	
 	return err;
 }
 
@@ -256,6 +262,7 @@
 	remove_proc_entry(idev->stats.proc_dir_entry->name,
 			  proc_net_devsnmp6);
 	snmp6_mib_free((void **)idev->stats.icmpv6);
+	snmp6_mib_free((void **)idev->stats.ipv6);
 
 	return 0;
 }
@@ -305,9 +312,13 @@
 	if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
 			   __alignof__(struct icmpv6_mib)) < 0)
 		goto err_icmp;
+	if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ip_stats),
+			   __alignof__(struct ip_stats)) < 0)
+		goto err_ip;
 
 	return 0;
-
+err_ip:
+	snmp6_mib_free((void **)idev->stats.icmpv6);
 err_icmp:
 	return err;
 }
@@ -315,6 +326,7 @@
 int snmp6_unregister_dev(struct inet6_dev *idev)
 {
 	snmp6_mib_free((void **)idev->stats.icmpv6);
+	snmp6_mib_free((void **)idev->stats.ipv6);
 	return 0;
 }
 
diff -urN linux-2.6.6/net/ipv6/raw.c linux-2.6.6-newmibs/net/ipv6/raw.c
--- linux-2.6.6/net/ipv6/raw.c	2004-05-09 19:32:28.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/raw.c	2004-05-26 12:18:55.000000000 -0700
@@ -498,11 +498,15 @@
 	struct ipv6hdr *iph;
 	struct sk_buff *skb;
 	unsigned int hh_len;
-	int err;
+	int err = 0;
+	struct inet6_dev *idev = NULL;
+
+	/* hold reference for IP MIBs */
 
 	if (length > rt->u.dst.dev->mtu) {
 		ipv6_local_error(sk, EMSGSIZE, fl, rt->u.dst.dev->mtu);
-		return -EMSGSIZE;
+		err = -EMSGSIZE;
+		goto out;
 	}
 	if (flags&MSG_PROBE)
 		goto out;
@@ -518,6 +522,9 @@
 	skb->priority = sk->sk_priority;
 	skb->dst = dst_clone(&rt->u.dst);
 
+	if (skb->dst)
+		idev = in6_dev_get(skb->dst->dev);
+
 	skb->nh.ipv6h = iph = (struct ipv6hdr *)skb_put(skb, length);
 
 	skb->ip_summed = CHECKSUM_NONE;
@@ -527,21 +534,27 @@
 	if (err)
 		goto error_fault;
 
-	IP6_INC_STATS(Ip6OutRequests);		
+	IP6_INC_STATS(Ip6OutRequests);
+	IPV6_INC_STATS(idev, ipStatsOutRequests);
+	IPV6_ADD_STATS(idev, ipStatsOutOctets, skb->len);
+
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
 		err = inet->recverr ? net_xmit_errno(err) : 0;
 	if (err)
 		goto error;
-out:
-	return 0;
-
+	else
+		goto out;
 error_fault:
 	err = -EFAULT;
 	kfree_skb(skb);
 error:
 	IP6_INC_STATS(Ip6OutDiscards);
+	IPV6_INC_STATS(idev, ipStatsOutDiscards);
+out:
+	if (idev)
+		in6_dev_put(idev);
 	return err; 
 }
 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
diff -urN linux-2.6.6/net/ipv6/reassembly.c linux-2.6.6-newmibs/net/ipv6/reassembly.c
--- linux-2.6.6/net/ipv6/reassembly.c	2004-05-09 19:32:27.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/reassembly.c	2004-05-26 12:05:40.000000000 -0700
@@ -264,6 +264,7 @@
 {
 	struct frag_queue *fq;
 	struct list_head *tmp;
+	struct inet6_dev *idev = NULL;
 
 	for(;;) {
 		if (atomic_read(&ip6_frag_mem) <= sysctl_ip6frag_low_thresh)
@@ -285,12 +286,18 @@
 
 		fq_put(fq);
 		IP6_INC_STATS_BH(Ip6ReasmFails);
+		/* idev might be pointed to NULL */
+		if (fq->fragments)
+			idev = __in6_dev_get(fq->fragments->dev);
+		IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 	}
 }
 
 static void ip6_frag_expire(unsigned long data)
 {
 	struct frag_queue *fq = (struct frag_queue *) data;
+	struct net_device *dev;
+	struct inet6_dev *idev = NULL;
 
 	spin_lock(&fq->lock);
 
@@ -301,10 +308,14 @@
 
 	IP6_INC_STATS_BH(Ip6ReasmTimeout);
 	IP6_INC_STATS_BH(Ip6ReasmFails);
+	dev = dev_get_by_index(fq->iif);
+	if (dev)
+		idev = __in6_dev_get(dev);
+	IPV6_INC_STATS_BH(idev, ipStatsInDiscards);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 
 	/* Send error only if the first segment arrived. */
 	if (fq->last_in&FIRST_IN && fq->fragments) {
-		struct net_device *dev = dev_get_by_index(fq->iif);
 
 		/*
 		   But use as source device on which LAST ARRIVED
@@ -315,9 +326,10 @@
 			fq->fragments->dev = dev;
 			icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0,
 				    dev);
-			dev_put(dev);
 		}
 	}
+	if (dev)
+		dev_put(dev);
 out:
 	spin_unlock(&fq->lock);
 	fq_put(fq);
@@ -367,6 +379,7 @@
 ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst)
 {
 	struct frag_queue *fq;
+	struct inet6_dev *idev = NULL;
 
 	if ((fq = frag_alloc_queue()) == NULL)
 		goto oom;
@@ -387,6 +400,7 @@
 
 oom:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 	return NULL;
 }
 
@@ -417,7 +431,10 @@
 {
 	struct sk_buff *prev, *next;
 	int offset, end;
+	struct inet6_dev *idev = NULL;
 
+	if (skb->dev)
+		idev = __in6_dev_get(skb->dev);
 	if (fq->last_in & COMPLETE)
 		goto err;
 
@@ -427,6 +444,7 @@
 
 	if ((unsigned int)end > IPV6_MAXPLEN) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
  		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
  		return;
 	}
@@ -454,6 +472,7 @@
 			 * this case. -DaveM
 			 */
 			IP6_INC_STATS_BH(Ip6InHdrErrors);
+			IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 			icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 
 					  offsetof(struct ipv6hdr, payload_len));
 			return;
@@ -573,6 +592,7 @@
 
 err:
 	IP6_INC_STATS(Ip6ReasmFails);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 	kfree_skb(skb);
 }
 
@@ -592,7 +612,10 @@
 	struct sk_buff *fp, *head = fq->fragments;
 	int    payload_len;
 	unsigned int nhoff;
-
+	struct inet6_dev *idev = NULL;
+	
+	if (dev)
+		idev = __in6_dev_get(dev);
 	fq_kill(fq);
 
 	BUG_TRAP(head != NULL);
@@ -667,6 +690,7 @@
 		head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
 
 	IP6_INC_STATS_BH(Ip6ReasmOKs);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmOKs);
 	fq->fragments = NULL;
 	*nhoffp = nhoff;
 	return 1;
@@ -680,6 +704,7 @@
 		printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
 out_fail:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 	return -1;
 }
 
@@ -690,19 +715,25 @@
 	struct frag_hdr *fhdr;
 	struct frag_queue *fq;
 	struct ipv6hdr *hdr;
+	struct inet6_dev *idev = NULL;
 
+	if (dev)
+		idev = __in6_dev_get(dev);
 	hdr = skb->nh.ipv6h;
 
 	IP6_INC_STATS_BH(Ip6ReasmReqds);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmReqds);
 
 	/* Jumbo payload inhibits frag. header */
 	if (hdr->payload_len==0) {
 		IP6_INC_STATS(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
 		IP6_INC_STATS(Ip6InHdrErrors);
+		IPV6_INC_STATS_BH(idev, ipStatsInHdrErrors);
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
 		return -1;
 	}
@@ -714,6 +745,7 @@
 		/* It is not a fragmented frame */
 		skb->h.raw += sizeof(struct frag_hdr);
 		IP6_INC_STATS_BH(Ip6ReasmOKs);
+		IPV6_INC_STATS_BH(idev, ipStatsReasmOKs);
 
 		*nhoffp = (u8*)fhdr - skb->nh.raw;
 		return 1;
@@ -739,6 +771,7 @@
 	}
 
 	IP6_INC_STATS_BH(Ip6ReasmFails);
+	IPV6_INC_STATS_BH(idev, ipStatsReasmFails);
 	kfree_skb(skb);
 	return -1;
 }
diff -urN linux-2.6.6/net/ipv6/route.c linux-2.6.6-newmibs/net/ipv6/route.c
--- linux-2.6.6/net/ipv6/route.c	2004-05-09 19:33:05.000000000 -0700
+++ linux-2.6.6-newmibs/net/ipv6/route.c	2004-05-26 12:05:40.000000000 -0700
@@ -85,7 +85,8 @@
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static int		 ip6_dst_gc(void);
 
-static int		ip6_pkt_discard(struct sk_buff *skb);
+static int		ip6_pkt_indiscard(struct sk_buff *skb);
+static int		ip6_pkt_outdiscard(struct sk_buff *skb);
 static void		ip6_link_failure(struct sk_buff *skb);
 static void		ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
 
@@ -110,8 +111,8 @@
 			.obsolete	= -1,
 			.error		= -ENETUNREACH,
 			.metrics	= { [RTAX_HOPLIMIT - 1] = 255, },
-			.input		= ip6_pkt_discard,
-			.output		= ip6_pkt_discard,
+			.input		= ip6_pkt_indiscard,
+			.output		= ip6_pkt_outdiscard,
 			.ops		= &ip6_dst_ops,
 			.path		= (struct dst_entry*)&ip6_null_entry,
 		}
@@ -767,8 +768,8 @@
 			dev_put(dev);
 		dev = &loopback_dev;
 		dev_hold(dev);
-		rt->u.dst.output = ip6_pkt_discard;
-		rt->u.dst.input = ip6_pkt_discard;
+		rt->u.dst.output = ip6_pkt_outdiscard;
+		rt->u.dst.input = ip6_pkt_indiscard;
 		rt->u.dst.error = -ENETUNREACH;
 		rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
 		goto install_route;
@@ -1255,9 +1256,30 @@
  *	Drop the packet on the floor
  */
 
-int ip6_pkt_discard(struct sk_buff *skb)
+static int ip6_pkt_indiscard(struct sk_buff *skb)
 {
+	struct inet6_dev *idev = NULL;
+
+	if (skb->dev)
+		idev = __in6_dev_get(skb->dev);
+	
+	IP6_INC_STATS(Ip6InNoRoutes);
+	IPV6_INC_STATS(idev, ipStatsInNoRoutes);
+	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
+	kfree_skb(skb);
+	return 0;
+}
+
+
+static int ip6_pkt_outdiscard(struct sk_buff *skb)
+{
+	struct inet6_dev *idev = NULL;
+	
+	if (skb->dev)
+		idev = __in6_dev_get(skb->dev);
+	
 	IP6_INC_STATS(Ip6OutNoRoutes);
+	IPV6_INC_STATS(idev, ipStatsOutNoRoutes);
 	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
 	kfree_skb(skb);
 	return 0;

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] pmtu check conditions error in IPv6
  2004-03-17 19:30 [PATCH]dump interface IPv6 multicast/anycast addresses through netlink Shirley Ma
  2004-03-19  6:06 ` David S. Miller
  2004-03-19  6:55 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-26 20:19 ` Shirley Ma
  2004-05-26 20:24   ` David S. Miller
  2004-05-26 20:50   ` [PATCH] IFA_MAX sets wrong in rtnetlink.h Shirley Ma
  2 siblings, 2 replies; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 20:19 UTC (permalink / raw)
  To: davem; +Cc: netdev, xma

[-- Attachment #1: Type: text/plain, Size: 216 bytes --]

Here is the patch. IPv6 pmtu check conditions were wrong in these two places.
this patch is against 2.6.6 kernel. It has been tested under 2.6.5 kernel for 
IPsec.

-- 
Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.6.pmtu.patch --]
[-- Type: text/x-diff, Size: 966 bytes --]

diff -urN linux-2.6.6/net/ipv6/route.c linux-2.6.6.pmtu/net/ipv6/route.c
--- linux-2.6.6/net/ipv6/route.c	2004-05-09 19:33:05.000000000 -0700
+++ linux-2.6.6.pmtu/net/ipv6/route.c	2004-05-26 13:15:28.288796272 -0700
@@ -554,6 +554,8 @@
 
 	if (mtu < dst_pmtu(dst) && rt6->rt6i_dst.plen == 128) {
 		rt6->rt6i_flags |= RTF_MODIFIED;
+		if (mtu < IPV6_MIN_MTU)
+			mtu = IPV6_MIN_MTU;
 		dst->metrics[RTAX_MTU-1] = mtu;
 	}
 }
diff -urN linux-2.6.6/net/ipv6/xfrm6_policy.c linux-2.6.6.pmtu/net/ipv6/xfrm6_policy.c
--- linux-2.6.6/net/ipv6/xfrm6_policy.c	2004-05-09 19:32:26.000000000 -0700
+++ linux-2.6.6.pmtu/net/ipv6/xfrm6_policy.c	2004-05-26 13:15:28.322791104 -0700
@@ -236,10 +236,10 @@
 {
 	struct dst_entry *path = dst->path;
 
-	if (mtu >= 1280 && mtu < dst_pmtu(dst))
-		return;
-
-	path->ops->update_pmtu(path, mtu);
+	if (mtu >= IPV6_MIN_MTU && mtu < dst_pmtu(dst))
+		path->ops->update_pmtu(path, mtu);
+	
+	return;
 }
 
 struct dst_ops xfrm6_dst_ops = {

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
@ 2004-05-26 20:22         ` David S. Miller
  2004-05-26 20:42           ` Shirley Ma
  2004-06-09 23:00         ` [PATCH] dst allocation problem in ndisc Shirley Ma
  2004-06-09 23:29         ` [PATCH] some condition check error in ipsec v6 Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-05-26 20:22 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, yoshfuji, xma

On Wed, 26 May 2004 13:10:05 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> This patch implements both per interface and global new IPv6 MIBs counters 
> through netlink based on new IP MIBs draft, 64 bit counters are not supported 
> here because of performance issues. It coexists old IPv6 MIBs counters (which 
> are through proc file system) for the compatibility.

Just to clarify, you named the struct ip_stats because we will use this
eventually for ipv4 as well?  Otherwise we should name it ip6_stats or
something like that.

Otherwise I think your patch is fine.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] pmtu check conditions error in IPv6
  2004-05-26 20:19 ` [PATCH] pmtu check conditions error in IPv6 Shirley Ma
@ 2004-05-26 20:24   ` David S. Miller
  2004-05-26 20:50   ` [PATCH] IFA_MAX sets wrong in rtnetlink.h Shirley Ma
  1 sibling, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-05-26 20:24 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, xma

On Wed, 26 May 2004 13:19:55 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> Here is the patch. IPv6 pmtu check conditions were wrong in these two places.
> this patch is against 2.6.6 kernel. It has been tested under 2.6.5 kernel for 
> IPsec.

Patch applied, thanks Shirley.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 20:22         ` David S. Miller
@ 2004-05-26 20:42           ` Shirley Ma
  2004-05-26 20:44             ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 20:42 UTC (permalink / raw)
  To: David S. Miller; +Cc: mashirle, netdev, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

Yes, same structure ip_stats applys to IPv4 as well.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228


[-- Attachment #2: Type: text/html, Size: 331 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 20:42           ` Shirley Ma
@ 2004-05-26 20:44             ` David S. Miller
  2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-05-26 20:44 UTC (permalink / raw)
  To: Shirley Ma; +Cc: mashirle, netdev, yoshfuji

On Wed, 26 May 2004 13:42:23 -0700
Shirley Ma <xma@us.ibm.com> wrote:

> Yes, same structure ip_stats applys to IPv4 as well.

Great, patch applied.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-26 20:19 ` [PATCH] pmtu check conditions error in IPv6 Shirley Ma
  2004-05-26 20:24   ` David S. Miller
@ 2004-05-26 20:50   ` Shirley Ma
  2004-05-26 20:56     ` David S. Miller
  1 sibling, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 20:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, xma

[-- Attachment #1: Type: text/plain, Size: 87 bytes --]

A tiny patch here for 2.6.6 kernel.

-- 
Thanks
Shirley Ma
IBM Linux Technology Center

[-- Attachment #2: linux-2.6.6-max.patch --]
[-- Type: text/x-diff, Size: 375 bytes --]

diff -urN linux-2.6.6/include/linux/rtnetlink.h linux-2.6.6-max/include/linux/rtnetlink.h
--- linux-2.6.6/include/linux/rtnetlink.h	2004-05-09 19:33:13.000000000 -0700
+++ linux-2.6.6-max/include/linux/rtnetlink.h	2004-05-26 13:47:20.535090648 -0700
@@ -348,7 +348,7 @@
 	IFA_MULTICAST
 };
 
-#define IFA_MAX IFA_CACHEINFO
+#define IFA_MAX IFA_MULTICAST
 
 /* ifa_flags */
 

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-26 20:50   ` [PATCH] IFA_MAX sets wrong in rtnetlink.h Shirley Ma
@ 2004-05-26 20:56     ` David S. Miller
  2004-05-28  4:48       ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-05-26 20:56 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, xma

On Wed, 26 May 2004 13:50:39 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> A tiny patch here for 2.6.6 kernel.

Good catch, patch applied.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 20:44             ` David S. Miller
@ 2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 23:22                 ` YOSHIFUJI Hideaki / 吉藤英明
                                   ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-26 23:08 UTC (permalink / raw)
  To: davem; +Cc: xma, mashirle, netdev, yoshfuji

In article <20040526134415.483a6384.davem@redhat.com> (at Wed, 26 May 2004 13:44:15 -0700), "David S. Miller" <davem@redhat.com> says:

> On Wed, 26 May 2004 13:42:23 -0700
> Shirley Ma <xma@us.ibm.com> wrote:
> 
> > Yes, same structure ip_stats applys to IPv4 as well.
> 
> Great, patch applied.

I failed to comment because I've just waken up...

Hmm, why are you so hurrying?
It on -rc stage and 2.6.7 is coming.
Each people should moderate yourself...

Sorry, please exclude it for now.

Comments:

Without adding support for u64 counter, it does not make sense to add
new interface. You can add new counter to the end of the structures.

This also contains per-interface statistics support.
(I rember that you said that) we should add idev into an route and avoid
get/put idev.

I strongly do not want to poeple to change their code twice to support
draft-ietf-ipv6-rfc2011-update-XX.txt.

I personally think this should be included in 2.7 phase.

--yoshfuji @ morning

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-26 23:22                 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 23:22                 ` David S. Miller
  2004-05-26 23:32                 ` Shirley Ma
  2 siblings, 0 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-26 23:22 UTC (permalink / raw)
  To: davem; +Cc: xma, mashirle, netdev, yoshfuji

To clarify...

In article <20040527.080828.06774575.yoshfuji@linux-ipv6.org> (at Thu, 27 May 2004 08:08:28 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says:

> I strongly do not want to poeple to change their code twice to support
> draft-ietf-ipv6-rfc2011-update-XX.txt.
(because of u64 things)

> I personally think this should be included in 2.7 phase.
(because of route things)

--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 23:22                 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-26 23:22                 ` David S. Miller
  2004-05-26 23:34                   ` Shirley Ma
  2004-05-26 23:32                 ` Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-05-26 23:22 UTC (permalink / raw)
  To: yoshfuji; +Cc: xma, mashirle, netdev

On Thu, 27 May 2004 08:08:28 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> Hmm, why are you so hurrying?

I've only added it to my tree and have not pushed it off to Linus.
I was in fact waiting for your feedback to occur first :-)

I see no way we will get the proper u64 support working any
time soon, it is a hard problem to get that right and with
acceptable performance on 32-bit platforms.

About idev in routes, we can add that as an optimization later.

Poor Shirley has waited long enough to get this feature integrated
and given current knowledge it is the best working implementation
we can come up with at this time.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 23:22                 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-26 23:22                 ` David S. Miller
@ 2004-05-26 23:32                 ` Shirley Ma
  2004-05-26 23:58                   ` YOSHIFUJI Hideaki / 吉藤英明
  2 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 23:32 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, mashirle, netdev, Hideaki YOSHIFUJI, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 1037 bytes --]

Hi,Yoshifuji

        Thanks for you comments!

> Without adding support for u64 counter, it does not make sense to add
> new interface. You can add new counter to the end of the structures.

It's not good to add new counters to the end of the old structure. The mib 

number and offset will be wrong.

>This also contains per-interface statistics support.
(I rember that you said that) we should add idev into an route and avoid
get/put idev.

Only a few get/put idev there, not too many. And in some places there are 
no 
route, no we can't use idev in route.

> I strongly do not want to poeple to change their code twice to support
draft-ietf-ipv6-rfc2011-update-XX.txt.

All the counters not just IP will be eventually 64 bits. We can fix it 
later. And 
if we implement 64 counters here, there is performance issue on some 
architectures which don't support atmoic 64 for 32 bit platform.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228


[-- Attachment #2: Type: text/html, Size: 1571 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:22                 ` David S. Miller
@ 2004-05-26 23:34                   ` Shirley Ma
  0 siblings, 0 replies; 47+ messages in thread
From: Shirley Ma @ 2004-05-26 23:34 UTC (permalink / raw)
  To: David S. Miller; +Cc: mashirle, netdev, netdev-bounce, yoshfuji

[-- Attachment #1: Type: text/plain, Size: 375 bytes --]

> Poor Shirley has waited long enough to get this feature integrated
and given current knowledge it is the best working implementation
we can come up with at this time.

Appreciate your understanding. Maitaining this patch takes time.

Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228

[-- Attachment #2: Type: text/html, Size: 551 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:32                 ` Shirley Ma
@ 2004-05-26 23:58                   ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-27  0:01                     ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-26 23:58 UTC (permalink / raw)
  To: xma; +Cc: davem, mashirle, netdev, yoshfuji

In article <OFA97F4753.DC8C93AD-ON87256EA0.0080DAAB-07256EA0.00814B08@us.ibm.com> (at Wed, 26 May 2004 16:32:04 -0700), Shirley Ma <xma@us.ibm.com> says:

> > Without adding support for u64 counter, it does not make sense to add
> > new interface. You can add new counter to the end of the structures.
> 
> It's not good to add new counters to the end of the old structure. The mib 
> 
> number and offset will be wrong.

I don't think so.
But, even if so, we can add only missing stats.

> >This also contains per-interface statistics support.
> (I rember that you said that) we should add idev into an route and avoid
> get/put idev.
> 
> Only a few get/put idev there, not too many. And in some places there are 
> no 
> route, no we can't use idev in route.

okay.

> > I strongly do not want to poeple to change their code twice to support
> draft-ietf-ipv6-rfc2011-update-XX.txt.
> 
> All the counters not just IP will be eventually 64 bits. We can fix it 
> later. And 
> if we implement 64 counters here, there is performance issue on some 
> architectures which don't support atmoic 64 for 32 bit platform.

I strongly do not want to change interface twice to support these new
statistics.

--yoshfuji @ driving traffic jam

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH]Add new IPv6 MIBs counters support through netlink
  2004-05-26 23:58                   ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-27  0:01                     ` David S. Miller
  0 siblings, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-05-27  0:01 UTC (permalink / raw)
  To: yoshfuji; +Cc: xma, mashirle, netdev

On Thu, 27 May 2004 08:58:12 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> > All the counters not just IP will be eventually 64 bits. We can fix it 
> > later. And 
> > if we implement 64 counters here, there is performance issue on some 
> > architectures which don't support atmoic 64 for 32 bit platform.
> 
> I strongly do not want to change interface twice to support these new
> statistics.

As a side note, I am worried about investing so much effort and
expense if by the time we make 64-bit atomic counters work acceptably
on 32-bit platforms we are all running Opteron machines :-)

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-26 20:56     ` David S. Miller
@ 2004-05-28  4:48       ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-28  5:07         ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-28  4:48 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji

In article <20040526135610.2ecaa96a.davem@redhat.com> (at Wed, 26 May 2004 13:56:10 -0700), "David S. Miller" <davem@redhat.com> says:

> On Wed, 26 May 2004 13:50:39 -0700
> Shirley Ma <mashirle@us.ibm.com> wrote:
> 
> > A tiny patch here for 2.6.6 kernel.
> 
> Good catch, patch applied.

BTW, how do you think of the code below to minimize diffs and risk of error
when we add new item for enum?

enum {
     :
     IFA_MULTICAST,
     __IFA_MAX
};

#define IFA_MAX (__IFA_MAX - 1)

-----
enum {
     :
     IFA_CACHEINFO
};

#define IFA_MAX IFA_CACHEINFO

enum {
     :
     IFA_CACHEINFO,  /* changed to add "," */
     IFA_MULTICAST   /* added */
};

#define IFA_MAX IFA_MULTICAST /* changed */

--- vs ---

enum {
     :
     IFA_CACHEINFO,
     __IFA_MAX
};

#define IFA_MAX (__IFA_MAX - 1)

enum {
     :
     IFA_CACHEINFO,
     IFA_MULTICAST,   /* added */
     __IFA_MAX
};

#define IFA_MAX (__IFA_MAX - 1)

--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-28  4:48       ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-28  5:07         ` David S. Miller
  2004-05-28  5:12           ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 47+ messages in thread
From: David S. Miller @ 2004-05-28  5:07 UTC (permalink / raw)
  To: yoshfuji; +Cc: netdev

On Fri, 28 May 2004 13:48:02 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> enum {
>      :
>      IFA_CACHEINFO,
>      IFA_MULTICAST,   /* added */
>      __IFA_MAX
> };
> 
> #define IFA_MAX (__IFA_MAX - 1)

I like this last technique the best, one-line diffs :-)

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-28  5:07         ` David S. Miller
@ 2004-05-28  5:12           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-28  9:25             ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-28  9:27             ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 2 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-28  5:12 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji

In article <20040527220756.7c41a55b.davem@redhat.com> (at Thu, 27 May 2004 22:07:56 -0700), "David S. Miller" <davem@redhat.com> says:

> On Fri, 28 May 2004 13:48:02 +0900 (JST)
> YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:
> 
> > enum {
> >      :
> >      IFA_CACHEINFO,
> >      IFA_MULTICAST,   /* added */
> >      __IFA_MAX
> > };
> > 
> > #define IFA_MAX (__IFA_MAX - 1)
> 
> I like this last technique the best, one-line diffs :-)

Ok, I'll do this.

--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-28  5:12           ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-28  9:25             ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-29 19:36               ` David S. Miller
  2004-05-28  9:27             ` YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-28  9:25 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji

In article <20040528.141200.564308976.yoshfuji@linux-ipv6.org> (at Fri, 28 May 2004 14:12:00 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says:

> In article <20040527220756.7c41a55b.davem@redhat.com> (at Thu, 27 May 2004 22:07:56 -0700), "David S. Miller" <davem@redhat.com> says:
> 
> > On Fri, 28 May 2004 13:48:02 +0900 (JST)
> > YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> wrote:
> > 
> > > enum {
> > >      :
> > >      IFA_CACHEINFO,
> > >      IFA_MULTICAST,   /* added */
> > >      __IFA_MAX
> > > };
> > > 
> > > #define IFA_MAX (__IFA_MAX - 1)
> > 
> > I like this last technique the best, one-line diffs :-)
> 
> Ok, I'll do this.

Here's the patch for 2.6. Please apply on top of the Sirley's patch.

--- linux-2.6+max/include/linux/rtnetlink.h	Fri May 28 17:56:55 2004
+++ linux-2.6+automax/include/linux/rtnetlink.h	Fri May 28 17:55:55 2004
@@ -118,9 +118,10 @@
 	RTN_THROW,		/* Not in this table		*/
 	RTN_NAT,		/* Translate this address	*/
 	RTN_XRESOLVE,		/* Use external resolver	*/
+	__RTN_MAX
 };
 
-#define RTN_MAX RTN_XRESOLVE
+#define RTN_MAX (__RTN_MAX - 1)
 
 
 /* rtm_protocol */
@@ -183,9 +184,10 @@
 /* User defined values */
 	RT_TABLE_DEFAULT=253,
 	RT_TABLE_MAIN=254,
-	RT_TABLE_LOCAL=255
+	RT_TABLE_LOCAL=255,
+	__RT_TABLE_MAX
 };
-#define RT_TABLE_MAX RT_TABLE_LOCAL
+#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
 
 
 
@@ -207,9 +209,10 @@
 	RTA_FLOW,
 	RTA_CACHEINFO,
 	RTA_SESSION,
+	__RTA_MAX
 };
 
-#define RTA_MAX RTA_SESSION
+#define RTA_MAX (__RTA_MAX - 1)
 
 #define RTM_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
 #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
@@ -294,9 +297,10 @@
 #define RTAX_INITCWND RTAX_INITCWND
 	RTAX_FEATURES,
 #define RTAX_FEATURES RTAX_FEATURES
+	__RTAX_MAX
 };
 
-#define RTAX_MAX RTAX_FEATURES
+#define RTAX_MAX (__RTAX_MAX - 1)
 
 #define RTAX_FEATURE_ECN	0x00000001
 #define RTAX_FEATURE_SACK	0x00000002
@@ -345,10 +349,11 @@
 	IFA_BROADCAST,
 	IFA_ANYCAST,
 	IFA_CACHEINFO,
-	IFA_MULTICAST
+	IFA_MULTICAST,
+	__IFA_MAX
 };
 
-#define IFA_MAX IFA_MULTICAST
+#define IFA_MAX (__IFA_MAX - 1)
 
 /* ifa_flags */
 
@@ -399,10 +404,11 @@
 	NDA_UNSPEC,
 	NDA_DST,
 	NDA_LLADDR,
-	NDA_CACHEINFO
+	NDA_CACHEINFO,
+	__NDA_MAX
 };
 
-#define NDA_MAX NDA_CACHEINFO
+#define NDA_MAX (__NDA_MAX - 1)
 
 #define NDA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
@@ -485,9 +491,10 @@
 	PREFIX_UNSPEC,
 	PREFIX_ADDRESS,
 	PREFIX_CACHEINFO,
+	__PREFIX_MAX
 };
 
-#define PREFIX_MAX	PREFIX_CACHEINFO
+#define PREFIX_MAX	(__PREFIX_MAX - 1)
 
 struct prefix_cacheinfo
 {
@@ -549,10 +556,11 @@
 #define IFLA_WIRELESS IFLA_WIRELESS
 	IFLA_PROTINFO,		/* Protocol specific information for a link */
 #define IFLA_PROTINFO IFLA_PROTINFO
+	__IFLA_MAX
 };
 
 
-#define IFLA_MAX IFLA_PROTINFO
+#define IFLA_MAX (__IFLA_MAX - 1)
 
 #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
 #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
@@ -595,8 +603,11 @@
 	IFLA_INET6_STATS,	/* statistics			*/
 	IFLA_INET6_MCAST,	/* MC things. What of them?	*/
 	IFLA_INET6_CACHEINFO,	/* time values and max reasm size */
+	__IFLA_INET6_MAX
 };
 
+#define IFLA_INET6_MAX	(__IFLA_INET6_MAX - 1)
+
 struct ifla_cacheinfo
 {
 	__u32	max_reasm_len;
@@ -605,8 +616,6 @@
 	__u32	retrans_time;
 };
 
-#define IFLA_INET6_MAX	IFLA_INET6_CACHEINFO
-
 /*****************************************************************
  *		Traffic control messages.
  ****/
@@ -630,9 +639,10 @@
 	TCA_STATS,
 	TCA_XSTATS,
 	TCA_RATE,
+	__TCA_MAX
 };
 
-#define TCA_MAX TCA_RATE
+#define TCA_MAX (__TCA_MAX - 1)
 
 #define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
--- linux-2.6+max/include/linux/pkt_cls.h	2002-02-06 02:39:42 +09:00
+++ linux-2.6+automax/include/linux/pkt_cls.h	2004-05-28 17:53:49 +09:00
@@ -24,11 +24,12 @@
 	TCA_POLICE_RATE,
 	TCA_POLICE_PEAKRATE,
 	TCA_POLICE_AVRATE,
-	TCA_POLICE_RESULT
+	TCA_POLICE_RESULT,
 #define TCA_POLICE_RESULT TCA_POLICE_RESULT
+	__TCA_POLICE_MAX
 };
 
-#define TCA_POLICE_MAX TCA_POLICE_RESULT
+#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
 
 /* U32 filters */
 
@@ -49,9 +50,10 @@
 	TCA_U32_DIVISOR,
 	TCA_U32_SEL,
 	TCA_U32_POLICE,
+	__TCA_U32_MAX
 };
 
-#define TCA_U32_MAX TCA_U32_POLICE
+#define TCA_U32_MAX (__TCA_U32_MAX - 1)
 
 struct tc_u32_key
 {
@@ -97,9 +99,10 @@
 	TCA_RSVP_SRC,
 	TCA_RSVP_PINFO,
 	TCA_RSVP_POLICE,
+	__TCA_RSVP_MAX
 };
 
-#define TCA_RSVP_MAX TCA_RSVP_POLICE
+#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1)
 
 struct tc_rsvp_gpi
 {
@@ -127,9 +130,10 @@
 	TCA_ROUTE4_FROM,
 	TCA_ROUTE4_IIF,
 	TCA_ROUTE4_POLICE,
+	__TCA_ROUTE4_MAX
 };
 
-#define TCA_ROUTE4_MAX TCA_ROUTE4_POLICE
+#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
 
 
 /* FW filter */
@@ -139,9 +143,10 @@
 	TCA_FW_UNSPEC,
 	TCA_FW_CLASSID,
 	TCA_FW_POLICE,
+	__TCA_FW_MAX
 };
 
-#define TCA_FW_MAX TCA_FW_POLICE
+#define TCA_FW_MAX (__TCA_FW_MAX - 1)
 
 /* TC index filter */
 
@@ -154,8 +159,9 @@
 	TCA_TCINDEX_FALL_THROUGH,
 	TCA_TCINDEX_CLASSID,
 	TCA_TCINDEX_POLICE,
+	__TCA_TCINDEX_MAX
 };
 
-#define TCA_TCINDEX_MAX        TCA_TCINDEX_POLICE
+#define TCA_TCINDEX_MAX        (__TCA_TCINDEX_MAX - 1)
 
 #endif
--- linux-2.6+max/include/linux/xfrm.h	2003-08-08 13:04:46 +09:00
+++ linux-2.6+automax/include/linux/xfrm.h	2004-05-28 17:01:28 +09:00
@@ -152,8 +152,9 @@
 	XFRMA_ALG_COMP,		/* struct xfrm_algo */
 	XFRMA_ENCAP,		/* struct xfrm_algo + struct xfrm_encap_tmpl */
 	XFRMA_TMPL,		/* 1 or more struct xfrm_user_tmpl */
+	__XFRMA_MAX
 
-#define XFRMA_MAX XFRMA_TMPL
+#define XFRMA_MAX (__XFRMA_MAX - 1)
 };
 
 struct xfrm_usersa_info {

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-28  5:12           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-05-28  9:25             ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-28  9:27             ` YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 0 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-05-28  9:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji

In article <20040528.141200.564308976.yoshfuji@linux-ipv6.org> (at Fri, 28 May 2004 14:12:00 +0900 (JST)), YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> says:

> In article <20040527220756.7c41a55b.davem@redhat.com> (at Thu, 27 May 2004 22:07:56 -0700), "David S. Miller" <davem@redhat.com> says:
> 
> > On Fri, 28 May 2004 13:48:02 +0900 (JST)
> > YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> wrote:
> > 
> > > enum {
> > >      :
> > >      IFA_CACHEINFO,
> > >      IFA_MULTICAST,   /* added */
> > >      __IFA_MAX
> > > };
> > > 
> > > #define IFA_MAX (__IFA_MAX - 1)
> > 
> > I like this last technique the best, one-line diffs :-)
> 
> Ok, I'll do this.

Here's the patch for 2.4.

===== include/linux/pkt_cls.h 1.1 vs edited =====
--- 1.1/include/linux/pkt_cls.h	2002-02-06 02:39:42 +09:00
+++ edited/include/linux/pkt_cls.h	2004-05-28 17:25:08 +09:00
@@ -24,11 +24,12 @@
 	TCA_POLICE_RATE,
 	TCA_POLICE_PEAKRATE,
 	TCA_POLICE_AVRATE,
-	TCA_POLICE_RESULT
+	TCA_POLICE_RESULT,
 #define TCA_POLICE_RESULT TCA_POLICE_RESULT
+	__TCA_POLICE_MAX
 };
 
-#define TCA_POLICE_MAX TCA_POLICE_RESULT
+#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
 
 /* U32 filters */
 
@@ -49,9 +50,10 @@
 	TCA_U32_DIVISOR,
 	TCA_U32_SEL,
 	TCA_U32_POLICE,
+	__TCA_U32_MAX
 };
 
-#define TCA_U32_MAX TCA_U32_POLICE
+#define TCA_U32_MAX (__TCA_U32_MAX - 1)
 
 struct tc_u32_key
 {
@@ -97,9 +99,10 @@
 	TCA_RSVP_SRC,
 	TCA_RSVP_PINFO,
 	TCA_RSVP_POLICE,
+	__TCA_RSVP_MAX
 };
 
-#define TCA_RSVP_MAX TCA_RSVP_POLICE
+#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1)
 
 struct tc_rsvp_gpi
 {
@@ -127,9 +130,10 @@
 	TCA_ROUTE4_FROM,
 	TCA_ROUTE4_IIF,
 	TCA_ROUTE4_POLICE,
+	__TCA_ROUTE4_MAX
 };
 
-#define TCA_ROUTE4_MAX TCA_ROUTE4_POLICE
+#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
 
 
 /* FW filter */
@@ -139,9 +143,10 @@
 	TCA_FW_UNSPEC,
 	TCA_FW_CLASSID,
 	TCA_FW_POLICE,
+	__TCA_FW_MAX
 };
 
-#define TCA_FW_MAX TCA_FW_POLICE
+#define TCA_FW_MAX (__TCA_FW_MAX - 1)
 
 /* TC index filter */
 
@@ -154,8 +159,9 @@
 	TCA_TCINDEX_FALL_THROUGH,
 	TCA_TCINDEX_CLASSID,
 	TCA_TCINDEX_POLICE,
+	__TCA_TCINDEX_MAX
 };
 
-#define TCA_TCINDEX_MAX        TCA_TCINDEX_POLICE
+#define TCA_TCINDEX_MAX        (__TCA_TCINDEX_MAX - 1)
 
 #endif
===== include/linux/rtnetlink.h 1.11 vs edited =====
--- 1.11/include/linux/rtnetlink.h	2003-12-03 09:28:24 +09:00
+++ edited/include/linux/rtnetlink.h	2004-05-28 18:03:19 +09:00
@@ -113,9 +113,10 @@
 	RTN_THROW,		/* Not in this table		*/
 	RTN_NAT,		/* Translate this address	*/
 	RTN_XRESOLVE,		/* Use external resolver	*/
+	__RTN_MAX
 };
 
-#define RTN_MAX RTN_XRESOLVE
+#define RTN_MAX (__RTN_MAX - 1)
 
 
 /* rtm_protocol */
@@ -178,9 +179,10 @@
 /* User defined values */
 	RT_TABLE_DEFAULT=253,
 	RT_TABLE_MAIN=254,
-	RT_TABLE_LOCAL=255
+	RT_TABLE_LOCAL=255,
+	__RT_TABLE_MAX
 };
-#define RT_TABLE_MAX RT_TABLE_LOCAL
+#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
 
 
 
@@ -200,10 +202,11 @@
 	RTA_MULTIPATH,
 	RTA_PROTOINFO,
 	RTA_FLOW,
-	RTA_CACHEINFO
+	RTA_CACHEINFO,
+	__RTA_MAX
 };
 
-#define RTA_MAX RTA_CACHEINFO
+#define RTA_MAX (__RTA_MAX - 1)
 
 #define RTM_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
 #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
@@ -282,9 +285,10 @@
 #define RTAX_ADVMSS RTAX_ADVMSS
 	RTAX_REORDERING,
 #define RTAX_REORDERING RTAX_REORDERING
+	__RTAX_MAX
 };
 
-#define RTAX_MAX RTAX_REORDERING
+#define RTAX_MAX (__RTAX_MAX - 1)
 
 
 
@@ -309,10 +313,11 @@
 	IFA_LABEL,
 	IFA_BROADCAST,
 	IFA_ANYCAST,
-	IFA_CACHEINFO
+	IFA_CACHEINFO,
+	__IFA_MAX
 };
 
-#define IFA_MAX IFA_CACHEINFO
+#define IFA_MAX (__IFA_MAX - 1)
 
 /* ifa_flags */
 
@@ -360,10 +365,11 @@
 	NDA_UNSPEC,
 	NDA_DST,
 	NDA_LLADDR,
-	NDA_CACHEINFO
+	NDA_CACHEINFO,
+	__NDA_MAX
 };
 
-#define NDA_MAX NDA_CACHEINFO
+#define NDA_MAX (__NDA_MAX - 1)
 
 #define NDA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
@@ -448,10 +454,11 @@
 #define IFLA_WIRELESS IFLA_WIRELESS
 	IFLA_PROTINFO,		/* Protocol specific information for a link */
 #define IFLA_PROTINFO IFLA_PROTINFO
+	__IFLA_MAX
 };
 
 
-#define IFLA_MAX IFLA_PROTINFO
+#define IFLA_MAX (__IFLA_MAX - 1)
 
 #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
 #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
@@ -493,9 +500,10 @@
 	IFLA_INET6_CONF,	/* sysctl parameters		*/
 	IFLA_INET6_STATS,	/* statistics			*/
 	IFLA_INET6_MCAST,	/* MC things. What of them?	*/
+	__IFLA_INET6_MAX
 };
 
-#define IFLA_INET6_MAX	IFLA_INET6_MCAST
+#define IFLA_INET6_MAX	(__IFLA_INET6_MAX - 1)
 
 /*****************************************************************
  *		Traffic control messages.
@@ -520,9 +528,10 @@
 	TCA_STATS,
 	TCA_XSTATS,
 	TCA_RATE,
+	__TCA_MAX
 };
 
-#define TCA_MAX TCA_RATE
+#define TCA_MAX (__TCA_MAX - 1)
 
 #define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))

-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] IFA_MAX sets wrong in rtnetlink.h
  2004-05-28  9:25             ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-05-29 19:36               ` David S. Miller
  0 siblings, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-05-29 19:36 UTC (permalink / raw)
  To: yoshfuji; +Cc: netdev

On Fri, 28 May 2004 18:25:38 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> Here's the patch for 2.6. Please apply on top of the Sirley's patch.

Applied, thanks.

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] dst allocation problem in ndisc
  2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
  2004-05-26 20:22         ` David S. Miller
@ 2004-06-09 23:00         ` Shirley Ma
  2004-06-10  2:12           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-06-09 23:29         ` [PATCH] some condition check error in ipsec v6 Shirley Ma
  2 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-06-09 23:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji, xma

[-- Attachment #1: Type: text/plain, Size: 993 bytes --]

When creating dst entry from ndisc, the dst entry of pmtu is not set, and the 
outout for this kind of dst entry is set to ip_output2 instead of ip_output. 
This could lead to send bigger packets through these des entries without 
fragmentation, and uninitialized pmtu could lead the network unreachable. 

These problems are easy reproduced when configuring IPSEC for ipv6. IPSEC 
could pick up dst entry created by ndisc as child des entry if ndisc dst 
entry generated earlier. If sending bigger packets through IPSEC, the ip 
output2 will send bigger packets out, the driver will drop these packets on 
receiver side. Also the dst_entry pmtu will be 0, the network is unreachable.

The patch has been tested against 2.6.6. I am not sure why ndisc genereats dst 
entry with output equal to ip6_output2 not ip6_output. If ndisc sends bigger 
packets, it will break also. 

Here is the patch against 2.6.6 kernel. Please review this patch.

-- 
Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.6-dst.patch --]
[-- Type: text/x-diff, Size: 3891 bytes --]

diff -urN linux-2.6.6/net/ipv6/ndisc.c linux-2.6.6-dst/net/ipv6/ndisc.c
--- linux-2.6.6/net/ipv6/ndisc.c	2004-05-09 19:32:39.000000000 -0700
+++ linux-2.6.6-dst/net/ipv6/ndisc.c	2004-06-09 15:35:37.000000000 -0700
@@ -395,7 +395,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -486,7 +486,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -562,7 +562,7 @@
 
 	ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
 	if (!dst)
 		return;
 
diff -urN linux-2.6.6/net/ipv6/route.c linux-2.6.6-dst/net/ipv6/route.c
--- linux-2.6.6/net/ipv6/route.c	2004-05-09 19:33:05.000000000 -0700
+++ linux-2.6.6-dst/net/ipv6/route.c	2004-06-09 15:41:49.000000000 -0700
@@ -558,6 +558,56 @@
 	}
 }
 
+/* Clean host part of a prefix. Not necessary in radix tree,
+   but results in cleaner routing tables.
+
+   Remove it only when all the things will work!
+ */
+
+static int ipv6_get_mtu(struct net_device *dev)
+{
+	int mtu = IPV6_MIN_MTU;
+	struct inet6_dev *idev;
+
+	idev = in6_dev_get(dev);
+	if (idev) {
+		mtu = idev->cnf.mtu6;
+		in6_dev_put(idev);
+	}
+	return mtu;
+}
+
+static inline unsigned int ipv6_advmss(unsigned int mtu)
+{
+	mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
+
+	if (mtu < ip6_rt_min_advmss)
+		mtu = ip6_rt_min_advmss;
+
+	/*
+	 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and 
+	 * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. 
+	 * IPV6_MAXPLEN is also valid and means: "any MSS, 
+	 * rely only on pmtu discovery"
+	 */
+	if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
+		mtu = IPV6_MAXPLEN;
+	return mtu;
+}
+
+static int ipv6_get_hoplimit(struct net_device *dev)
+{
+	int hoplimit = ipv6_devconf.hop_limit;
+	struct inet6_dev *idev;
+
+	idev = in6_dev_get(dev);
+	if (idev) {
+		hoplimit = idev->cnf.hop_limit;
+		in6_dev_put(idev);
+	}
+	return hoplimit;
+}
+
 /* Protected by rt6_lock.  */
 static struct dst_entry *ndisc_dst_gc_list;
 
@@ -585,6 +635,8 @@
 	rt->rt6i_metric   = 0;
 	atomic_set(&rt->u.dst.__refcnt, 1);
 	rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
+	rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+	rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
 	rt->u.dst.output  = output;
 
 	write_lock_bh(&rt6_lock);
@@ -641,56 +693,6 @@
 	return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size);
 }
 
-/* Clean host part of a prefix. Not necessary in radix tree,
-   but results in cleaner routing tables.
-
-   Remove it only when all the things will work!
- */
-
-static int ipv6_get_mtu(struct net_device *dev)
-{
-	int mtu = IPV6_MIN_MTU;
-	struct inet6_dev *idev;
-
-	idev = in6_dev_get(dev);
-	if (idev) {
-		mtu = idev->cnf.mtu6;
-		in6_dev_put(idev);
-	}
-	return mtu;
-}
-
-static inline unsigned int ipv6_advmss(unsigned int mtu)
-{
-	mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
-
-	if (mtu < ip6_rt_min_advmss)
-		mtu = ip6_rt_min_advmss;
-
-	/*
-	 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and 
-	 * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. 
-	 * IPV6_MAXPLEN is also valid and means: "any MSS, 
-	 * rely only on pmtu discovery"
-	 */
-	if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
-		mtu = IPV6_MAXPLEN;
-	return mtu;
-}
-
-static int ipv6_get_hoplimit(struct net_device *dev)
-{
-	int hoplimit = ipv6_devconf.hop_limit;
-	struct inet6_dev *idev;
-
-	idev = in6_dev_get(dev);
-	if (idev) {
-		hoplimit = idev->cnf.hop_limit;
-		in6_dev_put(idev);
-	}
-	return hoplimit;
-}
-
 /*
  *
  */

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] some condition check error in ipsec v6
  2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
  2004-05-26 20:22         ` David S. Miller
  2004-06-09 23:00         ` [PATCH] dst allocation problem in ndisc Shirley Ma
@ 2004-06-09 23:29         ` Shirley Ma
  2004-06-10  1:48           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-06-11  5:11           ` David S. Miller
  2 siblings, 2 replies; 47+ messages in thread
From: Shirley Ma @ 2004-06-09 23:29 UTC (permalink / raw)
  To: davem; +Cc: netdev, yoshfuji, xma

[-- Attachment #1: Type: text/plain, Size: 155 bytes --]

Here is a small patch for condition checking in ah6.c and esp6.c. This patch 
is against 2.6.6 kernel.

-- 
Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: linux-2.6.6-ipsec.patch --]
[-- Type: text/x-diff, Size: 897 bytes --]

diff -urN linux-2.6.6/net/ipv6/ah6.c linux-2.6.6-ipsec/net/ipv6/ah6.c
--- linux-2.6.6/net/ipv6/ah6.c	2004-05-09 19:32:53.000000000 -0700
+++ linux-2.6.6-ipsec/net/ipv6/ah6.c	2004-06-09 16:13:26.000000000 -0700
@@ -360,7 +360,7 @@
 	struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
 	struct xfrm_state *x;
 
-	if (type != ICMPV6_DEST_UNREACH ||
+	if (type != ICMPV6_DEST_UNREACH &&
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
diff -urN linux-2.6.6/net/ipv6/esp6.c linux-2.6.6-ipsec/net/ipv6/esp6.c
--- linux-2.6.6/net/ipv6/esp6.c	2004-05-09 19:32:52.000000000 -0700
+++ linux-2.6.6-ipsec/net/ipv6/esp6.c	2004-06-09 16:13:38.000000000 -0700
@@ -324,7 +324,7 @@
 	struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
 	struct xfrm_state *x;
 
-	if (type != ICMPV6_DEST_UNREACH ||
+	if (type != ICMPV6_DEST_UNREACH && 
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] some condition check error in ipsec v6
  2004-06-09 23:29         ` [PATCH] some condition check error in ipsec v6 Shirley Ma
@ 2004-06-10  1:48           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-06-11  5:11           ` David S. Miller
  1 sibling, 0 replies; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-06-10  1:48 UTC (permalink / raw)
  To: mashirle; +Cc: davem, netdev, xma, yoshfuji

In article <200406091629.17365.mashirle@us.ibm.com> (at Wed, 9 Jun 2004 16:29:17 -0700), Shirley Ma <mashirle@us.ibm.com> says:

> Here is a small patch for condition checking in ah6.c and esp6.c. This patch 
> is against 2.6.6 kernel.

good catch.
--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] dst allocation problem in ndisc
  2004-06-09 23:00         ` [PATCH] dst allocation problem in ndisc Shirley Ma
@ 2004-06-10  2:12           ` YOSHIFUJI Hideaki / 吉藤英明
  2004-06-10 20:05             ` Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-06-10  2:12 UTC (permalink / raw)
  To: mashirle; +Cc: davem, netdev, xma, yoshfuji

In article <200406091600.30568.mashirle@us.ibm.com> (at Wed, 9 Jun 2004 16:00:29 -0700), Shirley Ma <mashirle@us.ibm.com> says:

> Here is the patch against 2.6.6 kernel. Please review this patch.

Basically, I agree.
One thing: you can minimize diff using function declaration.

--yoshfuji

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] dst allocation problem in ndisc
  2004-06-10  2:12           ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-06-10 20:05             ` Shirley Ma
  2004-06-10 20:46               ` Shirley Ma
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-06-10 20:05 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, mashirle, netdev, yoshfuji


[-- Attachment #1.1: Type: text/plain, Size: 154 bytes --]

Here it is.



Thanks
Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228

[-- Attachment #1.2: Type: text/html, Size: 290 bytes --]

[-- Attachment #2: linux-2.6.7-rc3.dst.patch --]
[-- Type: application/octet-stream, Size: 1771 bytes --]

diff -urN linux-2.6.7-rc3/net/ipv6/ndisc.c linux-2.6.7-rc3.dst/net/ipv6/ndisc.c
--- linux-2.6.7-rc3/net/ipv6/ndisc.c	2004-06-09 16:42:55.000000000 -0700
+++ linux-2.6.7-rc3.dst/net/ipv6/ndisc.c	2004-06-10 12:51:39.000000000 -0700
@@ -395,7 +395,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -486,7 +486,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -562,7 +562,7 @@
 
 	ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
 	if (!dst)
 		return;
 
diff -urN linux-2.6.7-rc3/net/ipv6/route.c linux-2.6.7-rc3.dst/net/ipv6/route.c
--- linux-2.6.7-rc3/net/ipv6/route.c	2004-06-09 16:42:55.000000000 -0700
+++ linux-2.6.7-rc3.dst/net/ipv6/route.c	2004-06-10 12:53:30.000000000 -0700
@@ -573,6 +573,8 @@
 
 /* Protected by rt6_lock.  */
 static struct dst_entry *ndisc_dst_gc_list;
+static int ipv6_get_mtu(struct net_device *dev);
+static inline unsigned int ipv6_advmss(unsigned int mtu);
 
 struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 
 				  struct neighbour *neigh,
@@ -598,6 +600,8 @@
 	rt->rt6i_metric   = 0;
 	atomic_set(&rt->u.dst.__refcnt, 1);
 	rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
+	rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+	rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
 	rt->u.dst.output  = output;
 
 	write_lock_bh(&rt6_lock);

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] dst allocation problem in ndisc
  2004-06-10 20:05             ` Shirley Ma
@ 2004-06-10 20:46               ` Shirley Ma
  2004-06-11  5:08                 ` David S. Miller
  0 siblings, 1 reply; 47+ messages in thread
From: Shirley Ma @ 2004-06-10 20:46 UTC (permalink / raw)
  To: Shirley Ma
  Cc: davem, mashirle, netdev, netdev-bounce,
	YOSHIFUJI Hideaki / 吉藤英明


[-- Attachment #1.1: Type: text/plain, Size: 205 bytes --]

Change ip6_output2 to static also. This patch is against 2.6.7-rc3.



Shirley Ma
IBM Linux Technology Center
15300 SW Koll Parkway
Beaverton, OR 97006-6063
Phone: (503) 578-7638
FAX:      (503) 578-3228


[-- Attachment #1.2: Type: text/html, Size: 345 bytes --]

[-- Attachment #2: linux-2.6.7-rc3.dst.patch --]
[-- Type: application/octet-stream, Size: 2712 bytes --]

diff -urN linux-2.6.7-rc3/include/net/ipv6.h linux-2.6.7-rc3.dst/include/net/ipv6.h
--- linux-2.6.7-rc3/include/net/ipv6.h	2004-06-09 16:42:45.000000000 -0700
+++ linux-2.6.7-rc3.dst/include/net/ipv6.h	2004-06-10 13:31:40.000000000 -0700
@@ -356,7 +356,6 @@
  */
 
 extern int			ip6_output(struct sk_buff **pskb);
-extern int			ip6_output2(struct sk_buff **pskb);
 extern int			ip6_forward(struct sk_buff *skb);
 extern int			ip6_input(struct sk_buff *skb);
 extern int			ip6_mc_input(struct sk_buff *skb);
diff -urN linux-2.6.7-rc3/net/ipv6/ip6_output.c linux-2.6.7-rc3.dst/net/ipv6/ip6_output.c
--- linux-2.6.7-rc3/net/ipv6/ip6_output.c	2004-06-09 16:42:55.000000000 -0700
+++ linux-2.6.7-rc3.dst/net/ipv6/ip6_output.c	2004-06-10 13:25:15.000000000 -0700
@@ -107,7 +107,7 @@
 }
 
 
-int ip6_output2(struct sk_buff **pskb)
+static int ip6_output2(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct dst_entry *dst = skb->dst;
diff -urN linux-2.6.7-rc3/net/ipv6/ndisc.c linux-2.6.7-rc3.dst/net/ipv6/ndisc.c
--- linux-2.6.7-rc3/net/ipv6/ndisc.c	2004-06-09 16:42:55.000000000 -0700
+++ linux-2.6.7-rc3.dst/net/ipv6/ndisc.c	2004-06-10 12:51:39.000000000 -0700
@@ -395,7 +395,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -486,7 +486,7 @@
 
 	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
 	if (!dst)
 		return;
 
@@ -562,7 +562,7 @@
 
 	ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
 
-	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+	dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
 	if (!dst)
 		return;
 
diff -urN linux-2.6.7-rc3/net/ipv6/route.c linux-2.6.7-rc3.dst/net/ipv6/route.c
--- linux-2.6.7-rc3/net/ipv6/route.c	2004-06-09 16:42:55.000000000 -0700
+++ linux-2.6.7-rc3.dst/net/ipv6/route.c	2004-06-10 12:53:30.000000000 -0700
@@ -573,6 +573,8 @@
 
 /* Protected by rt6_lock.  */
 static struct dst_entry *ndisc_dst_gc_list;
+static int ipv6_get_mtu(struct net_device *dev);
+static inline unsigned int ipv6_advmss(unsigned int mtu);
 
 struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 
 				  struct neighbour *neigh,
@@ -598,6 +600,8 @@
 	rt->rt6i_metric   = 0;
 	atomic_set(&rt->u.dst.__refcnt, 1);
 	rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
+	rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+	rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
 	rt->u.dst.output  = output;
 
 	write_lock_bh(&rt6_lock);

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] dst allocation problem in ndisc
  2004-06-10 20:46               ` Shirley Ma
@ 2004-06-11  5:08                 ` David S. Miller
  0 siblings, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-06-11  5:08 UTC (permalink / raw)
  To: Shirley Ma; +Cc: xma, mashirle, netdev, yoshfuji

On Thu, 10 Jun 2004 14:46:20 -0600
Shirley Ma <xma@us.ibm.com> wrote:

> Change ip6_output2 to static also. This patch is against 2.6.7-rc3.

Patch applied, thanks a lot!

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] some condition check error in ipsec v6
  2004-06-09 23:29         ` [PATCH] some condition check error in ipsec v6 Shirley Ma
  2004-06-10  1:48           ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-06-11  5:11           ` David S. Miller
  1 sibling, 0 replies; 47+ messages in thread
From: David S. Miller @ 2004-06-11  5:11 UTC (permalink / raw)
  To: Shirley Ma; +Cc: netdev, yoshfuji, xma

On Wed, 9 Jun 2004 16:29:17 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> Here is a small patch for condition checking in ah6.c and esp6.c. This patch 
> is against 2.6.6 kernel.

Applied, thanks a lot!

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2004-06-11  5:11 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-17 19:30 [PATCH]dump interface IPv6 multicast/anycast addresses through netlink Shirley Ma
2004-03-19  6:06 ` David S. Miller
2004-03-19  6:52   ` YOSHIFUJI Hideaki / 吉藤英明
2004-03-19  6:55 ` YOSHIFUJI Hideaki / 吉藤英明
2004-03-19  7:16   ` Shirley Ma
2004-03-19  7:32     ` David S. Miller
2004-03-19  8:03       ` Shirley Ma
2004-03-31 18:07     ` Shirley Ma
2004-04-01  4:50       ` YOSHIFUJI Hideaki / 吉藤英明
2004-04-01  5:18         ` Shirley Ma
2004-04-01 18:28           ` Shirley Ma
2004-04-03 22:45             ` David S. Miller
2004-04-05 20:51               ` Shirley Ma
2004-04-05 21:42                 ` David S. Miller
2004-04-06  0:11                   ` Fix IPv6 MIBs counters in 2.6.5 kernel Shirley Ma
2004-04-09 23:27                     ` David S. Miller
2004-03-31 21:26     ` [PATCH]Add IPv6 MIBs counters in MLD (mcast.c) Shirley Ma
2004-04-03 22:30       ` David S. Miller
2004-05-26 20:10       ` [PATCH]Add new IPv6 MIBs counters support through netlink Shirley Ma
2004-05-26 20:22         ` David S. Miller
2004-05-26 20:42           ` Shirley Ma
2004-05-26 20:44             ` David S. Miller
2004-05-26 23:08               ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-26 23:22                 ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-26 23:22                 ` David S. Miller
2004-05-26 23:34                   ` Shirley Ma
2004-05-26 23:32                 ` Shirley Ma
2004-05-26 23:58                   ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-27  0:01                     ` David S. Miller
2004-06-09 23:00         ` [PATCH] dst allocation problem in ndisc Shirley Ma
2004-06-10  2:12           ` YOSHIFUJI Hideaki / 吉藤英明
2004-06-10 20:05             ` Shirley Ma
2004-06-10 20:46               ` Shirley Ma
2004-06-11  5:08                 ` David S. Miller
2004-06-09 23:29         ` [PATCH] some condition check error in ipsec v6 Shirley Ma
2004-06-10  1:48           ` YOSHIFUJI Hideaki / 吉藤英明
2004-06-11  5:11           ` David S. Miller
2004-05-26 20:19 ` [PATCH] pmtu check conditions error in IPv6 Shirley Ma
2004-05-26 20:24   ` David S. Miller
2004-05-26 20:50   ` [PATCH] IFA_MAX sets wrong in rtnetlink.h Shirley Ma
2004-05-26 20:56     ` David S. Miller
2004-05-28  4:48       ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-28  5:07         ` David S. Miller
2004-05-28  5:12           ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-28  9:25             ` YOSHIFUJI Hideaki / 吉藤英明
2004-05-29 19:36               ` David S. Miller
2004-05-28  9:27             ` YOSHIFUJI Hideaki / 吉藤英明

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).