aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_vs.h1
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c96
-rw-r--r--net/netfilter/ipvs/ip_vs_est.c15
3 files changed, 69 insertions, 43 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 9db750d9082d..06f5af4b626d 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -374,6 +374,7 @@ struct ip_vs_stats {
374 struct ip_vs_estimator est; /* estimator */ 374 struct ip_vs_estimator est; /* estimator */
375 struct ip_vs_cpu_stats *cpustats; /* per cpu counters */ 375 struct ip_vs_cpu_stats *cpustats; /* per cpu counters */
376 spinlock_t lock; /* spin lock */ 376 spinlock_t lock; /* spin lock */
377 struct ip_vs_stats_user ustats0; /* reset values */
377}; 378};
378 379
379/* 380/*
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index a2a67ad7e094..804fee7be694 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -711,13 +711,51 @@ static void ip_vs_trash_cleanup(struct net *net)
711 } 711 }
712} 712}
713 713
714static void
715ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src)
716{
717#define IP_VS_SHOW_STATS_COUNTER(c) dst->c = src->ustats.c - src->ustats0.c
718#define IP_VS_SHOW_STATS_RATE(r) dst->r = src->ustats.r
719
720 spin_lock_bh(&src->lock);
721
722 IP_VS_SHOW_STATS_COUNTER(conns);
723 IP_VS_SHOW_STATS_COUNTER(inpkts);
724 IP_VS_SHOW_STATS_COUNTER(outpkts);
725 IP_VS_SHOW_STATS_COUNTER(inbytes);
726 IP_VS_SHOW_STATS_COUNTER(outbytes);
727
728 IP_VS_SHOW_STATS_RATE(cps);
729 IP_VS_SHOW_STATS_RATE(inpps);
730 IP_VS_SHOW_STATS_RATE(outpps);
731 IP_VS_SHOW_STATS_RATE(inbps);
732 IP_VS_SHOW_STATS_RATE(outbps);
733
734 spin_unlock_bh(&src->lock);
735}
714 736
715static void 737static void
716ip_vs_zero_stats(struct ip_vs_stats *stats) 738ip_vs_zero_stats(struct ip_vs_stats *stats)
717{ 739{
718 spin_lock_bh(&stats->lock); 740 spin_lock_bh(&stats->lock);
719 741
720 memset(&stats->ustats, 0, sizeof(stats->ustats)); 742 /* get current counters as zero point, rates are zeroed */
743
744#define IP_VS_ZERO_STATS_COUNTER(c) stats->ustats0.c = stats->ustats.c
745#define IP_VS_ZERO_STATS_RATE(r) stats->ustats.r = 0
746
747 IP_VS_ZERO_STATS_COUNTER(conns);
748 IP_VS_ZERO_STATS_COUNTER(inpkts);
749 IP_VS_ZERO_STATS_COUNTER(outpkts);
750 IP_VS_ZERO_STATS_COUNTER(inbytes);
751 IP_VS_ZERO_STATS_COUNTER(outbytes);
752
753 IP_VS_ZERO_STATS_RATE(cps);
754 IP_VS_ZERO_STATS_RATE(inpps);
755 IP_VS_ZERO_STATS_RATE(outpps);
756 IP_VS_ZERO_STATS_RATE(inbps);
757 IP_VS_ZERO_STATS_RATE(outbps);
758
721 ip_vs_zero_estimator(stats); 759 ip_vs_zero_estimator(stats);
722 760
723 spin_unlock_bh(&stats->lock); 761 spin_unlock_bh(&stats->lock);
@@ -1963,7 +2001,7 @@ static const struct file_operations ip_vs_info_fops = {
1963static int ip_vs_stats_show(struct seq_file *seq, void *v) 2001static int ip_vs_stats_show(struct seq_file *seq, void *v)
1964{ 2002{
1965 struct net *net = seq_file_single_net(seq); 2003 struct net *net = seq_file_single_net(seq);
1966 struct ip_vs_stats *tot_stats = &net_ipvs(net)->tot_stats; 2004 struct ip_vs_stats_user show;
1967 2005
1968/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 2006/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
1969 seq_puts(seq, 2007 seq_puts(seq,
@@ -1971,22 +2009,18 @@ static int ip_vs_stats_show(struct seq_file *seq, void *v)
1971 seq_printf(seq, 2009 seq_printf(seq,
1972 " Conns Packets Packets Bytes Bytes\n"); 2010 " Conns Packets Packets Bytes Bytes\n");
1973 2011
1974 spin_lock_bh(&tot_stats->lock); 2012 ip_vs_copy_stats(&show, &net_ipvs(net)->tot_stats);
1975 seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", tot_stats->ustats.conns, 2013 seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", show.conns,
1976 tot_stats->ustats.inpkts, tot_stats->ustats.outpkts, 2014 show.inpkts, show.outpkts,
1977 (unsigned long long) tot_stats->ustats.inbytes, 2015 (unsigned long long) show.inbytes,
1978 (unsigned long long) tot_stats->ustats.outbytes); 2016 (unsigned long long) show.outbytes);
1979 2017
1980/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 2018/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
1981 seq_puts(seq, 2019 seq_puts(seq,
1982 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); 2020 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n");
1983 seq_printf(seq,"%8X %8X %8X %16X %16X\n", 2021 seq_printf(seq, "%8X %8X %8X %16X %16X\n",
1984 tot_stats->ustats.cps, 2022 show.cps, show.inpps, show.outpps,
1985 tot_stats->ustats.inpps, 2023 show.inbps, show.outbps);
1986 tot_stats->ustats.outpps,
1987 tot_stats->ustats.inbps,
1988 tot_stats->ustats.outbps);
1989 spin_unlock_bh(&tot_stats->lock);
1990 2024
1991 return 0; 2025 return 0;
1992} 2026}
@@ -2298,14 +2332,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2298 2332
2299 2333
2300static void 2334static void
2301ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src)
2302{
2303 spin_lock_bh(&src->lock);
2304 memcpy(dst, &src->ustats, sizeof(*dst));
2305 spin_unlock_bh(&src->lock);
2306}
2307
2308static void
2309ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src) 2335ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src)
2310{ 2336{
2311 dst->protocol = src->protocol; 2337 dst->protocol = src->protocol;
@@ -2691,31 +2717,29 @@ static const struct nla_policy ip_vs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = {
2691static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type, 2717static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type,
2692 struct ip_vs_stats *stats) 2718 struct ip_vs_stats *stats)
2693{ 2719{
2720 struct ip_vs_stats_user ustats;
2694 struct nlattr *nl_stats = nla_nest_start(skb, container_type); 2721 struct nlattr *nl_stats = nla_nest_start(skb, container_type);
2695 if (!nl_stats) 2722 if (!nl_stats)
2696 return -EMSGSIZE; 2723 return -EMSGSIZE;
2697 2724
2698 spin_lock_bh(&stats->lock); 2725 ip_vs_copy_stats(&ustats, stats);
2699
2700 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, stats->ustats.conns);
2701 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, stats->ustats.inpkts);
2702 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, stats->ustats.outpkts);
2703 NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, stats->ustats.inbytes);
2704 NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, stats->ustats.outbytes);
2705 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, stats->ustats.cps);
2706 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, stats->ustats.inpps);
2707 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, stats->ustats.outpps);
2708 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, stats->ustats.inbps);
2709 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, stats->ustats.outbps);
2710 2726
2711 spin_unlock_bh(&stats->lock); 2727 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, ustats.conns);
2728 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, ustats.inpkts);
2729 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, ustats.outpkts);
2730 NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, ustats.inbytes);
2731 NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, ustats.outbytes);
2732 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, ustats.cps);
2733 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, ustats.inpps);
2734 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, ustats.outpps);
2735 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, ustats.inbps);
2736 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, ustats.outbps);
2712 2737
2713 nla_nest_end(skb, nl_stats); 2738 nla_nest_end(skb, nl_stats);
2714 2739
2715 return 0; 2740 return 0;
2716 2741
2717nla_put_failure: 2742nla_put_failure:
2718 spin_unlock_bh(&stats->lock);
2719 nla_nest_cancel(skb, nl_stats); 2743 nla_nest_cancel(skb, nl_stats);
2720 return -EMSGSIZE; 2744 return -EMSGSIZE;
2721} 2745}
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index b3751cfede2c..a85008796370 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -184,13 +184,14 @@ void ip_vs_kill_estimator(struct net *net, struct ip_vs_stats *stats)
184void ip_vs_zero_estimator(struct ip_vs_stats *stats) 184void ip_vs_zero_estimator(struct ip_vs_stats *stats)
185{ 185{
186 struct ip_vs_estimator *est = &stats->est; 186 struct ip_vs_estimator *est = &stats->est;
187 187 struct ip_vs_stats_user *u = &stats->ustats;
188 /* set counters zero, caller must hold the stats->lock lock */ 188
189 est->last_inbytes = 0; 189 /* reset counters, caller must hold the stats->lock lock */
190 est->last_outbytes = 0; 190 est->last_inbytes = u->inbytes;
191 est->last_conns = 0; 191 est->last_outbytes = u->outbytes;
192 est->last_inpkts = 0; 192 est->last_conns = u->conns;
193 est->last_outpkts = 0; 193 est->last_inpkts = u->inpkts;
194 est->last_outpkts = u->outpkts;
194 est->cps = 0; 195 est->cps = 0;
195 est->inpps = 0; 196 est->inpps = 0;
196 est->outpps = 0; 197 est->outpps = 0;