Имеем сервер
# uname -sr
FreeBSD 8.1-RELEASE
Установлен
# pkg_info | grep dhcp
isc-dhcp41-server-4.1.1.p1_1,1 The ISC Dynamic Host Configuration Protocol server
BGP роутер по FTP отдает список сетей, которые через него бегают. И стоит задача взять эти сетки и отдать клиентам вместе с динамическим IP список статичных маршрутов. По сути источник маршрутов не столь важен, главное - как настроить DHCP сервер для указания клиентам статичных маршрутов.
Поиски в мануалах, форумах и хэндбуках привели меня к следующему конфигу:
# Описываем опцию №249
option ms-classless-static-routes code 249 = array of unsigned integer 8;
# Описываем подсеть, на которую будем выдавать IP адреса
subnet 192.168.76.0 netmask 255.255.255.0 {
# Описываем диапазон адресов в подсети
range 192.168.76.50 192.168.76.100;
# Задаем адрес ДНС сервера для этой подсети
option domain-name-servers 192.168.76.1;
# Задаем статичные маршруты. В старых версиях сервера нужно было обязательно использовать только 16тиричный вид. В новых можно и десятичный.
# Формат следующий:
# Количество значащих бит в маске, сеть, адрес шлюза для сети. Разделитель - запятая. Все в одну строку.
option ms-classless-static-routes 23,62,33,58,172,31,0,1,24,62,213,32,172,31,0,1,24,62,213,33,172,31,0,1
}
То, что разделитель запятая - не сильно страшно. Лучше было бы, конечно, что бы формат был как для команды route (номер сети - правый слэш - префикс маски - пробел - адрес шлюза), но можно и так, написать скрипт, преобразующий формат к нужному виду не сложно.
Сложнее оказалось с количеством маршрутов. Передаю 31 маршрут и меньше - клиент прекрасно принимает IP и маршруты. Передаю 32 или больше - клиент не получает не только маршруты, но и IP адрес. В чем проблема пока понять не могу.
Вот скрипт, генерирующий конфиг файл. ВНИМАНИЕ!!! Скрипт автоматически перезаписывает конфигурационный файл DHCP сервера и перезапускает DHCP сервер!
#!/usr/bin/perl
use LWP;
#
# Взять список сетей с ftp://172.31.0.1/pub/rtrs
$cUrlListNets="ftp://172.31.0.1/pub/rtrs";
# и отправить их на 172.31. 0.1
$routgw = '172,31,0,1';# Количество отдаваемых маршрутов
$countRoute = 31;$subnet = '192.168.76.0';
$submask = '255.255.255.0';
$ns = '192.168.76.1';
$subrange = '192.168.76.50 192.168.76.100';
$subgw = '192.168.76.1';$routers = '';
$strForDHCP = 'option ms-classless-static-routes';
$cListNets = "nets.txt";
`fetch -o $cListNets $cUrlListNets`;open (LIST, "<$cListNets") or die ("Can`t open ".$cListNets);
$i=0;
while ($l = <LIST>)
{
$i++;
if ( $i <= $countRoute )
{
($net, $x) = split (/ /, $l);
( $okts, $mask) = split ( "/", $net );
( $dec1, $dec2, $dec3, $dec4 ) = split (/\./, $okts);
$rout = "$dec1,$dec2";
if ( '' eq $mask )
{
if ( '' eq $dec4 )
{
if ( '' eq $dec3)
{
$mask = '16';
}
else
{
$mask = '24';
$rout .= ",$dec3";
}
}
}
if ( '' ne $dec3 ) { $rout .= ",$dec3"; }
if ( '' ne $dec4 ) { $rout .= ",$dec4"; }
$routers .= "$mask,$rout,$routgw,";
}
}close (LIST);
`rm $cListNets`;
#
# create new DHCP config file
#chop ( $routers );
open (OUT, ">dhcpd.conf");
print OUT "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n";
print OUT "subnet $subnet netmask $submask {\n";
print OUT " range $subrange;\n";
print OUT " option domain-name-servers $ns;\n";
# print OUT " option routers $subgw;\n";
print OUT " $strForDHCP $routers;\n";
#
print OUT "}\n";
close (OUT);print "RM curr conf\n";
`rm /usr/local/etc/dhcpd.conf`;
print "COPY curr conf\n";
`cp ./dhcpd.conf /usr/local/etc/dhcpd.conf`;
print "RESTART DHCP\n";
`/usr/local/etc/rc.d/isc-dhcpd restart`;
print "RM local conf\n";
`rm ./dhcpd.conf`;
Скрипт не шедевр программирования и созщдавался только для анализа проблемы, в рабочей версии все будет по другому, включая веб-меорду для управления. Сейчас главное понять как преодолеть поблему 32ух маршрутов.
Пока идей нет ни каких. Кроме одной - проблемы на самом деле нет и я просто не вижу свою ошибку.