Сабж темы заслуживает внимания т.к. данная связка описана в разных местах и с разными допущениями и требует довольно долгого курения всяких процедур, чтобы понять что именно необходимо, поэтому собираю все до кучи в этой теме.
Если кто-то хочет вникать самостоятельно, то вот ссылки для облегчения поисков:
http://forum.nodeny.com.ua/index.php?topic=2703.75http://forum.nodeny.com.ua/index.php?topic=2374.0http://nodeny.com.ua/wiki/index.php/Dhcp%2BRadiusИтак. Что мы имеем? При нескольких вланах, обслуживаемых одним микротиком настройка ДХЦП сводится к поднятию и настройке DHCP сервера для каждого из вланов (со своим интерфейсом, пулом и т.п.) Тут самое важное понимать, что ДХЦП сервер микротика присылает запрос на радиус-сервер с радиус-атрибутом Called-Station-Id равным параметру Name в настройках дхцп микротика.
Раз мы все это поняли, то остается передавать в биллиг этот параметр и пометить необходимые динамические пулы тегом равным параметру Name (имени) дхцп для каждого из вланов.
Даллее sql.conf необходимо внести изменения чтобы было так:
authorize_check_query = "call radcheck('%{User-Name}')"
authorize_reply_query = "call radreply('%{User-Name}', '%{Called-Station-Id}')"
postauth_query = "call radupdate('%{User-Name}','%{reply:Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{Called-Station-Id}')"
accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{Called-Station-Id}')"
Не забыть ребутнуть после этого радиус-сервер.
Ну и внести в базу данных изменения в процедуры и функции:
DROP FUNCTION IF EXISTS `get_ip_by_tag`;
DELIMITER $$
CREATE FUNCTION `get_ip_by_tag` ( user_id INTEGER UNSIGNED, tag VARCHAR(64) )
RETURNS VARCHAR(15) NO SQL
BEGIN
DECLARE user_ip VARCHAR(15);
DECLARE real_ip VARCHAR(15);
SELECT 1 INTO real_ip FROM users_services WHERE uid = user_id AND tags LIKE '%,realip,%';
UPDATE ip_pool SET uid = user_id, `release` = UNIX_TIMESTAMP() + 300
WHERE (uid = 0 OR uid = user_id)
AND type = 'dynamic'
AND realip = IF(real_ip>0,1,0)
AND tags LIKE CONCAT('%,', tag, ',%')
ORDER BY uid DESC, id ASC LIMIT 1;
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
WHERE uid = user_id LIMIT 1;
RETURN user_ip;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64), tag VARCHAR(64))
BEGIN
DECLARE usr_mac VARCHAR(12);
DECLARE usr_ip VARCHAR(15);
DECLARE usr_id INT;
DECLARE add_attr MEDIUMTEXT;
DECLARE line MEDIUMTEXT;
DECLARE i INT DEFAULT 1;
SELECT REPLACE(login, ':', '') INTO usr_mac;
SELECT uid INTO usr_id FROM mac_uid WHERE mac=usr_mac;
IF usr_id IS NOT NULL AND usr_id>0 THEN
SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;
UPDATE mac_uid SET ip=0 WHERE ip=INET_ATON(usr_ip) AND uid<>usr_id;
UPDATE mac_uid SET ip=INET_ATON(usr_ip), time=UNIX_TIMESTAMP() WHERE uid=usr_id;
ELSE
START TRANSACTION;
SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool p WHERE uid=0 AND type='dynamic' AND tags LIKE CONCAT('%,', tag ,',%')
AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip)
ORDER BY RAND() LIMIT 1 FOR UPDATE;
INSERT INTO mac_uid VALUES(
NULL, usr_mac, INET_ATON(usr_ip), 0, UNIX_TIMESTAMP(), 0, 0, 0)
ON DUPLICATE KEY
UPDATE ip=IF(ip>0,ip,INET_ATON(usr_ip)), time=UNIX_TIMESTAMP();
COMMIT;
SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=usr_mac;
END IF;
SELECT NULL, login, 'Framed-IP-Address', usr_ip, '=';
SELECT NULL, login, 'Session-Timeout', '600', '=';
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(
IN login VARCHAR(64), IN ipa VARCHAR(16), IN properties VARCHAR(255), IN tag VARCHAR(64))
BEGIN
DECLARE usr_mac VARCHAR(16);
SELECT REPLACE(login, ':', '') INTO usr_mac;
CALL set_auth(ipa, CONCAT('mod=dhcp;user=', usr_mac, ';', REPLACE(properties,':','')));
UPDATE mac_uid SET time=UNIX_TIMESTAMP() WHERE ip=INET_ATON(ipa) LIMIT 1;
END$$
DELIMITER ;
Проверяем следующим образом:
SELECT get_ip_by_tag(id_абонента,'тэг_dhcp_пула');
CALL radreply('11:22:33:44:55:66', 'тэг_dhcp_пула');
Если ошибок нет, то все сделано правильно.