Если вы используете pppoe, то у вас стоит Radius, который периодически принимает от mpd accounting пакеты, в которых передается трафик. Вот эти пакеты в настоящее время используются только как признак "клиент жив". Хотя можно их использовать для начисления трафика в учетку клиента. Плюс в том, что практически никаких накладных расходов. Т.е мы удаляем ipcad (ну, и, соответственно, правила divert в фаерволе) и получаем увеличение производительности сервера. Минус в том, что лога трафика (графиков) не будет.
Фича оттестирована elite, поэтому если всплывут какие-то нюансы - задавайте вопросы ему.
В /usr/local/etc/raddb/sql.conf
postauth_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}',%{Acct-Session-Id},0)"
меняем на
accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}','%{Acct-Session-Id}',\
(%{%{Acct-Input-Gigawords}:-0} * POWER(2, 32)) + %{%{Acct-Input-Octets}:-0})"}
CREATE TABLE IF NOT EXISTS `ses_traf` (
`id` bigint(21) NOT NULL auto_increment,
`ses_id` varchar(32) NOT NULL default '',
`time` int(10) unsigned NOT NULL DEFAULT '0',
`traf_in` bigint(12) unsigned NOT NULL DEFAULT '0',
`traf_out` bigint(12) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ses_id` (`ses_id`),
KEY `time` (`time`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16),
IN properties VARCHAR(255), IN ses VARCHAR(32), IN trafin BIGINT(20))
BEGIN
DECLARE usr_id INT;
DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
SELECT id INTO usr_id FROM users WHERE name=login LIMIT 1;
SELECT get_ip(usr_id) INTO usr_ip;
CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':','')));
UPDATE users_trf SET in1=in1 + trafin - IFNULL(
(SELECT traf_in FROM ses_traf WHERE ses_id=ses LIMIT 1),0)
WHERE uid=usr_id;
INSERT INTO ses_traf SET ses_id=ses, traf_in=trafin, time=UNIX_TIMESTAMP()
ON DUPLICATE KEY UPDATE traf_in=trafin, time=UNIX_TIMESTAMP();
END$$
DELIMITER ;