May. 8th, 2015

victor_sudakov: (Default)
Возникла необходимость сделать подручными средствами L2 tunnel over IP, пропускающий любой Ethernet трафик, в том числе служебные кадры. Сначала пробовал сделать, как описано в if_bridge(4): через gif-туннель, а gif0 и vr0 собрал в bridge. Не проходят STP BPDUs.

Сделал UDP туннель с помощью net/vtun, а в бридж собрал vr0 и tap0. Опять не проходят STP BPDUs на другую сторону. Значит дело в if_bridge, именно он не пропускает BPDU, придется от него отказаться.

Решил делать через netgraph, соединил vr0:lower и ksocket. Оказывается, ng_ether снимает с поступившего кадра 802.1q тэг, таким образом все кадры, на этой стороне принадлежавшие разным vlan, на другой стороне оказываются в одном нетэгированном vlan. Кроме этого, при соединении непосредственно ng_ether и ksocket через этот интерфейс уже не поуправляешь хостом, а хотелось бы. Значит придется задействовать ng_bridge для обеспечения управления и ng_vlan для сортировки кадров по vlan-ам. Слава Богу, ng_bridge не знает про STP и поэтому не фильтрует BPDU.

В показанной на рисунке конфигурации vlan38 не только передается на другую сторону, но и используется для управления хостом, а vlan3 и нетэгированный трафик передаются на другую сторону напрямую:

netgraph1

Недостаток данной конструкции в том, что любой vlan, отличный от 3 и 38, будет отправлен в untagged_socket и отправлен на ту сторону с потерей информации о тэге. Поэтому надо следить, чтобы в данный туннель не попадали vlan, которые не должны туда попадать.

И наконец сам скрипт для netgraph.
#!/bin/sh

kldstat -q -m ng_ether || kldload ng_ether || exit 3

self=10.x.x.x
peer=10.y.y.y

port01=7701
port38=7738
port03=7703

if=vr0

case "$1" in
        start)
            echo "Starting netgraph switch."
            ngctl mkpeer ${if}: vlan lower downstream
            ngctl name ${if}:lower vlan

            ngctl mkpeer vlan: ksocket nomatch inet/dgram/udp
            ngctl name vlan:nomatch untagged_socket
            ngctl msg untagged_socket: bind inet/${self}:${port01}
            ngctl msg untagged_socket: connect inet/${peer}:${port01}

            ngctl mkpeer vlan: ksocket vlan3 inet/dgram/udp
            ngctl name vlan:vlan3 vlan3_socket
            ngctl msg vlan: addfilter '{ vlan=3 hook="vlan3" }'
            ngctl msg vlan3_socket: bind inet/${self}:${port03}
            ngctl msg vlan3_socket: connect inet/${peer}:${port03}

            ngctl mkpeer vlan: bridge vlan38 link0
            ngctl name vlan:vlan38 sw
            ngctl connect ${if}: sw: upper link1
            ngctl mkpeer sw: ksocket link2 inet/dgram/udp
            ngctl name sw:link2 vlan38_socket
            ngctl msg vlan: addfilter '{ vlan=38 hook="vlan38" }'
            ngctl msg vlan38_socket: bind inet/${self}:${port38}
            ngctl msg vlan38_socket: connect inet/${peer}:${port38}


            ngctl msg ${if}: setpromisc 1
            ngctl msg ${if}: setautosrc 0
            ngctl msg sw: setconfig '{ debugLevel=1 loopTimeout=60 maxStaleness=60 minStableAge=1 }'

            echo "Ok."
            exit 0
            ;;
        stop)
            echo "Stopping netgraph switch."
            ngctl shutdown vlan38_socket:
            ngctl shutdown vlan3_socket:
            ngctl shutdown untagged_socket:
            ngctl shutdown sw:
            ngctl shutdown vlan:
            ngctl shutdown ${if}:
            echo "Ok."
            exit 0
            ;;
        restart)
            sh $0 stop
            sh $0 start
            ;;
        *)
            echo "Usage: `basename $0` { start | stop | restart }"
            exit 64
            ;;
esac


Если кто подскажет способ сделать так, чтобы неизвестные скрипту vlan-ы просто отфильтровывались вместо попадания в untagged_socket, буду благодарен.

Profile

victor_sudakov: (Default)
Виктор Судаков

December 2024

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 15th, 2025 07:19 am
Powered by Dreamwidth Studios