Виртуальный свич с netgraph

27 Ноя
2008

Раз уже начали в предыдущей записи с узла ng_bridge, то разберем подробнее его в работе, соединив вместе несколько Ethernet сетей при помощи виртуального свича.

В /usr/share/examples/netgraph/ether.bridge находится скрипт, который можно использовать в качестве примера, а после некоторой доводки и для организации подобной функции. Если настройки выполняются удаленно при помощи SSH, то после выполнения ряда команд соединение может прерваться.
Для управления netgraph применяются две утилиты: ngctl и nghook. Первая более функциональна, поэтому в дальнейшем будем использовать именно ее.

ngctl_options

ngctl_options

Для начала проверим, какие узлы уже созданы в системе:

# ngctl list
There are 1 total nodes:
Name: ngctl850 Type: socket ID: 00000001 Num hooks: 0

В списке нужных нам нет, поэтому загружаем модули вручную:

# kldload -v ng_ether
Loaded ng_ether, id=5
# kldload -v ng_bridge
Loaded ng_bridge, id=6

Проверяем:

# kldstat
Id Refs Address Size Name

3 1 0xc3574000 4000 ng_socket.ko
4 3 0xc3578000 b000 netgraph.ko
5 1 0xc35ad000 4000 ng_ether.ko
6 1 0xc35b1000 4000 ng_bridge.ko

Для их автоматической загрузки добавляем в /boot/loader.conf следующие строки:

$ sudo vi /boot/loader.conf

netgraph_load=»YES»
ng_ether_load=»YES»
ng_bridge_load=»YES»

Теперь смотрим список узлов еще раз:

# ngctl list

There are 3 total nodes:
Name: ngctl863 Type: socket ID: 00000004 Num hooks: 0
Name: le1 Type: ether ID: 00000003 Num hooks: 0
Name: le0 Type: ether ID: 00000002 Num hooks: 0

Если ввести «ifconfig | grep le», то обнаружим, что имена Ethernet интерфейсов совпадают именем nodes, то есть le0 и le1. Создаем бридж и подключаем его хуком link0 к le0 на нижнем (lower) уровне.

# ngctl mkpeer le0: bridge lower link0

Параметр name команды ngctl позволяет дать имя созданному узлу:

# ngctl name le0:lower bnet0

ng_ether

ng_ether

Обратите внимание, что к узлу обращаемся по имени «le0:lower«, а к созданному узлу bnet0 – «bnet0:«. Вывод «ngctl list» должен показать наличие нового узла с именем bnet0 и типом bridge. Собираем все в кучу (le0 и link0 использовать нельзя, так как они уже задействованы):

# ngctl connect le1: bnet0: lower link1

Аналогично, используя крючки link2 и link3, соединяем le* с bnet0 по верхнему уровню:

# ngctl connect le0: bnet0: upper link2
# ngctl connect le1: bnet0: upper link3

Активируем на сетевых картах неразборчивый (promisc) режим, отправив сообщение setpromisc с любым не нулевым значением (все сообщения описаны в ng_ether(4)):

# ngctl msg le0: setpromisc 1
# ngctl msg le1: setpromisc 1

Запрещаем модификацию исходного Ethernet адреса принятого фрейма, иначе исходный адрес будет переписан на адрес интерфейса, который его получил:

# ngctl msg le0: setautosrc 0
# ngctl msg le1: setautosrc 0

Мост готов. Для удобства все эти команды следует записать в файл, который выполняется во время загрузки системы. При желании также можно обеспечить фильтрацию пакетов. Для этого в netgraph есть два модуля: ng_bpf и ng_ipfw, реализующие возможности соответствующих пакетных фильтров.

Комментировать

Наверх