Skip to contentSkip to conversation

ipv6: making UDP mibs per/namespace

PATCH In review Denis V. Lunev 4 participants 13 messages Oct 2, 2008 – Oct 7, 2008 1 message not in the archive

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

cover ipv6: making UDP mibs per/namespace

This patch series provides a basic infrastructure to make snmp6 statistics per/namespace and actually virtualize udp6/udplite6 mibs.

This set follows approach used by Pavel Emelyanov in IPv4 code. IP6/icmp6 statistics is also ready and will follow.

Regards,
Den

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

PATCH 1/9 netns: move /proc/net/dev_snmp6 to struct net

---
 include/net/netns/mib.h |    4 ++++
 net/ipv6/proc.c         |   20 +++++++++++---------
 2 files changed, 15 insertions(+), 9 deletions(-)
include/net/netns/mib.h +4 -0
index 4491476..ffcef5d 100644
@@ -11,6 +11,10 @@ struct netns_mib {
 	DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics);
 	DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics);
 	DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics);
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct proc_dir_entry *proc_net_devsnmp6;
+#endif
 };
 
 #endif
net/ipv6/proc.c +11 -9
index 0179b66..16ebf85 100644
@@ -29,8 +29,6 @@
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 
-static struct proc_dir_entry *proc_net_devsnmp6;
-
 static int sockstat6_seq_show(struct seq_file *seq, void *v)
 {
 	struct net *net = seq->private;
@@ -210,18 +208,20 @@ static const struct file_operations snmp6_seq_fops = {
 int snmp6_register_dev(struct inet6_dev *idev)
 {
 	struct proc_dir_entry *p;
+	struct net *net;
 
 	if (!idev || !idev->dev)
 		return -EINVAL;
 
-	if (!net_eq(dev_net(idev->dev), &init_net))
+	net = dev_net(idev->dev);
+	if (!net_eq(net, &init_net))
 		return 0;
 
-	if (!proc_net_devsnmp6)
+	if (!net->mib.proc_net_devsnmp6)
 		return -ENOENT;
 
 	p = proc_create_data(idev->dev->name, S_IRUGO,
-			     proc_net_devsnmp6, &snmp6_seq_fops, idev);
+			     net->mib.proc_net_devsnmp6, &snmp6_seq_fops, idev);
 	if (!p)
 		return -ENOMEM;
 
@@ -231,12 +231,13 @@ int snmp6_register_dev(struct inet6_dev *idev)
 
 int snmp6_unregister_dev(struct inet6_dev *idev)
 {
-	if (!proc_net_devsnmp6)
+	struct net *net = dev_net(idev->dev);
+	if (!net->mib.proc_net_devsnmp6)
 		return -ENOENT;
 	if (!idev || !idev->stats.proc_dir_entry)
 		return -EINVAL;
 	remove_proc_entry(idev->stats.proc_dir_entry->name,
-			  proc_net_devsnmp6);
+			  net->mib.proc_net_devsnmp6);
 	idev->stats.proc_dir_entry = NULL;
 	return 0;
 }
@@ -269,8 +270,9 @@ int __init ipv6_misc_proc_init(void)
 	if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
 		goto proc_snmp6_fail;
 
-	proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
-	if (!proc_net_devsnmp6)
+	init_net.mib.proc_net_devsnmp6 =
+		proc_mkdir("dev_snmp6", init_net.proc_net);
+	if (!init_net.mib.proc_net_devsnmp6)
 		goto proc_dev_snmp6_fail;
 out:
 	return rc;
Signature · 1 line
1.5.3.rc5
#3 lore raw

PATCH 2/9 netns: register /proc/net/dev_snmp6/* in each ns

In reply to a message not in the archive

Do the same for /proc/net/snmp6.

---
 net/ipv6/proc.c |   40 ++++++++++++++++------------------------
 1 files changed, 16 insertions(+), 24 deletions(-)
net/ipv6/proc.c +16 -24
index 16ebf85..5764062 100644
@@ -247,12 +247,27 @@ static int ipv6_proc_init_net(struct net *net)
 	if (!proc_net_fops_create(net, "sockstat6", S_IRUGO,
 			&sockstat6_seq_fops))
 		return -ENOMEM;
+
+	if (!proc_net_fops_create(net, "snmp6", S_IRUGO, &snmp6_seq_fops))
+		goto proc_snmp6_fail;
+
+	net->mib.proc_net_devsnmp6 = proc_mkdir("dev_snmp6", net->proc_net);
+	if (!net->mib.proc_net_devsnmp6)
+		goto proc_dev_snmp6_fail;
 	return 0;
+
+proc_snmp6_fail:
+	proc_net_remove(net, "sockstat6");
+proc_dev_snmp6_fail:
+	proc_net_remove(net, "dev_snmp6");
+	return -ENOMEM;
 }
 
 static void ipv6_proc_exit_net(struct net *net)
 {
 	proc_net_remove(net, "sockstat6");
+	proc_net_remove(net, "dev_snmp6");
+	proc_net_remove(net, "snmp6");
 }
 
 static struct pernet_operations ipv6_proc_ops = {
@@ -262,34 +277,11 @@ static struct pernet_operations ipv6_proc_ops = {
 
 int __init ipv6_misc_proc_init(void)
 {
-	int rc = 0;
-
-	if (register_pernet_subsys(&ipv6_proc_ops))
-		goto proc_net_fail;
-
-	if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
-		goto proc_snmp6_fail;
-
-	init_net.mib.proc_net_devsnmp6 =
-		proc_mkdir("dev_snmp6", init_net.proc_net);
-	if (!init_net.mib.proc_net_devsnmp6)
-		goto proc_dev_snmp6_fail;
-out:
-	return rc;
-
-proc_dev_snmp6_fail:
-	proc_net_remove(&init_net, "snmp6");
-proc_snmp6_fail:
-	unregister_pernet_subsys(&ipv6_proc_ops);
-proc_net_fail:
-	rc = -ENOMEM;
-	goto out;
+	return register_pernet_subsys(&ipv6_proc_ops);
 }
 
 void ipv6_misc_proc_exit(void)
 {
-	proc_net_remove(&init_net, "dev_snmp6");
-	proc_net_remove(&init_net, "snmp6");
 	unregister_pernet_subsys(&ipv6_proc_ops);
 }
 
Signature · 1 line
1.5.3.rc5
#4 lore raw

PATCH 3/9 ipv6: consolidate ipv6 sock_stat code at the beginning of net/ipv6/proc.c

In reply to a message not in the archive

Simple, comsolidate sockstat6 staff in one place, at the beginning of the file. Right now sockstat6_seq_open/sockstat6_seq_fops looks like an intrusion in the middle of snmp6 code.

---
 net/ipv6/proc.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)
net/ipv6/proc.c +13 -13
index 5764062..25eda8b 100644
@@ -46,6 +46,19 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
+static int sockstat6_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open_net(inode, file, sockstat6_seq_show);
+}
+
+static const struct file_operations sockstat6_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = sockstat6_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release_net,
+};
+
 static struct snmp_mib snmp6_ipstats_list[] = {
 /* ipv6 mib according to RFC 2465 */
 	SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
@@ -179,19 +192,6 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
-static int sockstat6_seq_open(struct inode *inode, struct file *file)
-{
-	return single_open_net(inode, file, sockstat6_seq_show);
-}
-
-static const struct file_operations sockstat6_seq_fops = {
-	.owner	 = THIS_MODULE,
-	.open	 = sockstat6_seq_open,
-	.read	 = seq_read,
-	.llseek	 = seq_lseek,
-	.release = single_release_net,
-};
-
 static int snmp6_seq_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, snmp6_seq_show, PDE(inode)->data);
