FreeBSD

Материал из gptel_wiki
Перейти к: навигация, поиск

rc.conf

Статические маршруты

static_routes="gp" 
route_gp="-net 192.168.128.0/22 10.1.1.1"

Алиасы на vlan

cloned_interfaces="vlan80 vlan81"
ifconfig_vlan80="inet 192.168.168.10 netmask 255.255.255.0 vlan 80 vlandev em2"
ifconfig_vlan80_alias0="alias 192.168.168.11 netmask 255.255.255.0"
ifconfig_vlan81="inet 192.168.169.10 netmask 255.255.255.0 vlan 81 vlandev em2"
ifconfig_vlan81_alias0="alias 192.168.169.11 netmask 255.255.255.0"

при этом не забываем
echo 'ifconfig em2 up' >> /etc/rc.local

sysctl.conf

kern.coredump=0 
net.inet6.ip6.auto_linklocal=0

raid1

Памятка о настройки RAID-1 поверх уже установленной FreeBSD версии 9 или 10. Неоднократно проверенный способ, когда используется именно GPT разметка. В примере будет создан RAID-1 массив, он же зеркало, из всех разделов на основном диске. Т.е. зеркалируются именно разделы, а не полностью диск.

1. Загружаем в shell FreeBSD с LiveCD.

2. Просматриваем имеющиеся разделы:

gpart show freebsd_gpart_show

Пример автоматической разбивки диска установщиком bsdinstall

3. Копируем таблицу разделов исходного диска на второй:

gpart backup ada0 | gpart restore -F /dev/ada1 4. Делаем второй диск возможным для загрузки:

gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1 5. Создаем зеркало каждого из разделов и загружаем gmirror:

gmirror label -vb round-robin boot /dev/ada0p1 gmirror label -vb round-robin root /dev/ada0p2 gmirror label -vb round-robin swap /dev/ada0p3 gmirror load 6. Просмотр состояния:

gmirror status freebsd_gmirror_status 7. Монтируем корневой раздел, делаем резервную копию файла fstab и редактируем оригинал с помощью «ee»:

mount -rw /dev/mirror/root /mnt cp /mnt/etc/fstab /mnt/etc/fstab_original ee /mnt/etc/fstab Было: freebsd_fstab_original Стало: freebsd_fstab_new 8. Тут же, можно настроить ssh доступ для root, если необходимо, или другие необходимые настройки:


ee /mnt/etc/ssh/sshd_config 9. Обязательно добавляем загрузку GEOM:

echo 'geom_mirror_load="YES"' >> /mnt/boot/loader.conf 10. Размонтируем диск и перезагружаемся в установленную ОС:

umount /mnt reboot 11. Добавляем зеркала для каждого из разделов:

gmirror insert boot /dev/ada1p1 gmirror insert root /dev/ada1p2 gmirror insert swap /dev/ada1p3 12. Проверяем статус синхронизации:

gmirror status


gmirror + GPT

Источник [[1]]

  1. gmirror label -v -b round-robin gm0 /dev/ad0\\
  2. gmirror load\\
  1. gpart create -s gpt mirror/gm0\\
  2. gpart add -t freebsd-boot -s 128k mirror/gm0\\
  3. gpart add -t freebsd-ufs -s 1G mirror/gm0\\
  4. gpart add -t freebsd-swap -s 4G -l swap mirror/gm0\\
  5. gpart add -t freebsd-ufs -s 1G mirror/gm0\\
  6. gpart add -t freebsd-ufs -s 4G mirror/gm0\\
  7. gpart add -t freebsd-ufs -s 20G mirror/gm0\\
  8. gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 mirror/gm0\\
  1. newfs -L rootfs /dev/mirror/gm0p2\\
  2. newfs -L tmpfs /dev/mirror/gm0p4\\
  3. newfs -L varfs /dev/mirror/gm0p5\\
  4. newfs -L usrfs /dev/mirror/gm0p6\\
  1. mkdir /mnt/root; mkdir /mnt/var; mkdir /mnt/usr\\
  2. mount /dev/ufs/rootfs /mnt/root\\
  3. mount /dev/ufs/varfs /mnt/var\\
  4. mount /dev/ufs/usrfs /mnt/usr\\
Либо с нуля создаем\\
  1. cd /usr/src\\
  2. make DESTDIR=/mnt installworld distribution installkernel KERNCONF="YOUR_KERNEL_HERE"\\
