@@ -331,7 +331,11 @@ static struct timer_list rate_timer;
331331static long long sec_prate = 0 , sec_brate = 0 ;
332332static long long min_prate = 0 , min_brate = 0 ;
333333static long long min5_prate = 0 , min5_brate = 0 ;
334- static unsigned int metric = 100 , min15_metric = 100 , min5_metric = 100 , min_metric = 100 ; /* hash metrics */
334+ #define METRIC_DFL 100
335+ static unsigned int metric = METRIC_DFL ,
336+ min15_metric = METRIC_DFL ,
337+ min5_metric = METRIC_DFL ,
338+ min_metric = METRIC_DFL ; /* hash metrics */
335339
336340static int set_hashsize (int new_size );
337341static void destination_removeall (void );
@@ -619,7 +623,7 @@ static int nf_seq_show(struct seq_file *seq, void *v)
619623 (unsigned long long )st -> searched ,
620624 (unsigned long long )st -> found ,
621625 (unsigned long long )st -> notfound ,
622- FFLOAT (SAFEDIV ( 100LL * ( st -> searched + st -> found + st -> notfound ), ( st -> found + st -> notfound )) , 100 ),
626+ FFLOAT (st -> metric , 100 ),
623627 st -> truncated , st -> frags , st -> alloc_err , st -> maxflows_err ,
624628 st -> exported_pkt , st -> send_failed , st -> sock_errors ,
625629 (unsigned long long )st -> exported_traf >> 10 ,
@@ -1300,6 +1304,17 @@ static int snmp_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,
13001304}
13011305#endif
13021306
1307+ static void clear_ipt_netflow_stat (void )
1308+ {
1309+ int cpu ;
1310+
1311+ for_each_present_cpu (cpu ) {
1312+ struct ipt_netflow_stat * st = & per_cpu (ipt_netflow_stat , cpu );
1313+ memset (st , 0 , sizeof (* st ));
1314+ st -> metric = METRIC_DFL ;
1315+ }
1316+ }
1317+
13031318static int flush_procctl (ctl_table * ctl , int write , BEFORE2632 (struct file * filp ,)
13041319 void __user * buffer , size_t * lenp , loff_t * fpos )
13051320{
@@ -1318,12 +1333,7 @@ static int flush_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp
13181333 pause_scan_worker ();
13191334 netflow_scan_and_export (AND_FLUSH );
13201335 if (val > 1 ) {
1321- int cpu ;
1322-
1323- for_each_present_cpu (cpu ) {
1324- struct ipt_netflow_stat * st = & per_cpu (ipt_netflow_stat , cpu );
1325- memset (st , 0 , sizeof (* st ));
1326- }
1336+ clear_ipt_netflow_stat ();
13271337 stat = " (reset stat counters)" ;
13281338 }
13291339 printk (KERN_INFO "ipt_NETFLOW: forced flush%s.\n" , stat );
@@ -3948,12 +3958,13 @@ static void rate_timer_calc(unsigned long dummy)
39483958 u64 searched = 0 ;
39493959 u64 found = 0 ;
39503960 u64 notfound = 0 ;
3951- unsigned int dsrch , dfnd , dnfnd ;
3961+ int dsrch , dfnd , dnfnd ;
39523962 u64 pkt_total = 0 ;
39533963 u64 traf_total = 0 ;
39543964 int cpu ;
39553965
39563966 for_each_present_cpu (cpu ) {
3967+ int metrt ;
39573968 struct ipt_netflow_stat * st = & per_cpu (ipt_netflow_stat , cpu );
39583969 u64 pkt_t = st -> pkt_total ;
39593970
@@ -3964,6 +3975,16 @@ static void rate_timer_calc(unsigned long dummy)
39643975 searched += st -> searched ;
39653976 found += st -> found ;
39663977 notfound += st -> notfound ;
3978+ /* calculate hash metric per cpu */
3979+ dsrch = st -> searched - st -> old_searched ;
3980+ dfnd = st -> found - st -> old_found ;
3981+ dnfnd = st -> notfound - st -> old_notfound ;
3982+ /* zero values are not accounted, becasue only usage is interesting, not nonusage */
3983+ metrt = (dfnd + dnfnd )? 100 * (dsrch + dfnd + dnfnd ) / (dfnd + dnfnd ) : st -> metric ;
3984+ CALC_RATE (st -> metric , metrt , 1 );
3985+ st -> old_searched = st -> searched ;
3986+ st -> old_found = st -> found ;
3987+ st -> old_notfound = st -> notfound ;
39673988 }
39683989
39693990 sec_prate = (pkt_total - old_pkt_total ) >> RATESHIFT ;
@@ -3976,17 +3997,18 @@ static void rate_timer_calc(unsigned long dummy)
39763997 CALC_RATE (min_brate , sec_brate , 1 );
39773998 old_traf_total = traf_total ;
39783999
4000+ /* hash stat */
39794001 dsrch = searched - old_searched ;
3980- dfnd = found - old_found ;
4002+ dfnd = found - old_found ;
39814003 dnfnd = notfound - old_notfound ;
39824004 old_searched = searched ;
3983- old_found = found ;
4005+ old_found = found ;
39844006 old_notfound = notfound ;
39854007 /* if there is no access to hash keep rate steady */
39864008 metric = (dfnd + dnfnd )? 100 * (dsrch + dfnd + dnfnd ) / (dfnd + dnfnd ) : metric ;
3987- CALC_RATE (min15_metric , ( unsigned long long ) metric , 15 );
3988- CALC_RATE (min5_metric , ( unsigned long long ) metric , 5 );
3989- CALC_RATE (min_metric , ( unsigned long long ) metric , 1 );
4009+ CALC_RATE (min15_metric , metric , 15 );
4010+ CALC_RATE (min5_metric , metric , 5 );
4011+ CALC_RATE (min_metric , metric , 1 );
39904012
39914013 /* yes, timer delay is not accounted, but this stat is just estimational */
39924014 mod_timer (& rate_timer , jiffies + (HZ * SAMPLERATE ));
@@ -4975,6 +4997,7 @@ static int __init ipt_netflow_init(void)
49754997 tpl_element_sizes [observationDomainName ] = version_string_size + 1 ;
49764998
49774999 start_ts .first = ktime_get_real ();
5000+ clear_ipt_netflow_stat ();
49785001
49795002 /* determine hash size (idea from nf_conntrack_core.c) */
49805003 if (!hashsize ) {
0 commit comments