Signature · 1 line
1.5.3.rc5
#5 lore raw

PATCH 4/9 ipv6: separate seq_ops for global & per/device ipv6 statistics

In reply to a message not in the archive

idev has been stored on seq->private. NULL has been stored for global statistics.

The situation is changed with net namespace. We need to store pointer to struct net and the only place is seq->private. So, we'll have for /proc/net/dev_snmp6/* and for /proc/net/snmp6 pointers of two different types stored in the same field.

This effectively requires to separate seq_ops of these files.

---
 net/ipv6/proc.c |   48 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 32 insertions(+), 16 deletions(-)
net/ipv6/proc.c +32 -16
index 25eda8b..7601f56 100644
@@ -175,26 +175,17 @@ snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
 
 static int snmp6_seq_show(struct seq_file *seq, void *v)
 {
-	struct inet6_dev *idev = (struct inet6_dev *)seq->private;
-
-	if (idev) {
-		seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
-		snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
-		snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
-		snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg);
-	} else {
-		snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
-		snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
-		snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
-		snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
-		snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
-	}
+	snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
+	snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
+	snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
+	snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
+	snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
 	return 0;
 }
 
 static int snmp6_seq_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, snmp6_seq_show, PDE(inode)->data);
+	return single_open(file, snmp6_seq_show, NULL);
 }
 
 static const struct file_operations snmp6_seq_fops = {
@@ -205,6 +196,30 @@ static const struct file_operations snmp6_seq_fops = {
 	.release = single_release,
 };
 
+static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
+{
+	struct inet6_dev *idev = (struct inet6_dev *)seq->private;
+
+	seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
+	snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
+	snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
+	snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg);
+	return 0;
+}
+
+static int snmp6_dev_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, snmp6_dev_seq_show, PDE(inode)->data);
+}
+
+static const struct file_operations snmp6_dev_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = snmp6_dev_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
 int snmp6_register_dev(struct inet6_dev *idev)
 {
 	struct proc_dir_entry *p;
@@ -221,7 +236,8 @@ int snmp6_register_dev(struct inet6_dev *idev)
 		return -ENOENT;
 
 	p = proc_create_data(idev->dev->name, S_IRUGO,
-			     net->mib.proc_net_devsnmp6, &snmp6_seq_fops, idev);
+			     net->mib.proc_net_devsnmp6,
+			     &snmp6_dev_seq_fops, idev);
 	if (!p)
 		return -ENOMEM;
 
