All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
@ 2003-10-08 18:55 Shirley Ma
  2003-10-08 20:00 ` David S. Miller
  0 siblings, 1 reply; 18+ messages in thread
From: Shirley Ma @ 2003-10-08 18:55 UTC (permalink / raw)
  To: mashirle; +Cc: davem, kuznet, netdev, yoshfuji





I think it's better to define MAX_JIFFIES unsigned long.

#define MAX_JIFFIES (~0UL)

Should I resent the whole patch again?

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

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-08 18:55 [PATCH] Implementation for IPv6 MIB:ipv6AddressTable Shirley Ma
@ 2003-10-08 20:00 ` David S. Miller
  2003-10-09  0:06   ` [PATCH] New Patch: " Shirley Ma
  0 siblings, 1 reply; 18+ messages in thread
From: David S. Miller @ 2003-10-08 20:00 UTC (permalink / raw)
  To: Shirley Ma; +Cc: mashirle, kuznet, netdev, yoshfuji

On Wed, 8 Oct 2003 11:55:49 -0700
Shirley Ma <xma@us.ibm.com> wrote:

> I think it's better to define MAX_JIFFIES unsigned long.
> 
> #define MAX_JIFFIES (~0UL)
> 
> Should I resent the whole patch again?

I think this is still incorrect, MAX_JIFFIES is "(~0UL >> 1)"

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-08 20:00 ` David S. Miller
@ 2003-10-09  0:06   ` Shirley Ma
  2003-10-09 20:17     ` Shirley Ma
  2003-10-14 17:38     ` Shirley Ma
  0 siblings, 2 replies; 18+ messages in thread
From: Shirley Ma @ 2003-10-09  0:06 UTC (permalink / raw)
  To: David S. Miller, kuznet; +Cc: netdev, yoshfuji

You are right for MAX_JIFFIES. 
My intention using MAX_JIFFIES was to calculate the right address creation 
timestamp with the INITIAL_JIFFIES set when system boot up. Now I create a 
new patch to avoid using the MAX_JIFFIES. The patch has been tested against 
linux-2.6.0-test6-bk8.

Thanks
Shirley Ma
IBM Linux Technology Center
----------------------------------------------


diff -urN linux-2.6.0-test6/include/linux/rtnetlink.h 
linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h
--- linux-2.6.0-test6/include/linux/rtnetlink.h	2003-09-27 17:50:40.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h	2003-10-08 
00:15:38.000000000 -0700
@@ -352,8 +352,10 @@
 
 struct ifa_cacheinfo
 {
-	__s32	ifa_prefered;
-	__s32	ifa_valid;
+	__u32	ifa_prefered;
+	__u32	ifa_valid;
+	__u32	cstamp; /* created timestamp, hundredths of seconds */
+	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 };
 
 
diff -urN linux-2.6.0-test6/include/net/if_inet6.h 
linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h
--- linux-2.6.0-test6/include/net/if_inet6.h	2003-09-27 17:51:07.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h	2003-10-08 
00:15:38.000000000 -0700
@@ -34,7 +34,8 @@
 	
 	__u32			valid_lft;
 	__u32			prefered_lft;
-	unsigned long		tstamp;
+	unsigned long		cstamp;	/* created timestamp */
+	unsigned long		tstamp; /* updated timestamp */
 	atomic_t		refcnt;
 	spinlock_t		lock;
 
@@ -111,6 +112,8 @@
 	atomic_t		mca_refcnt;
 	spinlock_t		mca_lock;
 	unsigned char		mca_crcount;
+	unsigned long		mca_cstamp;
+	unsigned long		mca_tstamp;
 };
 
 /* Anycast stuff */
@@ -130,6 +133,8 @@
 	int			aca_users;
 	atomic_t		aca_refcnt;
 	spinlock_t		aca_lock;
+	unsigned long		aca_cstamp;
+	unsigned long		aca_tstamp;
 };
 
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
diff -urN linux-2.6.0-test6/net/ipv6/addrconf.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c
--- linux-2.6.0-test6/net/ipv6/addrconf.c	2003-09-27 17:51:02.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c	2003-10-08 
16:32:05.000000000 -0700
@@ -92,6 +92,9 @@
 #define ADBG(x)
 #endif
 
+#define	INFINITY_LIFE_TIME	0xFFFFFFFF
+#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct 
ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -505,6 +508,7 @@
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
 	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->cstamp = ifa->tstamp = jiffies;
 
 	read_lock(&addrconf_lock);
 	if (idev->dead) {
@@ -707,6 +711,7 @@
 	ift->ifpub = ifp;
 	ift->valid_lft = tmp_valid_lft;
 	ift->prefered_lft = tmp_prefered_lft;
+	ift->cstamp = ifp->cstamp;
 	ift->tstamp = ifp->tstamp;
 	spin_unlock_bh(&ift->lock);
 	addrconf_dad_start(ift, 0);
@@ -1412,6 +1417,7 @@
 			}
 
 			update_lft = create = 1;
+			ifp->cstamp = jiffies;
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
 		}
 
@@ -2447,14 +2453,85 @@
 	if (!(ifa->flags&IFA_F_PERMANENT)) {
 		ci.ifa_prefered = ifa->prefered_lft;
 		ci.ifa_valid = ifa->valid_lft;
-		if (ci.ifa_prefered != 0xFFFFFFFF) {
+		if (ci.ifa_prefered != INFINITY_LIFE_TIME) {
 			long tval = (jiffies - ifa->tstamp)/HZ;
 			ci.ifa_prefered -= tval;
-			if (ci.ifa_valid != 0xFFFFFFFF)
+			if (ci.ifa_valid != INFINITY_LIFE_TIME)
 				ci.ifa_valid -= tval;
 		}
-		RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	} else {
+		ci.ifa_prefered = INFINITY_LIFE_TIME;
+		ci.ifa_valid = INFINITY_LIFE_TIME;
 	}
+	ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100);
+	ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100);
+	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_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_ADDRESS, 16, &ifmca->mca_addr);
+	ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ * 
100);
+	ci.tstamp = (__u32)(TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) / HZ * 
100);
+	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_ADDRESS, 16, &ifaca->aca_addr);
+	ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ * 
100);
+	ci.tstamp = (__u32)(TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) / HZ * 
100);
+	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;
 
@@ -2468,33 +2545,79 @@
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
- 	struct inet6_ifaddr *ifa;
-
+	int err = 1;
+	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];
-
-	for (idx=0; idx < IN6_ADDR_HSIZE; idx++) {
+	read_lock(&dev_base_lock);
+	
+	for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
 		if (idx > s_idx)
 			s_ip_idx = 0;
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifa=inet6_addr_lst[idx], ip_idx = 0; ifa;
-		     ifa = ifa->lst_next, ip_idx++) {
+		ip_idx = 0;
+		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 (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
-				read_unlock_bh(&addrconf_hash_lock);
+			if ((err = inet6_fill_ifaddr(skb, ifa, 
+			    NETLINK_CB(cb->skb).pid, 
+			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
 				goto done;
-			}
 		}
-		read_unlock_bh(&addrconf_hash_lock);
+		/* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+		for (ifa = idev->tempaddr_list; ifa; 
+		     ifa = ifua->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
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 done:
+	if (err <= 0) {
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+	}
+	read_unlock(&dev_base_lock);
 	cb->args[0] = idx;
 	cb->args[1] = ip_idx;
-
 	return skb->len;
 }
 
diff -urN linux-2.6.0-test6/net/ipv6/anycast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c
--- linux-2.6.0-test6/net/ipv6/anycast.c	2003-09-27 17:50:06.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c	2003-10-08 
00:15:38.000000000 -0700
@@ -343,6 +343,8 @@
 	ipv6_addr_copy(&aca->aca_addr, addr);
 	aca->aca_idev = idev;
 	aca->aca_users = 1;
+	/* aca_tstamp should be updated upon changes */
+	aca->aca_cstamp = aca->aca_tstamp = jiffies;
 	atomic_set(&aca->aca_refcnt, 2);
 	aca->aca_lock = SPIN_LOCK_UNLOCKED;
 
diff -urN linux-2.6.0-test6/net/ipv6/mcast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c
--- linux-2.6.0-test6/net/ipv6/mcast.c	2003-09-27 17:50:53.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c	2003-10-08 00:15:38.000000000 
-0700
@@ -830,6 +830,8 @@
 	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
+	/* mca_stamp should be updated upon changes */
+	mc->mca_cstamp = mc->mca_tstamp = jiffies;
 	atomic_set(&mc->mca_refcnt, 2);
 	mc->mca_lock = SPIN_LOCK_UNLOCKED;
 

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-09  0:06   ` [PATCH] New Patch: " Shirley Ma
@ 2003-10-09 20:17     ` Shirley Ma
  2003-10-10  7:04       ` David S. Miller
  2003-10-14 17:38     ` Shirley Ma
  1 sibling, 1 reply; 18+ messages in thread
From: Shirley Ma @ 2003-10-09 20:17 UTC (permalink / raw)
  To: David S. Miller, kuznet; +Cc: netdev, yoshfuji

Hi, David,

There is possible loss of precision in the new patch for the timestamp. I have 
two solutions. 

Which one do you think is better.

This one is too much math.

ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100
		  + TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100
		  + TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);

This one might overflow.

ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) *100 ) / HZ;
ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) * 100) / HZ;

Thanks
Shirley Ma
IBM Linux Technology Center
--------------------------------------------

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-09 20:17     ` Shirley Ma
@ 2003-10-10  7:04       ` David S. Miller
  0 siblings, 0 replies; 18+ messages in thread
From: David S. Miller @ 2003-10-10  7:04 UTC (permalink / raw)
  To: Shirley Ma; +Cc: kuznet, netdev, yoshfuji

On Thu, 9 Oct 2003 13:17:35 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> Which one do you think is better.
> 
> This one is too much math.
> 
> ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100
> 		  + TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
> ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100
> 		  + TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);

Why are you using jiffies for timestamps?  I guess these values
are measured "since bootup" or something like that?

Anyways, I prefer the "too much math" because 1) it isn't a lot of
math, most of these things are constants which make the expressions
easy to compute 2) it's only done when someone asks for the information.

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-09  0:06   ` [PATCH] New Patch: " Shirley Ma
  2003-10-09 20:17     ` Shirley Ma
@ 2003-10-14 17:38     ` Shirley Ma
  2003-10-14 22:25       ` David S. Miller
  2003-10-16  5:37       ` David S. Miller
  1 sibling, 2 replies; 18+ messages in thread
