From 6ee7c2ef1260fd9b700893aa05c3d2a770d65e45 Mon Sep 17 00:00:00 2001 From: Torsten Schmidt Date: Tue, 5 Jan 2010 09:34:51 +0100 Subject: [PATCH 2/3] ipv4: add DSCP OUT statistic Signed-off-by: Torsten Schmidt --- include/net/ipdscp.h | 31 +++++++++++++++++++++++++++++++ include/net/netns/mib.h | 1 + net/ipv4/ip_output.c | 5 +++++ net/ipv4/ipdscp.c | 21 ++++++++++++++++----- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/net/ipdscp.h b/include/net/ipdscp.h index 4236704..c14f523 100644 --- a/include/net/ipdscp.h +++ b/include/net/ipdscp.h @@ -38,10 +38,13 @@ #define IP_DSCP_AF43 (0x26) #define IP_DSCP_EF (0x2E) + #ifdef CONFIG_IP_DSCP_STAT #define IP_DSCPIN_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ipdscp_in_statistics, field) +#define IP_DSCPOUT_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ipdscp_out_statistics, field) #else #define IP_DSCPIN_INC_STATS_BH(net, field) ((void)(net)) +#define IP_DSCPOUT_INC_STATS(net, field) ((void)(net)) #endif @@ -76,4 +79,32 @@ static inline void ipv4_dscp_stat_in(struct net *net, __u8 dsfield) } } + +static inline void ipv4_dscp_stat_out(struct net *net, __u8 dsfield) +{ + switch (dsfield >> 2) { + case IP_DSCP_CS0: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS0);break; + case IP_DSCP_EF: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_EF);break; + case IP_DSCP_CS1: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS1);break; + case IP_DSCP_CS2: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS2);break; + case IP_DSCP_CS3: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS3);break; + case IP_DSCP_CS4: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS4);break; + case IP_DSCP_CS5: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS5);break; + case IP_DSCP_CS6: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS6);break; + case IP_DSCP_CS7: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_CS7);break; + case IP_DSCP_AF11: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF11);break; + case IP_DSCP_AF12: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF12);break; + case IP_DSCP_AF13: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF13);break; + case IP_DSCP_AF21: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF21);break; + case IP_DSCP_AF22: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF22);break; + case IP_DSCP_AF23: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF23);break; + case IP_DSCP_AF31: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF31);break; + case IP_DSCP_AF32: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF32);break; + case IP_DSCP_AF33: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF33);break; + case IP_DSCP_AF41: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF41);break; + case IP_DSCP_AF42: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF42);break; + case IP_DSCP_AF43: IP_DSCPOUT_INC_STATS(net, LINUX_MIB_IPDSCP_AF43);break; + } +} + #endif diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h index a849e89..183f15b 100644 --- a/include/net/netns/mib.h +++ b/include/net/netns/mib.h @@ -26,6 +26,7 @@ struct netns_mib { #ifdef CONFIG_IP_DSCP_STAT struct proc_dir_entry *proc_net_ipdscp; DEFINE_SNMP_STAT(struct ipdscp_mib, ipdscp_in_statistics); + DEFINE_SNMP_STAT(struct ipdscp_mib, ipdscp_out_statistics); #endif }; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f989518..e14eca8 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -79,6 +79,7 @@ #include #include #include +#include int sysctl_ip_default_ttl __read_mostly = IPDEFTTL; @@ -300,6 +301,10 @@ int ip_output(struct sk_buff *skb) IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); +#ifdef CONFIG_IP_DSCP_STAT + ipv4_dscp_stat_out(dev_net(dev), ip_hdr(skb)->tos); +#endif + skb->dev = dev; skb->protocol = htons(ETH_P_IP); diff --git a/net/ipv4/ipdscp.c b/net/ipv4/ipdscp.c index fdbfb7b..8988ccb 100644 --- a/net/ipv4/ipdscp.c +++ b/net/ipv4/ipdscp.c @@ -46,8 +46,10 @@ static int ipdscp_statistics_seq_show(struct seq_file *seq, void *v) struct net *net = seq->private; int i; for (i=0; ipdscp_mib_list[i].name; i++) - seq_printf(seq, "%-24s\t%lu\n", ipdscp_mib_list[i].name, + seq_printf(seq, "%-24s\t%lu\t%lu\n", ipdscp_mib_list[i].name, snmp_fold_field((void **)net->mib.ipdscp_in_statistics, + ipdscp_mib_list[i].entry), + snmp_fold_field((void **)net->mib.ipdscp_out_statistics, ipdscp_mib_list[i].entry)); return 0; } @@ -89,11 +91,20 @@ int __net_init ipdscp_stat_init(struct net *net) if (snmp_mib_init((void **)net->mib.ipdscp_in_statistics, sizeof(struct ipdscp_mib)) < 0) - return -ENOMEM; + goto err_ipdscp_in; + if (snmp_mib_init((void **)net->mib.ipdscp_out_statistics, + sizeof(struct ipdscp_mib)) < 0) + goto err_ipdscp_out; + rv = ipdscp_proc_init(net); - if (rv < 0) - snmp_mib_free((void **)net->mib.ipdscp_in_statistics); - return rv; + if (rv >= 0) + return 0; + +err_ipdscp_out: + snmp_mib_free((void **)net->mib.ipdscp_out_statistics); +err_ipdscp_in: + snmp_mib_free((void **)net->mib.ipdscp_in_statistics); + return -ENOMEM; } void ipdscp_stat_fini(struct net *net) -- 1.6.3.3