Signature · 1 line
1.5.3.rc5
#6 lore raw

PATCH 5/9 netns: register global ipv6 mibs statistics in each namespace

In reply to a message not in the archive

Unused net variable will become used very soon.

---
 net/ipv6/proc.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
net/ipv6/proc.c +4 -2
index 7601f56..c38c9e5 100644
@@ -175,6 +175,8 @@ snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
 
 static int snmp6_seq_show(struct seq_file *seq, void *v)
 {
+	struct net *net = (struct net *)seq->private;
+
 	snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
 	snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
 	snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
@@ -185,7 +187,7 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 
 static int snmp6_seq_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, snmp6_seq_show, NULL);
+	return single_open_net(inode, file, snmp6_seq_show);
 }
 
 static const struct file_operations snmp6_seq_fops = {
@@ -193,7 +195,7 @@ static const struct file_operations snmp6_seq_fops = {
 	.open	 = snmp6_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = single_release,
+	.release = single_release_net,
 };
 
 static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
Signature · 1 line
1.5.3.rc5
#7 lore raw

PATCH 6/9 netns: allow per device ipv6 snmp statistics in non-initial namespace

In reply to a message not in the archive
---
 net/ipv6/proc.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
net/ipv6/proc.c +0 -3
index c38c9e5..23e567f 100644
@@ -231,9 +231,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
 		return -EINVAL;
 
 	net = dev_net(idev->dev);
-	if (!net_eq(net, &init_net))
-		return 0;
-
 	if (!net->mib.proc_net_devsnmp6)
 		return -ENOENT;
 
Signature · 1 line
1.5.3.rc5
#8 lore raw

PATCH 7/9 netns: add stab functions for per/namespace mibs allocation

In reply to a message not in the archive

The content of init_ipv6_mibs/cleanup_ipv6_mibs will be moved to new calls one by one next.

---
 net/ipv6/af_inet6.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)
net/ipv6/af_inet6.c +16 -2
index 95055f8..46d4e62 100644
@@ -834,6 +834,15 @@ static void cleanup_ipv6_mibs(void)
 	snmp_mib_free((void **)udplite_stats_in6);
 }
 