From: Shirley Ma @ 2003-10-14 17:38 UTC (permalink / raw)
  To: David S. Miller, kuznet; +Cc: netdev, yoshfuji

This is the modified new patch for IPv6 MIB: ipv6AddressTable.
This patch has been tested against linux-2.6.0-test6-bk8 kernel.

Thanks
Shirley Ma
IBM Linux Technology Center
=======================

diff -urN linux-2.6.0-test6/include/linux/rtnetlink.h 
linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h
--- linux-2.6.0-test6/include/linux/rtnetlink.h	2003-09-27 17:50:40.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h	2003-10-08 
00:15:38.000000000 -0700
@@ -352,8 +352,10 @@
 
 struct ifa_cacheinfo
 {
-	__s32	ifa_prefered;
-	__s32	ifa_valid;
+	__u32	ifa_prefered;
+	__u32	ifa_valid;
+	__u32	cstamp; /* created timestamp, hundredths of seconds */
+	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 };
 
 
diff -urN linux-2.6.0-test6/include/net/if_inet6.h 
linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h
--- linux-2.6.0-test6/include/net/if_inet6.h	2003-09-27 17:51:07.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h	2003-10-08 
00:15:38.000000000 -0700
@@ -34,7 +34,8 @@
 	
 	__u32			valid_lft;
 	__u32			prefered_lft;
-	unsigned long		tstamp;
+	unsigned long		cstamp;	/* created timestamp */
+	unsigned long		tstamp; /* updated timestamp */
 	atomic_t		refcnt;
 	spinlock_t		lock;
 
@@ -111,6 +112,8 @@
 	atomic_t		mca_refcnt;
 	spinlock_t		mca_lock;
 	unsigned char		mca_crcount;
+	unsigned long		mca_cstamp;
+	unsigned long		mca_tstamp;
 };
 
 /* Anycast stuff */
@@ -130,6 +133,8 @@
 	int			aca_users;
 	atomic_t		aca_refcnt;
 	spinlock_t		aca_lock;
+	unsigned long		aca_cstamp;
+	unsigned long		aca_tstamp;
 };
 
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
diff -urN linux-2.6.0-test6/net/ipv6/addrconf.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c
--- linux-2.6.0-test6/net/ipv6/addrconf.c	2003-09-27 17:51:02.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c	2003-10-09 
12:28:54.000000000 -0700
@@ -92,6 +92,9 @@
 #define ADBG(x)
 #endif
 
+#define	INFINITY_LIFE_TIME	0xFFFFFFFF
+#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct 
ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -505,6 +508,7 @@
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
 	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->cstamp = ifa->tstamp = jiffies;
 
 	read_lock(&addrconf_lock);
 	if (idev->dead) {
@@ -707,6 +711,7 @@
 	ift->ifpub = ifp;
 	ift->valid_lft = tmp_valid_lft;
 	ift->prefered_lft = tmp_prefered_lft;
+	ift->cstamp = ifp->cstamp;
 	ift->tstamp = ifp->tstamp;
 	spin_unlock_bh(&ift->lock);
 	addrconf_dad_start(ift, 0);
@@ -1412,6 +1417,7 @@
 			}
 
 			update_lft = create = 1;