Либо копируем существующую систему\\
  1. cd /; pax -p eme -X -rw . /mnt/root\\
  2. cd /var; pax -p eme -X -rw . /mnt/var\\
  3. cd /usr; pax -p eme -X -rw . /mnt/usr\\
  1. echo 'geom_mirror_load="YES"' >> /mnt/root/boot/loader.conf\\
  2. echo 'vfs.root.mountfrom="ufs:/dev/ufs/rootfs"' >> /mnt/root/boot/loader.conf\\
  1. cat > /mnt/root/etc/fstab\\
  2. Device Mountpoint FStype Options Dump Pass#\\

/dev/gpt/swap none swap sw 0 0\\ /dev/ufs/rootfs / ufs rw 1 1\\ /dev/ufs/usrfs /usr ufs rw 2 2\\ ^D\\

shutdown -r now

Убираем текущий загрузочный диск, делаем загрузочным созданый.

  1. chmod 1777 /tmp

fail2ban

test


Shell-программирование

Автор: iNo // k0dsweb gr0up Статья является собственностью команды KodsWeb (www.kodsweb.ru) -= 06.09.2006 =-

Intro...

В данной статье я вкратце опишу shell-программирование, рассмотрю простейшие примеры и прокомментирую их. Сразу оговорюсь,что эта статья не является исчерпывающим руководством по shell-программированию. Но её будет достаточно чтобы освоить его основы. Несмотря на кажущуюся простоту shell-программирования, оно является достаточно мощным инструментом администратора unix-системы.Замечу,что для полноценного администрирования unix-системы, уметь программировать на shell просто необходимо. Все примеры протестированы на системе Slackware Linux 10.2 и полностью работоспособны.

Общие положения.

Комментарии начинаются с символа #, за исключением первой строки. Первой строкой сценария является путь к интерпретатору, начинающийся с #! с помошью которого будет запущен данный скрипт. Например:


       #!/bin/sh
       #А вот это уже комментарий

Переменные, ввод и вывод данных.

Для задания переменных используется оператор присваевания "=". Синтаксис следующий:


       <переменная>=<значение>

Замечу,что в отличие от языков perl и php,между знаком "=" и остальными параметрами нельзя ставить пробел.В этом случае интерпретатор выдаст ошибку.Чтобы обратится к заданной переменной ,надо вызвать её поставив перед ней знак $.Удалить переменную можно с помощью оператора unset. Оператор Echo просто выводит строку(или переменную), идущую после него:


       #!/bin/sh
       var=Vasya
       echo $var
       >--------------------------------------<
       Vasya
       >--------------------------------------<
       #!/bin/sh
       echo My name is Vasya
       >--------------------------------------<
       My name is Vasya
       >--------------------------------------<