+static int __net_init ipv6_init_mibs(struct net *net)
+{
+	return 0;
+}
+
+static void __net_exit ipv6_cleanup_mibs(struct net *net)
+{
+}
+
 static int inet6_net_init(struct net *net)
 {
 	int err = 0;
@@ -849,6 +858,9 @@ static int inet6_net_init(struct net *net)
 	net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
 	net->ipv6.sysctl.icmpv6_time = 1*HZ;
 
+	err = ipv6_init_mibs(net);
+	if (err)
+		return err;
 #ifdef CONFIG_PROC_FS
 	err = udp6_proc_init(net);
 	if (err)
@@ -859,7 +871,6 @@ static int inet6_net_init(struct net *net)
 	err = ac6_proc_init(net);
 	if (err)
 		goto proc_ac6_fail;
-out:
 #endif
 	return err;
 
@@ -868,7 +879,9 @@ proc_ac6_fail:
 	tcp6_proc_exit(net);
 proc_tcp6_fail:
 	udp6_proc_exit(net);
-	goto out;
+out:
+	ipv6_cleanup_mibs(net);
+	return err;
 #endif
 }
 
@@ -879,6 +892,7 @@ static void inet6_net_exit(struct net *net)
 	tcp6_proc_exit(net);
 	ac6_proc_exit(net);
 #endif
+	ipv6_cleanup_mibs(net);
 }
 
 static struct pernet_operations inet6_net_ops = {
Signature · 1 line
1.5.3.rc5
#9 lore raw

PATCH 8/9 netns: make udpv6 mib per/namespace

In reply to a message not in the archive
---
 include/net/netns/mib.h |    1 +
 include/net/udp.h       |   12 ++++++------
 net/ipv4/udp.c          |    3 ---
 net/ipv6/af_inet6.c     |    9 ++++-----
 net/ipv6/proc.c         |    3 ++-
 5 files changed, 13 insertions(+), 15 deletions(-)
include/net/netns/mib.h +1 -0
index ffcef5d..ba622b2 100644
@@ -14,6 +14,7 @@ struct netns_mib {
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct proc_dir_entry *proc_net_devsnmp6;
+	DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
 #endif
 };
 
include/net/udp.h +6 -6
index addcdc6..e2a5de9 100644
@@ -148,8 +148,6 @@ extern int 	udp_lib_setsockopt(struct sock *sk, int level, int optname,
 				   char __user *optval, int optlen,
 				   int (*push_pending_frames)(struct sock *));
 
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-
 /* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
 DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 
@@ -163,12 +161,14 @@ DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 	if (is_udplite) SNMP_INC_STATS_BH((net)->mib.udplite_statistics, field);         \
 	else		SNMP_INC_STATS_BH((net)->mib.udp_statistics, field);    }  while(0)
 
-#define UDP6_INC_STATS_BH(net, field, is_udplite) 	    do { (void)net;  \
+#define UDP6_INC_STATS_BH(net, field, is_udplite) 	    do { \
 	if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);         \
-	else		SNMP_INC_STATS_BH(udp_stats_in6, field);    } while(0)
-#define UDP6_INC_STATS_USER(net, field, is_udplite)	    do { (void)net;    \
+	else		SNMP_INC_STATS_BH((net)->mib.udp_stats_in6, field);  \
+} while(0)
+#define UDP6_INC_STATS_USER(net, field, is_udplite)	    do { \
 	if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field);         \
-	else		SNMP_INC_STATS_USER(udp_stats_in6, field);    } while(0)
+	else		SNMP_INC_STATS_USER((net)->mib.udp_stats_in6, field);  \
+} while(0)
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #define UDPX_INC_STATS_BH(sk, field) \
net/ipv4/udp.c +0 -3
index 8e42fbb..4903420 100644
@@ -108,9 +108,6 @@
  *	Snmp MIB for the UDP layer
  */
 
-DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
-EXPORT_SYMBOL(udp_stats_in6);
-
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
 DEFINE_RWLOCK(udp_hash_lock);
 
net/ipv6/af_inet6.c +4 -5
index 46d4e62..f2933b2 100644
@@ -805,16 +805,12 @@ static int __init init_ipv6_mibs(void)
 	if (snmp_mib_init((void **)icmpv6msg_statistics,
 			  sizeof(struct icmpv6msg_mib)) < 0)
 		goto err_icmpmsg_mib;
-	if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
-		goto err_udp_mib;
 	if (snmp_mib_init((void **)udplite_stats_in6,
 			  sizeof (struct udp_mib)) < 0)
 		goto err_udplite_mib;
 	return 0;
 
 err_udplite_mib:
-	snmp_mib_free((void **)udp_stats_in6);
-err_udp_mib:
 	snmp_mib_free((void **)icmpv6msg_statistics);
 err_icmpmsg_mib:
 	snmp_mib_free((void **)icmpv6_statistics);
@@ -830,17 +826,20 @@ static void cleanup_ipv6_mibs(void)
 	snmp_mib_free((void **)ipv6_statistics);
 	snmp_mib_free((void **)icmpv6_statistics);
 	snmp_mib_free((void **)icmpv6msg_statistics);
-	snmp_mib_free((void **)udp_stats_in6);
 	snmp_mib_free((void **)udplite_stats_in6);
 }
 
 static int __net_init ipv6_init_mibs(struct net *net)
 {
+	if (snmp_mib_init((void **)net->mib.udp_stats_in6,
+			  sizeof (struct udp_mib)) < 0)
+		return -ENOMEM;
 	return 0;
 }
 
 static void __net_exit ipv6_cleanup_mibs(struct net *net)
 {
+	snmp_mib_free((void **)net->mib.udp_stats_in6);
 }
 
 static int inet6_net_init(struct net *net)
