diff options
Diffstat (limited to 'net/netfilter/xt_connbytes.c')
| -rw-r--r-- | net/netfilter/xt_connbytes.c | 44 | 
1 files changed, 23 insertions, 21 deletions
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index 5b138506690..1e634615ab9 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -26,60 +26,62 @@ connbytes_mt(const struct sk_buff *skb, struct xt_action_param *par)  	u_int64_t what = 0;	/* initialize to make gcc happy */  	u_int64_t bytes = 0;  	u_int64_t pkts = 0; +	const struct nf_conn_acct *acct;  	const struct nf_conn_counter *counters;  	ct = nf_ct_get(skb, &ctinfo);  	if (!ct)  		return false; -	counters = nf_conn_acct_find(ct); -	if (!counters) +	acct = nf_conn_acct_find(ct); +	if (!acct)  		return false; +	counters = acct->counter;  	switch (sinfo->what) {  	case XT_CONNBYTES_PKTS:  		switch (sinfo->direction) {  		case XT_CONNBYTES_DIR_ORIGINAL: -			what = counters[IP_CT_DIR_ORIGINAL].packets; +			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);  			break;  		case XT_CONNBYTES_DIR_REPLY: -			what = counters[IP_CT_DIR_REPLY].packets; +			what = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);  			break;  		case XT_CONNBYTES_DIR_BOTH: -			what = counters[IP_CT_DIR_ORIGINAL].packets; -			what += counters[IP_CT_DIR_REPLY].packets; +			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets); +			what += atomic64_read(&counters[IP_CT_DIR_REPLY].packets);  			break;  		}  		break;  	case XT_CONNBYTES_BYTES:  		switch (sinfo->direction) {  		case XT_CONNBYTES_DIR_ORIGINAL: -			what = counters[IP_CT_DIR_ORIGINAL].bytes; +			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes);  			break;  		case XT_CONNBYTES_DIR_REPLY: -			what = counters[IP_CT_DIR_REPLY].bytes; +			what = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);  			break;  		case XT_CONNBYTES_DIR_BOTH: -			what = counters[IP_CT_DIR_ORIGINAL].bytes; -			what += counters[IP_CT_DIR_REPLY].bytes; +			what = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes); +			what += atomic64_read(&counters[IP_CT_DIR_REPLY].bytes);  			break;  		}  		break;  	case XT_CONNBYTES_AVGPKT:  		switch (sinfo->direction) {  		case XT_CONNBYTES_DIR_ORIGINAL: -			bytes = counters[IP_CT_DIR_ORIGINAL].bytes; -			pkts  = counters[IP_CT_DIR_ORIGINAL].packets; +			bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes); +			pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets);  			break;  		case XT_CONNBYTES_DIR_REPLY: -			bytes = counters[IP_CT_DIR_REPLY].bytes; -			pkts  = counters[IP_CT_DIR_REPLY].packets; +			bytes = atomic64_read(&counters[IP_CT_DIR_REPLY].bytes); +			pkts  = atomic64_read(&counters[IP_CT_DIR_REPLY].packets);  			break;  		case XT_CONNBYTES_DIR_BOTH: -			bytes = counters[IP_CT_DIR_ORIGINAL].bytes + -				counters[IP_CT_DIR_REPLY].bytes; -			pkts  = counters[IP_CT_DIR_ORIGINAL].packets + -				counters[IP_CT_DIR_REPLY].packets; +			bytes = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].bytes) + +				atomic64_read(&counters[IP_CT_DIR_REPLY].bytes); +			pkts  = atomic64_read(&counters[IP_CT_DIR_ORIGINAL].packets) + +				atomic64_read(&counters[IP_CT_DIR_REPLY].packets);  			break;  		}  		if (pkts != 0) @@ -87,10 +89,10 @@ connbytes_mt(const struct sk_buff *skb, struct xt_action_param *par)  		break;  	} -	if (sinfo->count.to) +	if (sinfo->count.to >= sinfo->count.from)  		return what <= sinfo->count.to && what >= sinfo->count.from; -	else -		return what >= sinfo->count.from; +	else /* inverted */ +		return what < sinfo->count.to || what > sinfo->count.from;  }  static int connbytes_mt_check(const struct xt_mtchk_param *par)  | 