+			ifp->cstamp = jiffies;
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
 		}
 
@@ -2447,14 +2453,95 @@
 	if (!(ifa->flags&IFA_F_PERMANENT)) {
 		ci.ifa_prefered = ifa->prefered_lft;
 		ci.ifa_valid = ifa->valid_lft;
-		if (ci.ifa_prefered != 0xFFFFFFFF) {
+		if (ci.ifa_prefered != INFINITY_LIFE_TIME) {
 			long tval = (jiffies - ifa->tstamp)/HZ;
 			ci.ifa_prefered -= tval;
-			if (ci.ifa_valid != 0xFFFFFFFF)
+			if (ci.ifa_valid != INFINITY_LIFE_TIME)
 				ci.ifa_valid -= tval;
 		}
-		RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	} else {
+		ci.ifa_prefered = INFINITY_LIFE_TIME;
+		ci.ifa_valid = INFINITY_LIFE_TIME;
 	}
+	ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100
+		    + TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+	ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100
+		    + TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+	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_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_ADDRESS, 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_ADDRESS, 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;
 
@@ -2468,33 +2555,79 @@
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
- 	struct inet6_ifaddr *ifa;
-
+	int err = 1;
+	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];
-
-	for (idx=0; idx < IN6_ADDR_HSIZE; idx++) {
+	read_lock(&dev_base_lock);
+	
+	for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
 		if (idx > s_idx)
 			s_ip_idx = 0;
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifa=inet6_addr_lst[idx], ip_idx = 0; ifa;
-		     ifa = ifa->lst_next, ip_idx++) {
+		ip_idx = 0;
+		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 (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
-				read_unlock_bh(&addrconf_hash_lock);
+			if ((err = inet6_fill_ifaddr(skb, ifa, 
+			    NETLINK_CB(cb->skb).pid, 
+			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
 				goto done;
-			}
 		}
-		read_unlock_bh(&addrconf_hash_lock);
+		/* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+		for (ifa = idev->tempaddr_list; ifa; 
+		     ifa = ifua->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
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 done:
+	if (err <= 0) {
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+	}
+	read_unlock(&dev_base_lock);
 	cb->args[0] = idx;
 	cb->args[1] = ip_idx;
-
 	return skb->len;
 }
 
diff -urN linux-2.6.0-test6/net/ipv6/anycast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c
--- linux-2.6.0-test6/net/ipv6/anycast.c	2003-09-27 17:50:06.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c	2003-10-08 
00:15:38.000000000 -0700
@@ -343,6 +343,8 @@
 	ipv6_addr_copy(&aca->aca_addr, addr);
 	aca->aca_idev = idev;
 	aca->aca_users = 1;
+	/* aca_tstamp should be updated upon changes */
+	aca->aca_cstamp = aca->aca_tstamp = jiffies;
 	atomic_set(&aca->aca_refcnt, 2);
 	aca->aca_lock = SPIN_LOCK_UNLOCKED;
 
diff -urN linux-2.6.0-test6/net/ipv6/mcast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c
--- linux-2.6.0-test6/net/ipv6/mcast.c	2003-09-27 17:50:53.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c	2003-10-08 00:15:38.000000000 
-0700
@@ -830,6 +830,8 @@
 	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
+	/* mca_stamp should be updated upon changes */
+	mc->mca_cstamp = mc->mca_tstamp = jiffies;
 	atomic_set(&mc->mca_refcnt, 2);
 	mc->mca_lock = SPIN_LOCK_UNLOCKED;
 

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-14 17:38     ` Shirley Ma
@ 2003-10-14 22:25       ` David S. Miller
  2003-10-16  5:37       ` David S. Miller
  1 sibling, 0 replies; 18+ messages in thread
From: David S. Miller @ 2003-10-14 22:25 UTC (permalink / raw)
  To: Shirley Ma; +Cc: kuznet, netdev, yoshfuji

On Tue, 14 Oct 2003 10:38:04 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> This is the modified new patch for IPv6 MIB: ipv6AddressTable.
> This patch has been tested against linux-2.6.0-test6-bk8 kernel.

This patch looks great, I think I'll add it to my 2.6.x tree
tomorrow.

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-14 17:38     ` Shirley Ma
  2003-10-14 22:25       ` David S. Miller
@ 2003-10-16  5:37       ` David S. Miller
  2003-10-16 16:56         ` Shirley Ma
  1 sibling, 1 reply; 18+ messages in thread
From: David S. Miller @ 2003-10-16  5:37 UTC (permalink / raw)
  To: Shirley Ma; +Cc: kuznet, netdev, yoshfuji

On Tue, 14 Oct 2003 10:38:04 -0700
Shirley Ma <mashirle@us.ibm.com> wrote:

> This is the modified new patch for IPv6 MIB: ipv6AddressTable.
> This patch has been tested against linux-2.6.0-test6-bk8 kernel.

Please configure KMAIL so that it doesn't corrupt the patches
you send by auto-wrapping newlines.

I can't use the patch you've posted because of this.

Thanks.

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-16  5:37       ` David S. Miller
@ 2003-10-16 16:56         ` Shirley Ma
  2003-10-16 23:29           ` David S. Miller
  0 siblings, 1 reply; 18+ messages in thread
From: Shirley Ma @ 2003-10-16 16:56 UTC (permalink / raw)
  To: David S. Miller; +Cc: kuznet, netdev, yoshfuji

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

> I can't use the patch you've posted because of this.

I am very sorry for wasting your time. In case of other mistake, I am giving 
you an attachment this time. I will fix my KMAIL later.

Thanks
Shirley Ma
IBM Linux Technology Center


[-- Attachment #2: ipv6mib4-2.6.0-test6-bk8.patch --]
[-- Type: text/x-diff, Size: 9511 bytes --]

diff -urN linux-2.6.0-test6/include/linux/rtnetlink.h linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h
--- linux-2.6.0-test6/include/linux/rtnetlink.h	2003-09-27 17:50:40.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h	2003-10-08 00:15:38.000000000 -0700
@@ -352,8 +352,10 @@
 
 struct ifa_cacheinfo
 {
-	__s32	ifa_prefered;
-	__s32	ifa_valid;
+	__u32	ifa_prefered;
+	__u32	ifa_valid;
+	__u32	cstamp; /* created timestamp, hundredths of seconds */
+	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 };
 
 
diff -urN linux-2.6.0-test6/include/net/if_inet6.h linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h
--- linux-2.6.0-test6/include/net/if_inet6.h	2003-09-27 17:51:07.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h	2003-10-08 00:15:38.000000000 -0700
@@ -34,7 +34,8 @@
 	
 	__u32			valid_lft;
 	__u32			prefered_lft;
-	unsigned long		tstamp;
+	unsigned long		cstamp;	/* created timestamp */
+	unsigned long		tstamp; /* updated timestamp */
 	atomic_t		refcnt;
 	spinlock_t		lock;
 
@@ -111,6 +112,8 @@
 	atomic_t		mca_refcnt;
 	spinlock_t		mca_lock;
 	unsigned char		mca_crcount;
+	unsigned long		mca_cstamp;
+	unsigned long		mca_tstamp;
 };
 
 /* Anycast stuff */
@@ -130,6 +133,8 @@
 	int			aca_users;
 	atomic_t		aca_refcnt;
 	spinlock_t		aca_lock;
+	unsigned long		aca_cstamp;
+	unsigned long		aca_tstamp;
 };
 
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
diff -urN linux-2.6.0-test6/net/ipv6/addrconf.c linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c
--- linux-2.6.0-test6/net/ipv6/addrconf.c	2003-09-27 17:51:02.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c	2003-10-09 12:28:54.000000000 -0700
@@ -92,6 +92,9 @@
 #define ADBG(x)
 #endif
 
+#define	INFINITY_LIFE_TIME	0xFFFFFFFF
+#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -505,6 +508,7 @@
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
 	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->cstamp = ifa->tstamp = jiffies;
 
 	read_lock(&addrconf_lock);
 	if (idev->dead) {
@@ -707,6 +711,7 @@
 	ift->ifpub = ifp;
 	ift->valid_lft = tmp_valid_lft;
 	ift->prefered_lft = tmp_prefered_lft;
+	ift->cstamp = ifp->cstamp;
 	ift->tstamp = ifp->tstamp;
 	spin_unlock_bh(&ift->lock);
 	addrconf_dad_start(ift, 0);
@@ -1412,6 +1417,7 @@
 			}
 
 			update_lft = create = 1;
+			ifp->cstamp = jiffies;
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
 		}
 
@@ -2447,14 +2453,95 @@
 	if (!(ifa->flags&IFA_F_PERMANENT)) {
 		ci.ifa_prefered = ifa->prefered_lft;
 		ci.ifa_valid = ifa->valid_lft;
-		if (ci.ifa_prefered != 0xFFFFFFFF) {
+		if (ci.ifa_prefered != INFINITY_LIFE_TIME) {
 			long tval = (jiffies - ifa->tstamp)/HZ;
 			ci.ifa_prefered -= tval;
-			if (ci.ifa_valid != 0xFFFFFFFF)
+			if (ci.ifa_valid != INFINITY_LIFE_TIME)
 				ci.ifa_valid -= tval;
 		}
-		RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	} else {
+		ci.ifa_prefered = INFINITY_LIFE_TIME;
+		ci.ifa_valid = INFINITY_LIFE_TIME;
 	}
+	ci.cstamp = (__u32)(TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) / HZ * 100
+		    + TIME_DELTA(ifa->cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+	ci.tstamp = (__u32)(TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) / HZ * 100
+		    + TIME_DELTA(ifa->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+	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_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_ADDRESS, 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_ADDRESS, 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;
 
@@ -2468,33 +2555,79 @@
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
- 	struct inet6_ifaddr *ifa;
-
+	int err = 1;
+	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];
-
-	for (idx=0; idx < IN6_ADDR_HSIZE; idx++) {
+	read_lock(&dev_base_lock);
+	
+	for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
 		if (idx > s_idx)
 			s_ip_idx = 0;
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifa=inet6_addr_lst[idx], ip_idx = 0; ifa;
-		     ifa = ifa->lst_next, ip_idx++) {
+		ip_idx = 0;
+		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 (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
-				read_unlock_bh(&addrconf_hash_lock);
+			if ((err = inet6_fill_ifaddr(skb, ifa, 
+			    NETLINK_CB(cb->skb).pid, 
+			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
 				goto done;
-			}
 		}
-		read_unlock_bh(&addrconf_hash_lock);
+		/* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+		for (ifa = idev->tempaddr_list; ifa; 
+		     ifa = ifua->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
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 done:
+	if (err <= 0) {
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+	}
+	read_unlock(&dev_base_lock);
 	cb->args[0] = idx;
 	cb->args[1] = ip_idx;
-
 	return skb->len;
 }
 
diff -urN linux-2.6.0-test6/net/ipv6/anycast.c linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c
--- linux-2.6.0-test6/net/ipv6/anycast.c	2003-09-27 17:50:06.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c	2003-10-08 00:15:38.000000000 -0700
@@ -343,6 +343,8 @@
 	ipv6_addr_copy(&aca->aca_addr, addr);
 	aca->aca_idev = idev;
 	aca->aca_users = 1;
+	/* aca_tstamp should be updated upon changes */
+	aca->aca_cstamp = aca->aca_tstamp = jiffies;
 	atomic_set(&aca->aca_refcnt, 2);
 	aca->aca_lock = SPIN_LOCK_UNLOCKED;
 
diff -urN linux-2.6.0-test6/net/ipv6/mcast.c linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c
--- linux-2.6.0-test6/net/ipv6/mcast.c	2003-09-27 17:50:53.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c	2003-10-08 00:15:38.000000000 -0700
@@ -830,6 +830,8 @@
 	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
+	/* mca_stamp should be updated upon changes */
+	mc->mca_cstamp = mc->mca_tstamp = jiffies;
 	atomic_set(&mc->mca_refcnt, 2);
 	mc->mca_lock = SPIN_LOCK_UNLOCKED;
 

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

* Re: [PATCH] New Patch: Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-16 16:56         ` Shirley Ma
@ 2003-10-16 23:29           ` David S. Miller
  0 siblings, 0 replies; 18+ messages in thread
From: David S. Miller @ 2003-10-16 23:29 UTC (permalink / raw)
  To: Shirley Ma; +Cc: kuznet, netdev, yoshfuji

Patch applied, thanks a lot Shirley.

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-07 17:11 [PATCH] " Shirley Ma
@ 2003-10-08 18:23 ` Shirley Ma
  0 siblings, 0 replies; 18+ messages in thread
From: Shirley Ma @ 2003-10-08 18:23 UTC (permalink / raw)
  To: davem, kuznet; +Cc: netdev, yoshfuji

Thanks for all your comments. Here is the new patch. This patch is against 
linux-2.6.0-test6-bk8. This patch has been tested.

Please review this again.

Thanks
Shirley Ma
IBM Linux Technology Center
-------------------------------------------


diff -urN linux-2.6.0-test6/include/linux/rtnetlink.h 
linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h
--- linux-2.6.0-test6/include/linux/rtnetlink.h	2003-09-27 17:50:40.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/linux/rtnetlink.h	2003-10-07 
23:37:29.000000000 -0700
@@ -352,8 +352,10 @@
 
 struct ifa_cacheinfo
 {
-	__s32	ifa_prefered;
-	__s32	ifa_valid;
+	__u32	ifa_prefered;
+	__u32	ifa_valid;
+	__u32	cstamp; /* created timestamp, hundredths of seconds */
+	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 };
 
 
diff -urN linux-2.6.0-test6/include/linux/time.h 
linux-2.6.0-test6-ipv6mib4/include/linux/time.h
--- linux-2.6.0-test6/include/linux/time.h	2003-09-27 17:50:30.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/include/linux/time.h	2003-10-07 
23:37:29.000000000 -0700
@@ -55,6 +55,7 @@
  * at _least_ "jiffies" - so "jiffies+1" had better still
  * be positive.
  */
+#define MAX_JIFFIES (~0)
 #define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
 
 /* Parameters used to convert the timespec values */
diff -urN linux-2.6.0-test6/include/net/if_inet6.h 
linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h
--- linux-2.6.0-test6/include/net/if_inet6.h	2003-09-27 17:51:07.000000000 
-0700
+++ linux-2.6.0-test6-ipv6mib4/include/net/if_inet6.h	2003-10-07 
23:37:29.000000000 -0700
@@ -34,7 +34,8 @@
 	
 	__u32			valid_lft;
 	__u32			prefered_lft;
-	unsigned long		tstamp;
+	unsigned long		cstamp;	/* created timestamp */
+	unsigned long		tstamp; /* updated timestamp */
 	atomic_t		refcnt;
 	spinlock_t		lock;
 
@@ -111,6 +112,8 @@
 	atomic_t		mca_refcnt;
 	spinlock_t		mca_lock;
 	unsigned char		mca_crcount;
+	unsigned long		mca_cstamp;
+	unsigned long		mca_tstamp;
 };
 
 /* Anycast stuff */
@@ -130,6 +133,8 @@
 	int			aca_users;
 	atomic_t		aca_refcnt;
 	spinlock_t		aca_lock;
+	unsigned long		aca_cstamp;
+	unsigned long		aca_tstamp;
 };
 
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
diff -urN linux-2.6.0-test6/net/ipv6/addrconf.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c
--- linux-2.6.0-test6/net/ipv6/addrconf.c	2003-09-27 17:51:02.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/addrconf.c	2003-10-07 
23:58:39.000000000 -0700
@@ -92,6 +92,8 @@
 #define ADBG(x)
 #endif
 
+#define	INFINITY_LIFE_TIME	0xFFFFFFFF
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct 
ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -505,6 +507,7 @@
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
 	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->cstamp = ifa->tstamp = jiffies;
 
 	read_lock(&addrconf_lock);
 	if (idev->dead) {
@@ -707,6 +710,7 @@
 	ift->ifpub = ifp;
 	ift->valid_lft = tmp_valid_lft;
 	ift->prefered_lft = tmp_prefered_lft;
+	ift->cstamp = ifp->cstamp;
 	ift->tstamp = ifp->tstamp;
 	spin_unlock_bh(&ift->lock);
 	addrconf_dad_start(ift, 0);
@@ -1412,6 +1416,7 @@
 			}
 
 			update_lft = create = 1;
+			ifp->cstamp = jiffies;
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
 		}
 
@@ -2447,14 +2452,103 @@
 	if (!(ifa->flags&IFA_F_PERMANENT)) {
 		ci.ifa_prefered = ifa->prefered_lft;
 		ci.ifa_valid = ifa->valid_lft;
-		if (ci.ifa_prefered != 0xFFFFFFFF) {
+		if (ci.ifa_prefered != INFINITY_LIFE_TIME) {
 			long tval = (jiffies - ifa->tstamp)/HZ;
 			ci.ifa_prefered -= tval;
-			if (ci.ifa_valid != 0xFFFFFFFF)
+			if (ci.ifa_valid != INFINITY_LIFE_TIME)
 				ci.ifa_valid -= tval;
 		}
-		RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	} else {
+		ci.ifa_prefered = INFINITY_LIFE_TIME;
+		ci.ifa_valid = INFINITY_LIFE_TIME;
 	}
+	if (ifa->cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifa->cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.cstamp = (ifa->cstamp - INITIAL_JIFFIES) / HZ * 100;
+	if (ifa->tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifa->tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.tstamp = (ifa->tstamp - INITIAL_JIFFIES) / HZ * 100;
+	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_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_ADDRESS, 16, &ifmca->mca_addr);
+	if (ifmca->mca_cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifmca->mca_cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.cstamp = (ifmca->mca_cstamp - INITIAL_JIFFIES) / HZ * 100;
+	if (ifmca->mca_tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifmca->mca_tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.tstamp = (ifmca->mca_tstamp - INITIAL_JIFFIES) / HZ * 100;
+	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_ADDRESS, 16, &ifaca->aca_addr);
+	if (ifaca->aca_cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifaca->aca_cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.cstamp = (ifaca->aca_cstamp - INITIAL_JIFFIES) / HZ * 100;
+	if (ifaca->aca_tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifaca->aca_tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ * 100;
+	else
+		ci.tstamp = (ifaca->aca_tstamp - INITIAL_JIFFIES) / HZ * 100;
+	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;
 
@@ -2468,33 +2562,79 @@
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
- 	struct inet6_ifaddr *ifa;
-
+	int err = 1;
+	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];
-
-	for (idx=0; idx < IN6_ADDR_HSIZE; idx++) {
+	read_lock(&dev_base_lock);
+	
+	for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
 		if (idx > s_idx)
 			s_ip_idx = 0;
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifa=inet6_addr_lst[idx], ip_idx = 0; ifa;
-		     ifa = ifa->lst_next, ip_idx++) {
+		ip_idx = 0;
+		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 (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
-				read_unlock_bh(&addrconf_hash_lock);
+			if ((err = inet6_fill_ifaddr(skb, ifa, 
+			    NETLINK_CB(cb->skb).pid, 
+			    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
 				goto done;
-			}
 		}
-		read_unlock_bh(&addrconf_hash_lock);
+		/* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+		for (ifa = idev->tempaddr_list; ifa; 
+		     ifa = ifua->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
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		/* 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_NEWADDR)) <= 0) 
+				goto done;
+		}
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
 	}
 done:
+	if (err <= 0) {
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+	}	
+	read_unlock(&dev_base_lock);
 	cb->args[0] = idx;
 	cb->args[1] = ip_idx;
-
 	return skb->len;
 }
 
diff -urN linux-2.6.0-test6/net/ipv6/anycast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c
--- linux-2.6.0-test6/net/ipv6/anycast.c	2003-09-27 17:50:06.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/anycast.c	2003-10-07 
23:37:29.000000000 -0700
@@ -343,6 +343,8 @@
 	ipv6_addr_copy(&aca->aca_addr, addr);
 	aca->aca_idev = idev;
 	aca->aca_users = 1;
+	/* aca_tstamp should be updated upon changes */
+	aca->aca_cstamp = aca->aca_tstamp = jiffies;
 	atomic_set(&aca->aca_refcnt, 2);
 	aca->aca_lock = SPIN_LOCK_UNLOCKED;
 
diff -urN linux-2.6.0-test6/net/ipv6/mcast.c 
linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c
--- linux-2.6.0-test6/net/ipv6/mcast.c	2003-09-27 17:50:53.000000000 -0700
+++ linux-2.6.0-test6-ipv6mib4/net/ipv6/mcast.c	2003-10-07 23:37:29.000000000 
-0700
@@ -830,6 +830,8 @@
 	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
+	/* mca_stamp should be updated upon changes */
+	mc->mca_cstamp = mc->mca_tstamp = jiffies;
 	atomic_set(&mc->mca_refcnt, 2);
 	mc->mca_lock = SPIN_LOCK_UNLOCKED;
 

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
@ 2003-10-07 17:11 Shirley Ma
  2003-10-08 18:23 ` Shirley Ma
  0 siblings, 1 reply; 18+ messages in thread
From: Shirley Ma @ 2003-10-07 17:11 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: davem, kuznet, mashirle, netdev, yoshfuji





Yes. Yoshifuji is right.The timeStamp should be

-- hundredths of seconds since an epoch
TimeTicks ::=
    [APPLICATION 3]
        IMPLICIT INTEGER (0..4294967295)

I will modify the patch, and resubmit it against Linux-2.6.0-test6-bk8
again.

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-ipv6.org>@oss.sgi.com on
10/07/2003 04:35:18 AM

Sent by:    netdev-bounce@oss.sgi.com


To:    davem@redhat.com
cc:    kuznet@ms2.inr.ac.ru, mashirle@us.ltcfwd.linux.ibm.com,
       netdev@oss.sgi.com, yoshfuji@linux-ipv6.org
Subject:    Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable


In article <20031007041246.13aa0391.davem@redhat.com> (at Tue, 7 Oct 2003
04:12:46 -0700), "David S. Miller" <davem@redhat.com> says:

> On Tue, 7 Oct 2003 15:16:20 +0400 (MSD)
> kuznet@ms2.inr.ac.ru wrote:
>
> > Actually, this does not depend on our implementation. If people
implement
> > a MIB, required precision of these times is prescribed in the rfc.
> > And this is definitely not jiffies.
>
> Right, Shirley what is it?

The type is TimeTicks (RFC2578) via TimeStamp (RFC2579).
Thus, uint32_t counter in 1/100 sec. unit.

--yoshfuji

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-07 11:12       ` David S. Miller
@ 2003-10-07 11:35         ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 0 replies; 18+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2003-10-07 11:35 UTC (permalink / raw)
  To: davem; +Cc: kuznet, mashirle, netdev, yoshfuji

In article <20031007041246.13aa0391.davem@redhat.com> (at Tue, 7 Oct 2003 04:12:46 -0700), "David S. Miller" <davem@redhat.com> says:

> On Tue, 7 Oct 2003 15:16:20 +0400 (MSD)
> kuznet@ms2.inr.ac.ru wrote:
> 
> > Actually, this does not depend on our implementation. If people implement
> > a MIB, required precision of these times is prescribed in the rfc.
> > And this is definitely not jiffies.
> 
> Right, Shirley what is it?

The type is TimeTicks (RFC2578) via TimeStamp (RFC2579).
Thus, uint32_t counter in 1/100 sec. unit.

--yoshfuji

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-07 10:40   ` David S. Miller
@ 2003-10-07 11:16     ` kuznet
  2003-10-07 11:12       ` David S. Miller
  0 siblings, 1 reply; 18+ messages in thread
From: kuznet @ 2003-10-07 11:16 UTC (permalink / raw)
  To: David S. Miller; +Cc: mashirle, netdev

Hello!

> Do you think it is large enough for timestamp? :)

If it is not, "unsigned long" is not enough either.

Actually, this does not depend on our implementation. If people implement
a MIB, required precision of these times is prescribed in the rfc.
And this is definitely not jiffies.

Alexey

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-07 11:16     ` kuznet
@ 2003-10-07 11:12       ` David S. Miller
  2003-10-07 11:35         ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 18+ messages in thread
From: David S. Miller @ 2003-10-07 11:12 UTC (permalink / raw)
  To: kuznet; +Cc: mashirle, netdev

On Tue, 7 Oct 2003 15:16:20 +0400 (MSD)
kuznet@ms2.inr.ac.ru wrote:

> Actually, this does not depend on our implementation. If people implement
> a MIB, required precision of these times is prescribed in the rfc.
> And this is definitely not jiffies.

Right, Shirley what is it?

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-07 10:38 ` kuznet
@ 2003-10-07 10:40   ` David S. Miller
  2003-10-07 11:16     ` kuznet
  0 siblings, 1 reply; 18+ messages in thread
From: David S. Miller @ 2003-10-07 10:40 UTC (permalink / raw)
  To: kuznet; +Cc: mashirle, netdev

On Tue, 7 Oct 2003 14:38:50 +0400 (MSD)
kuznet@ms2.inr.ac.ru wrote:

> Please, do not use "long" things, they are not allowed in API.
> u32 would be good.

Do you think it is large enough for timestamp? :)

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

* Re: [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
  2003-10-01 23:37 Shirley Ma
@ 2003-10-07 10:38 ` kuznet
  2003-10-07 10:40   ` David S. Miller
  0 siblings, 1 reply; 18+ messages in thread
From: kuznet @ 2003-10-07 10:38 UTC (permalink / raw)
  To: Shirley Ma; +Cc: davem, netdev

Hello!

> +=09unsigned long=09cstamp; /* created time */
> +=09unsigned long=09tstamp; /* updated time */

Please, do not use "long" things, they are not allowed in API.
u32 would be good.

Alexey

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

* [PATCH] Implementation for IPv6 MIB:ipv6AddressTable
@ 2003-10-01 23:37 Shirley Ma
  2003-10-07 10:38 ` kuznet
  0 siblings, 1 reply; 18+ messages in thread
From: Shirley Ma @ 2003-10-01 23:37 UTC (permalink / raw)
  To: davem, kuznet; +Cc: netdev

I've sent my explanation of IPv6 MIBs implementation a couple of weeks back. 
This patch implements the IPv6 MIBs ipv6AddressTable. The implementation is 
based on the new last call draft of IPv6 MIBs, see link blow. It's going to 
be a RFC. 

http://www.ietf.org/internet-drafts/draft-ietf-ipv6-rfc2011-update-04.txt

The patch has been tested against Linux-2.6.0-test5-bk12. I have made sure 
this applies cleanly to Linux 2.6.0-test6-bk3. 

Below is the patch. Please give me your comments.

Thanks
Shirley Ma
IBM Linux Technology Center
=======================

diff -urN linux-2.6.0-test5/include/linux/rtnetlink.h 
linux-2.6.0-test5-ipv6mib4/include/linux/rtnetlink.h
--- linux-2.6.0-test5/include/linux/rtnetlink.h	2003-09-25 17:17:02.000000000 
-0700
+++ linux-2.6.0-test5-ipv6mib4/include/linux/rtnetlink.h	2003-10-01 
11:00:03.000000000 -0700
@@ -352,8 +352,10 @@
 
 struct ifa_cacheinfo
 {
-	__s32	ifa_prefered;
-	__s32	ifa_valid;
+	__u32	ifa_prefered;
+	__u32	ifa_valid;
+	unsigned long	cstamp; /* created time */
+	unsigned long	tstamp; /* updated time */
 };
 
 
diff -urN linux-2.6.0-test5/include/linux/time.h 
linux-2.6.0-test5-ipv6mib4/include/linux/time.h
--- linux-2.6.0-test5/include/linux/time.h	2003-09-08 12:50:08.000000000 -0700
+++ linux-2.6.0-test5-ipv6mib4/include/linux/time.h	2003-10-01 
11:40:42.000000000 -0700
@@ -55,6 +55,7 @@
  * at _least_ "jiffies" - so "jiffies+1" had better still
  * be positive.
  */
+#define MAX_JIFFIES (~0)
 #define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
 
 /* Parameters used to convert the timespec values */
diff -urN linux-2.6.0-test5/include/net/if_inet6.h 
linux-2.6.0-test5-ipv6mib4/include/net/if_inet6.h
--- linux-2.6.0-test5/include/net/if_inet6.h	2003-09-25 17:17:02.000000000 
-0700
+++ linux-2.6.0-test5-ipv6mib4/include/net/if_inet6.h	2003-10-01 
11:23:27.000000000 -0700
@@ -34,7 +34,8 @@
 	
 	__u32			valid_lft;
 	__u32			prefered_lft;
-	unsigned long		tstamp;
+	unsigned long		cstamp;	/* created timestamp */
+	unsigned long		tstamp; /* updated timestamp */
 	atomic_t		refcnt;
 	spinlock_t		lock;
 
@@ -111,6 +112,8 @@
 	atomic_t		mca_refcnt;
 	spinlock_t		mca_lock;
 	unsigned char		mca_crcount;
+	unsigned long		mca_cstamp;
+	unsigned long		mca_tstamp;
 };
 
 /* Anycast stuff */
@@ -130,6 +133,8 @@
 	int			aca_users;
 	atomic_t		aca_refcnt;
 	spinlock_t		aca_lock;
+	unsigned long		aca_cstamp;
+	unsigned long		aca_tstamp;
 };
 
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
diff -urN linux-2.6.0-test5/net/ipv6/addrconf.c 
linux-2.6.0-test5-ipv6mib4/net/ipv6/addrconf.c
--- linux-2.6.0-test5/net/ipv6/addrconf.c	2003-09-25 17:17:03.000000000 -0700
+++ linux-2.6.0-test5-ipv6mib4/net/ipv6/addrconf.c	2003-10-01 
11:28:41.000000000 -0700
@@ -92,6 +92,8 @@
 #define ADBG(x)
 #endif
 
+#define	INFINITY_LIFE_TIME	0xFFFFFFFF
+
 #ifdef CONFIG_SYSCTL
 static void addrconf_sysctl_register(struct inet6_dev *idev, struct 
ipv6_devconf *p);
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
@@ -505,6 +507,7 @@
 	ifa->scope = scope;
 	ifa->prefix_len = pfxlen;
 	ifa->flags = flags | IFA_F_TENTATIVE;
+	ifa->cstamp = ifa->tstamp = jiffies;
 
 	read_lock(&addrconf_lock);
 	if (idev->dead) {
@@ -707,6 +710,7 @@
 	ift->ifpub = ifp;
 	ift->valid_lft = tmp_valid_lft;
 	ift->prefered_lft = tmp_prefered_lft;
+	ift->cstamp = ifp->cstamp;
 	ift->tstamp = ifp->tstamp;
 	spin_unlock_bh(&ift->lock);
 	addrconf_dad_start(ift, 0);
@@ -1412,6 +1416,7 @@
 			}
 
 			update_lft = create = 1;
+			ifp->cstamp = jiffies;
 			addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT);
 		}
 
@@ -2447,14 +2452,103 @@
 	if (!(ifa->flags&IFA_F_PERMANENT)) {
 		ci.ifa_prefered = ifa->prefered_lft;
 		ci.ifa_valid = ifa->valid_lft;
-		if (ci.ifa_prefered != 0xFFFFFFFF) {
+		if (ci.ifa_prefered != INFINITY_LIFE_TIME) {
 			long tval = (jiffies - ifa->tstamp)/HZ;
 			ci.ifa_prefered -= tval;
-			if (ci.ifa_valid != 0xFFFFFFFF)
+			if (ci.ifa_valid != INFINITY_LIFE_TIME)
 				ci.ifa_valid -= tval;
 		}
-		RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci);
+	} else {
+		ci.ifa_prefered = INFINITY_LIFE_TIME;
+		ci.ifa_valid = INFINITY_LIFE_TIME;
 	}
+	if (ifa->cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifa->cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.cstamp = (ifa->cstamp - INITIAL_JIFFIES) / HZ;
+	if (ifa->tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifa->tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.tstamp = (ifa->tstamp - INITIAL_JIFFIES) / HZ;
+	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_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_ADDRESS, 16, &ifmca->mca_addr);
+	if (ifmca->mca_cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifmca->mca_cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.cstamp = (ifmca->mca_cstamp - INITIAL_JIFFIES) / HZ;
+	if (ifmca->mca_tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifmca->mca_tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.tstamp = (ifmca->mca_tstamp - INITIAL_JIFFIES) / 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_ADDRESS, 16, &ifaca->aca_addr);
+	if (ifaca->aca_cstamp < INITIAL_JIFFIES)
+		ci.cstamp = (ifaca->aca_cstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.cstamp = (ifaca->aca_cstamp - INITIAL_JIFFIES) / HZ;
+	if (ifaca->aca_tstamp < INITIAL_JIFFIES)
+		ci.tstamp = (ifaca->aca_tstamp + MAX_JIFFIES - INITIAL_JIFFIES) / HZ;
+	else
+		ci.tstamp = (ifaca->aca_tstamp - INITIAL_JIFFIES) / 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;
 
@@ -2468,33 +2562,83 @@
 {
 	int idx, ip_idx;
 	int s_idx, s_ip_idx;
- 	struct inet6_ifaddr *ifa;
-
+	struct net_device *dev;
+	struct inet6_dev *idev;
+	struct inet6_ifaddr *ifa;
+	struct ifmcaddr6 *ifmca;
+	struct ifacaddr6 *ifaca;
+	
 	s_idx = cb->args[0];
 	s_ip_idx = ip_idx = cb->args[1];
-
-	for (idx=0; idx < IN6_ADDR_HSIZE; idx++) {
+	read_lock(&dev_base_lock);
+	
+	for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
 		if (idx > s_idx)
 			s_ip_idx = 0;
-		read_lock_bh(&addrconf_hash_lock);
-		for (ifa=inet6_addr_lst[idx], ip_idx = 0; ifa;
-		     ifa = ifa->lst_next, ip_idx++) {
+		if ((idev = in6_dev_get(dev)) == NULL)
+			continue;
+		read_lock_bh(&idev->lock);
+		/* unicast address */
+		for (ifa = idev->addr_list, ip_idx = 0; ifa;
+		     ifa = ifa->if_next, ip_idx++) {
+			if (ip_idx < s_ip_idx)
+				continue;
+			if (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
+					cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
+				read_unlock(&addrconf_lock);
+				in6_dev_put(idev);
+				goto done;
+			}
+		}
+		/* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+		for (ifa = idev->tempaddr_list; ifa; 
+		     ifa = ifua->tmp_next, ip_idx++) {
 			if (ip_idx < s_ip_idx)
 				continue;
 			if (inet6_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
-					      cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
-				read_unlock_bh(&addrconf_hash_lock);
+					cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
+				read_unlock(&addrconf_lock);
+				in6_dev_put(idev);
+				goto done;
+			}	
+		}
+#endif
+		/* multicast address */
+		for (ifmca = idev->mc_list; ifmca; 
+		     ifmca = ifmca->next, ip_idx++) {
+			if (ip_idx < s_ip_idx)
+				continue;
+			if (inet6_fill_ifmcaddr(skb, ifmca, 
+					NETLINK_CB(cb->skb).pid,
+					cb->nlh->nlmsg_seq, RTM_NEWADDR) <= 0) {
+				read_unlock(&addrconf_lock);
+				in6_dev_put(idev);
+				goto done;
+			}
+		}
+		/* anycast address */
+		for (ifaca = idev->ac_list; ifaca;
+		     ifaca = ifaca->aca_next, ip_idx++) {
+			if (ip_idx < s_ip_idx)
+				continue;
+			if (inet6_fill_ifacaddr(skb, ifaca, 
+					NETLINK_CB(cb->skb).pid, 
+					cb->nlh->nlmsg_seq, RTM_NEWADDR) <=0) {
+				read_unlock(&addrconf_lock);
+				in6_dev_put(idev);
 				goto done;
 			}
 		}
-		read_unlock_bh(&addrconf_hash_lock);
+		read_unlock(&addrconf_lock);
+		in6_dev_put(idev);
 	}
 done:
+	read_unlock(&dev_base_lock);
 	cb->args[0] = idx;
 	cb->args[1] = ip_idx;
-
 	return skb->len;
 }
 
diff -urN linux-2.6.0-test5/net/ipv6/anycast.c 
linux-2.6.0-test5-ipv6mib4/net/ipv6/anycast.c
--- linux-2.6.0-test5/net/ipv6/anycast.c	2003-09-25 17:17:03.000000000 -0700
+++ linux-2.6.0-test5-ipv6mib4/net/ipv6/anycast.c	2003-10-01 
11:23:04.000000000 -0700
@@ -343,6 +343,8 @@
 	ipv6_addr_copy(&aca->aca_addr, addr);
 	aca->aca_idev = idev;
 	aca->aca_users = 1;
+	/* aca_tstamp should be updated later, once it's updated */
+	aca->aca_cstamp = aca->aca_tstamp = jiffies;
 	atomic_set(&aca->aca_refcnt, 2);
 	aca->aca_lock = SPIN_LOCK_UNLOCKED;
 
diff -urN linux-2.6.0-test5/net/ipv6/mcast.c 
linux-2.6.0-test5-ipv6mib4/net/ipv6/mcast.c
--- linux-2.6.0-test5/net/ipv6/mcast.c	2003-09-25 17:17:03.000000000 -0700
+++ linux-2.6.0-test5-ipv6mib4/net/ipv6/mcast.c	2003-09-30 18:40:29.000000000 
-0700
@@ -830,6 +830,8 @@
 	ipv6_addr_copy(&mc->mca_addr, addr);
 	mc->idev = idev;
 	mc->mca_users = 1;
+	/* mca_stamp should be updated later, once it's updated */
+	mc->mca_cstamp = mc->mca_tstamp = jiffies;
 	atomic_set(&mc->mca_refcnt, 2);
 	mc->mca_lock = SPIN_LOCK_UNLOCKED;
 

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

end of thread, other threads:[~2003-10-16 23:29 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-08 18:55 [PATCH] Implementation for IPv6 MIB:ipv6AddressTable Shirley Ma
2003-10-08 20:00 ` David S. Miller
2003-10-09  0:06   ` [PATCH] New Patch: " Shirley Ma
2003-10-09 20:17     ` Shirley Ma
2003-10-10  7:04       ` David S. Miller
2003-10-14 17:38     ` Shirley Ma
2003-10-14 22:25       ` David S. Miller
2003-10-16  5:37       ` David S. Miller
2003-10-16 16:56         ` Shirley Ma
2003-10-16 23:29           ` David S. Miller
  -- strict thread matches above, loose matches on Subject: below --
2003-10-07 17:11 [PATCH] " Shirley Ma
2003-10-08 18:23 ` Shirley Ma
2003-10-01 23:37 Shirley Ma
2003-10-07 10:38 ` kuznet
2003-10-07 10:40   ` David S. Miller
2003-10-07 11:16     ` kuznet
2003-10-07 11:12       ` David S. Miller
2003-10-07 11:35         ` YOSHIFUJI Hideaki / 吉藤英明

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.