net/ipv6/proc.c +2 -1
index 23e567f..3eaf20b 100644
@@ -180,7 +180,8 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 	snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
 	snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
 	snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
-	snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
+	snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6,
+			    snmp6_udp6_list);
 	snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
 	return 0;
 }
Signature · 1 line
1.5.3.rc5
#10 lore raw

PATCH 9/9 netns: make uplitev6 mib per/namespace

In reply to a message not in the archive
---
 include/net/netns/mib.h |    1 +
 include/net/udp.h       |   11 ++++-------
 net/ipv6/af_inet6.c     |   14 ++++++++------
 net/ipv6/proc.c         |    3 ++-
 net/ipv6/udplite.c      |    2 --
 5 files changed, 15 insertions(+), 16 deletions(-)
include/net/netns/mib.h +1 -0
index ba622b2..4e58f05 100644
@@ -15,6 +15,7 @@ struct netns_mib {
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct proc_dir_entry *proc_net_devsnmp6;
 	DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
+	DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 #endif
 };
 
include/net/udp.h +4 -7
index e2a5de9..bd0d21a 100644
@@ -148,9 +148,6 @@ extern int 	udp_lib_setsockopt(struct sock *sk, int level, int optname,
 				   char __user *optval, int optlen,
 				   int (*push_pending_frames)(struct sock *));
 
-/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
-DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-
 /*
  * 	SNMP statistics for UDP and UDP-Lite
  */
@@ -162,12 +159,12 @@ DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 	else		SNMP_INC_STATS_BH((net)->mib.udp_statistics, field);    }  while(0)
 
 #define UDP6_INC_STATS_BH(net, field, is_udplite) 	    do { \
-	if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);         \
+	if (is_udplite) SNMP_INC_STATS_BH((net)->mib.udplite_stats_in6, field);\
 	else		SNMP_INC_STATS_BH((net)->mib.udp_stats_in6, field);  \
 } while(0)
-#define UDP6_INC_STATS_USER(net, field, is_udplite)	    do { \
-	if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field);         \
-	else		SNMP_INC_STATS_USER((net)->mib.udp_stats_in6, field);  \
+#define UDP6_INC_STATS_USER(net, field, __lite)		    do { \
+	if (__lite) SNMP_INC_STATS_USER((net)->mib.udplite_stats_in6, field);  \
+	else	    SNMP_INC_STATS_USER((net)->mib.udp_stats_in6, field);      \
 } while(0)
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
net/ipv6/af_inet6.c +8 -6
index f2933b2..7da9146 100644
@@ -805,13 +805,8 @@ static int __init init_ipv6_mibs(void)
 	if (snmp_mib_init((void **)icmpv6msg_statistics,
 			  sizeof(struct icmpv6msg_mib)) < 0)
 		goto err_icmpmsg_mib;