В данный пример также можно добавить одинарные или двойные кавычки, от этого результат работы программы не изменится. Но не стоит использовать обратные кавычки, т.к.эти символы используются для выполнения команд:


       #!/bin/sh
       echo `My name is Vasya"
       >--------------------------------------<
       Error: My: command not found
       >--------------------------------------<
       #!/bin/sh
       echo 'ls -a'
       >--------------------------------------<
       . .. .bash_history script.sh
       >--------------------------------------<

Оператор read присваевает значение переменной.Вот пример,который просит ввести переменную var,считывает её а затем выводит.


       #!/bin/sh
       echo "Input var:"
       read var
       echo "The var is $var"
       >--------------------------------------<
       Input var:
       123
       The var is 123
       >--------------------------------------<

Агрументы командной строки.

Как и во всех консольных программах, в shell-сценарий можно передавать аргументы из командной строки.Переменные $1..$9 соответствуют параметрам, переданным из командной строки сценарию.Переменная $0 содержит имя интерпретируемого файла.$#-содержит количество переданных аргументов. $* и $@ содержат все аргументы,но в $@ все аргументы выделены кавычками. Напишем скрипт,который выводит 2 аргумента командной строки и имя исполняемого файла.Запуск скрипта: ./script.sh 1 2


       #!/bin/sh
       echo "Name:$0"
       echo "First argument:$1"
       echo "Second argument:$2"
       >--------------------------------------<
       Name:./script.sh
       First argument:1
       Second argument:2
       >--------------------------------------<

Арифметические операции.

Арифметические операции производятся с использованием оператора let. Операции:


  • - умножение

/ - деление + - сложение - - вычитание % - деление с остатком

Синтаксис арифметических операций в Shell:


       let <значение> <оператор> <значение>


Пример sh let:


       #!/bin/sh
       let res=2*7
       echo $res
       >--------------------------------------<
       14
       >--------------------------------------<

Оператор test или [].

Данные операторы предназначены для выполнения сравнений двух значений. Если сравнение успешно-оператор возвращает 0,иначе 1.Код завершения последней выполненной команды хранится в специальной переменной $?.


Синтаксис оператора test:


       test <значение> -опция <значение>

или

       [<значение> -опция <значение>]

Пример:

       #!/bin/sh
       var=10
       [ $var -eq 8 ]
       echo $?
       >--------------------------------------<
       1
       >--------------------------------------<


Ниже приведены все опции оператора test(или []):

Сравнение целых чисел:

-gt больше чем -lt меньше чем -ge больше чем либо равно -le меньше чем либо равно -eq равно -ne не равно Сравнение строк:

-z проверка на наличие пустой строки -n проверка на наличие строки-значения = равенство != неравенство str проверка на наличие строки,состоящей из нулей Логические операции:

-a И -o ИЛИ ! НЕ Проверка файлов:

-f установка факта существования файла и его регулярности -s проверка,не является-ли файл пустым -r проверка возможности считывания файла -w проверка возможности записи файла -x проверка исполняемости файла -d проверка,является-ли файл каталогом -h проверка,является-ли файл ссылкой -c проверка,является-ли файл байт-ориентированным устройством -d проверка,является-ли файл блок-ориентированным устройством Условия.

Ниже описан синтаксис всех условных операторов, с примерами.

1) if <команда> then <команда> fi

Пример условия if ... then:


       #!/bin/sh
       if [ $1 -eq 10 ]; then
           echo var=10
       fi

Результат работы,при переданном параметре равном 10:


       >--------------------------------------<
       var=10
       >--------------------------------------<


2) if <команда> then <команда> else <команда> fi

Пример if ... then ... else:


       #!/bin/sh
       if [ $1 -eq 10 ]; then
           echo var=10
       else
           echo var!=10
       fi

Результат работы,при переданном параметре равном 10:


       >--------------------------------------<
       var=10
       >--------------------------------------<


Результат работы,при переданном параметре равном 7:


       >--------------------------------------<
       var!=10
       >--------------------------------------<


3) if <команда> then <команда> elif <команда> else <команда> fi

Пример if ... then ... elif ... else:


       #!/bin/sh
       if [ $1 -eq 10 ]; then
           echo var=10
       elif [ $1 -eq 9 ]; then
           echo var=9
       else
           echo var!=10 and var!=9
       fi

Результат работы,при переданном параметре равном 10:


       >--------------------------------------<
       var=10
       >--------------------------------------<

Результат работы,при переданном параметре равном 9:


       >--------------------------------------<
       var=9
       >--------------------------------------<

Результат работы,при переданном параметре равном 8:


       >--------------------------------------<
       var!=10 and var!=9
       >--------------------------------------<

4) case <строка> in <шаблон>) <команды> ;; *) <команды> ;; esac

Case-конструкция позволяет выбирать один из нескольких альтернативных вариантов.


       #!/bin/sh
       case $1 in
       1)
       echo arg is 1
       ;;
       2)
       echo arg is 2
       ;;
       *)
       echo arg is other
       ;;
       esac


Результат работы,при переданном параметре равном 1:


       >--------------------------------------<
       arg is 1
       >--------------------------------------<

Результат работы,при переданном параметре равном 2:


       >--------------------------------------<
       arg is 2
       >--------------------------------------<

Результат работы,при переданном параметре равном 10:


       >--------------------------------------<
       arg is other
       >--------------------------------------<

Циклы.

1) while <условие> do <команды> done

Оператор языка shell-программирования while выполняет команды, пока условие истино. Пример:


       #!/bin/sh
       cont=yes
       while [ $cont = yes ]
       do
       echo -n "continue?"
       read cont
       done
       >--------------------------------------<
       continue?
       yes
       continue?
       no
       >--------------------------------------<


2) until <условие> do <команды> done

Оператор until выполняет команды, пока условие ложно. Пример:


       #!/bin/sh
       cont=yes
       until [ $cont = no ]
       do
       echo -n "continue?"
       read cont
       done
       >--------------------------------------<
       continue?
       yes
       continue?
       no
       >--------------------------------------<


3) for <переменная> do <команды> done

Цикл for - выполняет команды для каждого параметра, который был передан сценарию в командной строке. Пример:


       #!/bin/sh
       for var
       do
       echo $var
       done

Результат работы программы,с параметрами 1 2 3 4 5:


       >--------------------------------------<
       1
       2
       3
       4
       5
       >--------------------------------------<

4) for <переменная> in <строка> do <команды> done Эта конструкция отличается от обычного for тем, что параметры берутся не из командной строки, а из строки после оператора in.

5) select <строка> in <перечень элементов> do <команды> done Конструкция select создаёт меню на основе элементов заданного списка, а затем выполняет для него указанную команду. Пример:


       #!/bin/sh
       select var in 1 2 3
       do
       case $var in
       1)
       echo Number 1
       ;;
       2)
       echo Number 2
       ;;
       3)
       echo Number 3
       ;;
       *)
       echo Other
       ;;
       esac
       done
       >--------------------------------------<
       1) 1
       2) 2
       3) 3
       #? 3
       Number 3
       #? _
       >--------------------------------------<

Оригинал статьи http://www.opennet.ru/base/dev/shell_coding.txt.html

IPFW PIPE

options DUMMYNET	;Шейпер
options HZ=1000	;Частота системного таймера, (1000=1ms,100=10ms,0=NO!)

net.inet.ip.fw.one_pass: 1	;Заставляет напрямую поток из dummynet идти в большой мир минуя последующие правила файрвола
net.inet.ip.fw.one_pass: 0	;Заставляет идти выходящий поток из dummynet  далее по правилам
ipfw pipe NNN config bw B delay D queue Q plr P

NNN Номер полосы

bw		Ширина полосы					;{K | M}{bit/s | Bytes/s}

delay		Велечина задержки				;(ms)

queue		Размер очереди					;(slots,Bytes)

weight		Вес/приоритет очереди				;( [1..100], default =1! 1-min 100-max )

pipe		Канал для связи с очердью или очередями		;

plr		Доля потеряных пакетов случайным образом	;( 0,0..1,0] 0 =100%pass, 1 =100%reject)

mask		Группировка по маске				;(dst-ip, src-ip, dst-port, src-port, proto, all)

red | gred 	Выполняет алгоритм управления очередью RED	;(w_q/min_th/max_th/max_p)
								;w_q - вес очереди
								;min_th - минимальный порог
								;max_th - максимальный порог
								;max_p - максимальная вероятность отбрасывания пакета
								;w_q и max_p 		( !=0..1] )
								;min_th и max_th	(slots,Bytes)

При использовании алгоритма Random Early Detection (RED): Если уровень перегрузки* находится между порогами min_th и max_th, пакеты отбрасываются с линейно возрастающей вероятностью от 0 до max_p, которая достигается при достижении второго порога (max_th). Когда перегрузка выше второго порога, все пакеты отбрасываются.

При использовании алгоритма Gentle RED (GRED): Если уровень перегрузки* находится между порогами min_th и max_th, пакеты отбрасываются с линейно возрастающей вероятностью от 0 до max_p. Когда уровень перегрузки больше max_th, но меньше 2*max_th, то пакеты отбрасываются не все, как в случае с RED, а с линейно возрастающей вероятностью от max_th до 1. Все пакеты отбрасываются только после превышения значения уровня перегрузки канала 2*max_th.

Время заполнения очереди или время задержки при стандартном значении MTU (1500) определяется:

T=(MTU*byte*Q)/L (сек)

где: MTU - значение MTU; byte - 8 бит, чтобы перевести в биты, так как MTU в байтах Q - размер очереди в слотах; L - пробускная способность канала, бит/с.

Получаем что-то типа: T=(1500*8*Q)/L

Далее, если мы хотим чтобы при канале шириной в 256Kbit/s задержки не привышали 100ms, можем расчитать Q!

Мой канал 256Kbit/s -> 256*1024bit/s PPPOE(MTU) 1500 -> 1492 100ms/1000c=0,1ms

Q=(T*L)/(MTU*byte)

Получаем, при <=100ms Q=(0,1s*262144bit/s)/(1492*8)=26214,4/11936=~2,1=2слота

Получаем, при <=200ms Q=(0,2s*262144bit/s)/(1492*8)=52428,8/11936=~4,3=4слота

Получаем, при <=500ms Q=(0,5s*262144bit/s)/(1492*8)=131072/11936=~10,9=10слотов

Получаем, при <=1s Q=(1s*262144bit/s)/(1492*8)=262144/11936=~21,9=21слот

DUMMYNET позволяет установить очередь до 100 слотов, но округлем в меньшую сторону, дабы не вылазить за рамки и не получать отбрасываемых пакетов.

При нашем расчёте время задержки, при <=0,1s: T=(MTU*byte*Q)/L, при 0,1s; T=(1492*8*2)/262144=23872/262144=0,091c при 0,2s; T=(1492*8*4)/262144=47744/262144=0,182c при 0,5s; T=(1492*8*10)/262144=119360/262144=0,455c при 1s; T=(1492*8*21)/262144=250656/262144=0,956c

Для алгоритма RED или GRED расчитаем нижний порог: min_th=(T*L)/(MTU*byte) (слотов) min_th=(0,1*262144)/(1492*8)=26214,4/11936=~2,1=2слота, как у нас уже расчитано выше.

Теперь расчитаем верхний порог: max_th=(2..5)*min_th(слотов),возьмём среднее 3 max_th=3*2=6слотов, верхний порог, при задержки в 0,1s max_th=3*4=12слотов, верхний порог, при задержки в 0,2s max_th=3*10=30слотов, верхний порог, при задержки в 0,5s max_th=3*21=63слотa, верхний порог, при задержки в 1s

Далее нам нужно уровень перегрузки канала, при котором все пакеты будут отбрасываться: Q=2*max_th, Q=2*6=12слотов, при задержки в 0,1s Q=2*12=24слотов, при задержки в 0,2s Q=2*30=60слотов, при задержки в 0,5s Q=2*63=126слотов, при задержки в 1s - ???Получаем лажу! DUMMYNET способен только на 100слотов

Получаем следующие правила ipfw pipe 1 config bw 256Kbit/s queue 12 gred 0.002/2/6/0.1 ipfw pipe 2 config bw 256Kbit/s queue 24 gred 0.002/4/12/0.1

ipfw pipe4 config bw 256Kbit/s queue 126 gred 0.002/21/63/0.1 - ?! Но попробовать стоит ж;) ipfw: 2 <= queue size <= 100 ;Вот такая ругань получилась )))

И три трубы которые принял ipfw образовали:

00001: 256.000 Kbit/s 0 ms 12 sl. 0 queues (1 buckets) ;Пакеты бьються

 GRED w_q 0.001999 min_th 2 max_th 6 max_p 0.099991

00002: 256.000 Kbit/s 0 ms 48 sl. 0 queues (1 buckets) ;Средний вариант

 GRED w_q 0.001999 min_th 4 max_th 12 max_p 0.099991

00003: 256.000 Kbit/s 0 ms 60 sl. 0 queues (1 buckets) ;Слишком большой pipe?!

 GRED w_q 0.001999 min_th 10 max_th 30 max_p 0.099991

Так же можно вполне задать очередь в KBytes не только в слотах и очередь не должна привышать ширину канала, иначе будет куча битых пакетов. По советам её бы уменьшить процентов на 5%-10%. 256/8=32Kbytes/s, (32/100%)*5%=3,2=~4Kbytes, 32-4=28Kbytes, ipfw pipe 1 config bw 256Kbit/s queue 28Kbytes

Так же окружающие советуют: w_q=0.002/min_th=(queue/10)/max_th=(3*min_th)/max_p=0.1, при queue 30 слотах

Теперь к экспериментам! ... из всего что я понял и усвоил, я планирую: 1. создать 2 трубы pipe 1,2 и сделать честное деление канала по скорости между пользователям, типа: local->GW и GW<-local

2. создать 2 трубы и сделать 2 очереди для входящего и исходящего траффика типа GW->inet и inet<-GW с алгоритмом GRED, для предотвращения перегрузок

Результат при 256Kbit/s pipe 10 config bw 256Kbit/s queue 12 0.002/2/6/0.1 ~23.29 Kbytes/sec pipe 10 config bw 256Kbit/s queue 24 0.002/2/8/0.1 ~23.73 Kbytes/sec pipe 10 config bw 256Kbit/s queue 24 0.002/3/12/0.1 ~26.37 Kbytes/sec pipe 10 config bw 256Kbit/s queue 30 0.002/3/15/0.1 ~22.24 Kbytes/sec pipe 10 config bw 256Kbit/s queue 48 0.002/8/24/0.1 ~26.66 Kbytes/sec pipe 10 config bw 256Kbit/s queue 60 0.002/10/30/0.1 ~27.19 Kbytes/sec pipe 10 config bw 256Kbit/s queue 100 0.002/33/50/0.1 ~22.99 Kbytes/sec То что народ насоветовал ;) pipe 10 config bw 256Kbit/s queue 30 0.002/3/9/0.1 ~24.46 Kbytes/sec

В итоге написал такие правила:

  1. BANDWISH (PIPE & QUEUE)
  1. NO_PASS_ALL_AFTER_BANDWISH

sysctl net.inet.ip.fw.one_pass=0

  1. FLUSH

ipfw -f flush ipfw -f pipe flush ipfw -f queue flush

  1. CONFIG & ADD RULES

ipfw add pass ip from localhost to localhost via lo0

ipfw pipe 1 config bw 256Kbit/s ipfw queue 11 config pipe 1 mask src-ip 0xffffffff ipfw add queue 11 ip from 192.168.0.0/16 to any in via bfe0 ipfw add pass ip from 192.168.0.0/16 to any in via bfe0

ipfw pipe 2 config bw 256Kbit/s ipfw queue 22 config pipe 2 mask dst-ip 0xffffffff ipfw add queue 22 ip from any to 192.168.0.0/16 out via bfe0 ipfw add pass ip from 192.168.0.0/16 to any out via bfe0

ipfw pipe 3 config bw 256Kbit/s #queue 60 gred 0.002/10/30/0.1 ipfw add pipe 3 ip from 92.255.254.17 to any out via tun0 ipfw add pass ip from 92.255.254.17 to any out via tun0

ipfw pipe 4 config bw 256Kbit/s #queue 60 gred 0.002/10/30/0.1 ipfw add pipe 4 ip from any to 92.255.254.17 in via tun0 ipfw add pass ip from any to 92.255.254.17 in via tun0

В случае чего можно расскоментировать #queue 60 gred 0.002/10/30/0.1 Для сглаживания шороховатостей, но а пока я не увидел битых пакетов.

gw2# ipfw pipe show 00001: 256.000 Kbit/s 0 ms 50 sl. 0 queues (1 buckets) droptail 00002: 256.000 Kbit/s 0 ms 50 sl. 0 queues (1 buckets) droptail 00003: 256.000 Kbit/s 0 ms 50 sl. 1 queues (1 buckets) droptail

   mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000

BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp

 0 udp    92.255.254.17/57095    91.144.152.3/53    5644   533762  0    0   0

00004: 256.000 Kbit/s 0 ms 50 sl. 1 queues (1 buckets) droptail

   mask: 0x00 0x00000000/0x0000 -> 0x00000000/0x0000

BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp

 0 udp     91.144.152.3/53      92.255.254.17/57095 6154  7809516  0    0   0

q00022: weight 1 pipe 2 50 sl. 5 queues (64 buckets) droptail

   mask: 0x00 0x00000000/0x0000 -> 0xffffffff/0x0000

BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp

23 ip           0.0.0.0/0       192.168.10.71/0       21     4136  0    0   0
27 ip           0.0.0.0/0       192.168.1.203/0     7756  8079804  0    0   0
44 ip           0.0.0.0/0       192.168.5.124/0      385   158515  0    0   0
47 ip           0.0.0.0/0       192.168.1.255/0       11     1294  0    0   0
56 ip           0.0.0.0/0       192.168.1.104/0      135    43137  0    0   0

q00011: weight 1 pipe 1 50 sl. 11 queues (64 buckets) droptail

   mask: 0x00 0xffffffff/0x0000 -> 0x00000000/0x0000

BKT Prot ___Source IP/port____ ____Dest. IP/port____ Tot_pkt/bytes Pkt/Byte Drp

 4 ip      192.168.1.22/0             0.0.0.0/0        5      541  0    0   0
 8 ip     192.168.1.112/0             0.0.0.0/0        4      476  0    0   0
12 ip      192.168.1.18/0             0.0.0.0/0        1      229  0    0   0
16 ip     192.168.5.124/0             0.0.0.0/0      407    30272  0    0   0
26 ip      192.168.1.25/0             0.0.0.0/0        1      229  0    0   0
38 ip     192.168.1.103/0             0.0.0.0/0        3      404  0    0   0
52 ip      192.168.1.14/0             0.0.0.0/0        1      229  0    0   0
56 ip     192.168.1.104/0             0.0.0.0/0      147    65848  0    0   0
58 ip       192.168.1.9/0             0.0.0.0/0      223    17556  0    0   0
60 ip      192.168.1.10/0             0.0.0.0/0        1      234  0    0   0
62 ip     192.168.1.203/0             0.0.0.0/0     5775   833667  0    0   0

Продолжение с поправкой... с перемусоливанием выше изложенного.

http://rrv.jino-net.ru/wiki/index.php/QoS_FreeBSD Для лучшего понимания что к чему... Взято по ссылке и отдельное спасибо Николаю Ананину за некое объяснение непонятных мною моментов в расчётах.

И так в моём случае с каналом в 256Kbit/s: QUEUE_TOTA L= MTU*QUEUE_SIZE = (1492*8)*50 = 11936*50 = 596800 бит где, MTU = 1492 байт * 8 = 11936 бит QUEUE_SIZE = количество слотов(пакетов) или байтах (по умолчанию 50)

Время задержки получаем из T = QUEUE_SIZE/BANDWIDTH = 596800/262144 = ~2,276 секунды. где, BANDWIDTH = 256 * 1024 = 262144 бит

НО! ~2 сек. слишком большая задержка, нам нужно хотябы 0,5 сек. ~2 сек / 0,5 сек = 4 Наш QUEUE_SIZE = 50 / 4 = 12,5 = ~12 слотов для задержки в 0,5 сек.

Можем даже больше. Можем расчитать gred: max_th = 12/2 = 6 min_th = 6/3 = 2

Получаем правила: ipfw pipe 1 config bw 256Kbit/s queue 12 ipfw queue 1 config pipe 1 mask dst-ip 0xffffffff ipfw add queue 1 ip from any to 192.168.0.0/16 out via bfe0 ipfw add pass ip from 192.168.0.0/16 to any out via bfe0

Или правила с gred: ipfw pipe 1 config bw 256Kbit/s queue 12 gred 0.002/2/6/0.1 ipfw queue 1 config pipe 1 mask dst-ip 0xffffffff ipfw add queue 1 ip from any to 192.168.0.0/16 out via bfe0 ipfw add pass ip from 192.168.0.0/16 to any out via bfe0

Промежуточный вариант... плох... в нём нету pipe не умеет weight ipfw pipe 1 config bw 256Kbit/s mask dst-ip 0xffffffff queue 12 gred 0.002/2/6/0.1 ipfw add pipe 1 ip from any to 192.168.0.0/16 out via bfe0

Остановился на этом. ж;) ipfw pipe 1 config bw 256Kbit/s ipfw queue 1 config pipe 1 weight 50 mask dst-ip 0xffffffff queue 12 gred 0.002/2/6/0.1 ipfw add queue 1 ip from any to 192.168.0.0/16 out via bfe0 ipfw add pass ip from any to 192.168.0.0/16 out via bfe0

Работает как часы! Всё можно глядеть чрез iftop sh# iftop -i bfe0

                                  195Kb                               391Kb                               586Kb                               781Kb                          977Kb

gw2.fortd.ru => 192.168.5.124 118Kb 128Kb 125Kb gw2.fortd.ru => 192.168.5.38 127Kb 122Kb 125Kb gw2.fortd.ru => blackhole.fortd.ru 0b 0b 113b gw2.fortd.ru => 192.168.5.85 0b 0b 58b 192.168.1.255 => 192.168.1.203 0b 0b 0b 192.168.1.255 => 192.168.1.9 0b 0b 0b 255.255.255.255 => 169.254.2.2 0b 0b 0b


TX: cumm: 16.7MB peak: 253Kb rates: 245Kb 250Kb 250Kb RX: 953KB 13.1Kb 5.55Kb 5.91Kb 6.92Kb TOTAL: 17.6MB 263Kb 251Kb 256Kb 257Kb

Наконец-то канал поделился как хотелось!!!