-	if (snmp_mib_init((void **)udplite_stats_in6,
-			  sizeof (struct udp_mib)) < 0)
-		goto err_udplite_mib;
 	return 0;
 
-err_udplite_mib:
-	snmp_mib_free((void **)icmpv6msg_statistics);
 err_icmpmsg_mib:
 	snmp_mib_free((void **)icmpv6_statistics);
 err_icmp_mib:
@@ -826,7 +821,6 @@ static void cleanup_ipv6_mibs(void)
 	snmp_mib_free((void **)ipv6_statistics);
 	snmp_mib_free((void **)icmpv6_statistics);
 	snmp_mib_free((void **)icmpv6msg_statistics);
-	snmp_mib_free((void **)udplite_stats_in6);
 }
 
 static int __net_init ipv6_init_mibs(struct net *net)
@@ -834,12 +828,20 @@ static int __net_init ipv6_init_mibs(struct net *net)
 	if (snmp_mib_init((void **)net->mib.udp_stats_in6,
 			  sizeof (struct udp_mib)) < 0)
 		return -ENOMEM;
+	if (snmp_mib_init((void **)net->mib.udplite_stats_in6,
+			  sizeof (struct udp_mib)) < 0)
+		goto err_udplite_mib;
 	return 0;
+
+err_udplite_mib:
+	snmp_mib_free((void **)net->mib.udp_stats_in6);
+	return -ENOMEM;
 }
 
 static void __net_exit ipv6_cleanup_mibs(struct net *net)
 {
 	snmp_mib_free((void **)net->mib.udp_stats_in6);
+	snmp_mib_free((void **)net->mib.udplite_stats_in6);
 }
 
 static int inet6_net_init(struct net *net)
net/ipv6/proc.c +2 -1
index 3eaf20b..c78cf75 100644
@@ -182,7 +182,8 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 	snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
 	snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6,
 			    snmp6_udp6_list);
-	snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
+	snmp6_seq_show_item(seq, (void **)net->mib.udplite_stats_in6,
+			    snmp6_udplite6_list);
 	return 0;
 }
 
net/ipv6/udplite.c +0 -2
index f6cdcb3..3cd1a1a 100644
@@ -13,8 +13,6 @@
  */
 #include "udp_impl.h"
 
-DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly;
-
 static int udplitev6_rcv(struct sk_buff *skb)
 {
 	return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
Signature · 1 line
1.5.3.rc5
#11 lore raw
In reply to a message not in the archive

From: "Denis V. Lunev" <[email protected]>
Date: Thu, 02 Oct 2008 14:13:14 +0400

Quoted 5 lines

This patch series provides a basic infrastructure to make snmp6 statistics per/namespace and actually virtualize udp6/udplite6 mibs.

This set follows approach used by Pavel Emelyanov in IPv4 code. IP6/icmp6 statistics is also ready and will follow.

Applied and pushed out to net-next-2.6, thanks!

#12 lore raw

PATCH 8/9 netns: make udpv6 mib per/namespace

In reply to Denis V. Lunev
---
 include/net/netns/mib.h |    1 +
 include/net/udp.h       |   12 ++++++------
 net/ipv4/udp.c          |    3 ---
 net/ipv6/af_inet6.c     |    9 ++++-----
 net/ipv6/proc.c         |    3 ++-
 5 files changed, 13 insertions(+), 15 deletions(-)
include/net/netns/mib.h +1 -0
index ffcef5d..ba622b2 100644
@@ -14,6 +14,7 @@ struct netns_mib {
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct proc_dir_entry *proc_net_devsnmp6;
+	DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
 #endif
 };
 
include/net/udp.h +6 -6
index addcdc6..e2a5de9 100644
@@ -148,8 +148,6 @@ extern int 	udp_lib_setsockopt(struct sock *sk, int level, int optname,
 				   char __user *optval, int optlen,
 				   int (*push_pending_frames)(struct sock *));
 
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-
 /* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
 DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 
@@ -163,12 +161,14 @@ DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
 	if (is_udplite) SNMP_INC_STATS_BH((net)->mib.udplite_statistics, field);         \
 	else		SNMP_INC_STATS_BH((net)->mib.udp_statistics, field);    }  while(0)
 
-#define UDP6_INC_STATS_BH(net, field, is_udplite) 	    do { (void)net;  \
+#define UDP6_INC_STATS_BH(net, field, is_udplite) 	    do { \
 	if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);         \
-	else		SNMP_INC_STATS_BH(udp_stats_in6, field);    } while(0)
-#define UDP6_INC_STATS_USER(net, field, is_udplite)	    do { (void)net;    \
+	else		SNMP_INC_STATS_BH((net)->mib.udp_stats_in6, field);  \
+} while(0)
+#define UDP6_INC_STATS_USER(net, field, is_udplite)	    do { \
 	if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field);         \
-	else		SNMP_INC_STATS_USER(udp_stats_in6, field);    } while(0)
+	else		SNMP_INC_STATS_USER((net)->mib.udp_stats_in6, field);  \
+} while(0)
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #define UDPX_INC_STATS_BH(sk, field) \
net/ipv4/udp.c +0 -3
index 8e42fbb..4903420 100644
@@ -108,9 +108,6 @@
  *	Snmp MIB for the UDP layer
  */
 
-DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
-EXPORT_SYMBOL(udp_stats_in6);
-
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
 DEFINE_RWLOCK(udp_hash_lock);
 
net/ipv6/af_inet6.c +4 -5
index 46d4e62..f2933b2 100644
@@ -805,16 +805,12 @@ static int __init init_ipv6_mibs(void)
 	if (snmp_mib_init((void **)icmpv6msg_statistics,
 			  sizeof(struct icmpv6msg_mib)) < 0)
 		goto err_icmpmsg_mib;
-	if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
-		goto err_udp_mib;
 	if (snmp_mib_init((void **)udplite_stats_in6,
 			  sizeof (struct udp_mib)) < 0)
 		goto err_udplite_mib;
 	return 0;
 
 err_udplite_mib:
-	snmp_mib_free((void **)udp_stats_in6);
-err_udp_mib:
 	snmp_mib_free((void **)icmpv6msg_statistics);
 err_icmpmsg_mib:
 	snmp_mib_free((void **)icmpv6_statistics);
@@ -830,17 +826,20 @@ static void cleanup_ipv6_mibs(void)
 	snmp_mib_free((void **)ipv6_statistics);
 	snmp_mib_free((void **)icmpv6_statistics);
 	snmp_mib_free((void **)icmpv6msg_statistics);
-	snmp_mib_free((void **)udp_stats_in6);
 	snmp_mib_free((void **)udplite_stats_in6);
 }
 
 static int __net_init ipv6_init_mibs(struct net *net)
 {
+	if (snmp_mib_init((void **)net->mib.udp_stats_in6,
+			  sizeof (struct udp_mib)) < 0)
+		return -ENOMEM;
 	return 0;
 }
 
 static void __net_exit ipv6_cleanup_mibs(struct net *net)
 {
+	snmp_mib_free((void **)net->mib.udp_stats_in6);
 }
 
 static int inet6_net_init(struct net *net)
net/ipv6/proc.c +2 -1
index 23e567f..3eaf20b 100644
@@ -180,7 +180,8 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
 	snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
 	snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
 	snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
-	snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
+	snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6,
+			    snmp6_udp6_list);
 	snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
 	return 0;
 }
Signature · 1 line
1.5.3.rc5
maintainer
#13 lore raw
In reply to Denis V. Lunev

From: "Denis V. Lunev" <[email protected]>
Date: Thu, 02 Oct 2008 14:13:14 +0400

Quoted 5 lines

This patch series provides a basic infrastructure to make snmp6 statistics per/namespace and actually virtualize udp6/udplite6 mibs.

This set follows approach used by Pavel Emelyanov in IPv4 code. IP6/icmp6 statistics is also ready and will follow.

Applied and pushed out to net-next-2.6, thanks!