Что имеем:Два физических хоста, роутер Cisco Systems (модель не важна),
L2-свитчи Cisco Systems.В примере участвуют 3 сабнета, 192.168.0.0/24, 192.168.1.0/24, 10.0.0.0/24,
все они приземляются на роутере на интерфейсах вида vlan*
К роутеру через dot1.q транк подцеплен коммутатор, вланы везде есть (единый VTP-домен).
Два хоста поключены к свитчу, как "чистым" езером, так и транком dot1.qХост А:
192.168.0.2/24
default gw 192.168.0.1
Линк через карточку em0, чистый, не dot1.qem0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=b<RXCSUM,TXCSUM,VLAN_MTU>
inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
ether 00:0e:0c:4e:c0:5c
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
Хост B:
1)192.168.1.2/24
default gw 192.168.1.1
Линк через карточку em0, чистый, не dot1.q
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=b<RXCSUM,TXCSUM,VLAN_MTU>
inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
ether 00:04:23:b2:ef:6e
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
2) 10.0.0.2/24
Линк через каррточку em1, dot1q.
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=b<RXCSUM,TXCSUM,VLAN_MTU>
ether 00:04:23:b2:ef:6f
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
vlan200: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 10.0.0.2 netmask 0xffffff00 broadcast 10.0.0.255
ether 00:04:23:b2:ef:6f
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
vlan: 200 parent interface: em1
Роутинг работает, с хоста "A" адрес 10.0.0.1, живущий на маршрутизаторе, пингуется.
Трассируется через роутер, что тоже правильно.
C хоста "B" адрес 10.0.0.1 тоже пингуется и трассируется, но напрямую, ибо видит его по arp-у, что тоже верно.Известная тема - пингуем с хоста "A" (src 192.168.0.2) адрес - 10.0.0.2, пакеты на хост "А" прилетают через роутер 10.0.0.1, em1 и vlan200, а улетать хотят через em0 и 192.168.1.1, т.к. dst ответа в местной статической таблице отсутствует.
Задача - хотим, чтобы ответы на пакеты, влетевшие через em1 и vlan200 к dst 10.0.0.2, через них же и улетали на роутер 10.0.0.1.
Делаем:
# ipfw 200 add forward 10.0.0.1 log ip from 10.0.0.2 to any
# ipfw list
00200 fwd 10.0.0.1 log ip from 10.0.0.2 to any
65535 allow ip from any to anyПингуем с хоста "А" (src 192.168.0.2) адрес 10.0.0.2.
Все верно, пакеты с 192.168.0.2 через роутер 10.0.0.1 и vlan200 прилетают, как и ожидалось.
tcpdump -i vlan200 host 10.0.0.2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vlan200, link-type EN10MB (Ethernet), capture size 96 bytes
21:36:17.741944 IP 192.168.0.2 > 10.0.0.2: icmp 64: echo request seq 0
21:36:18.748314 IP 192.168.0.2 > 10.0.0.2: icmp 64: echo request seq 1
21:36:19.758305 IP 192.168.0.2 > 10.0.0.2: icmp 64: echo request seq 2
^CТеперь ожидаем, что ответы с src 10.0.0.2 на dst 192.168.0.2 будут форварднуты на хост 10.0.0.1. Причем пойдут эти ответы через vlan200, т.к. адрес 10.0.0.1 мы видим напрямую через vlan200, а не через default:
netstat -rn
Routing tablesInternet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.1.1 UGS 0 24633 em0
10/24 link#1 UC 0 0 vlan20
127.0.0.1 127.0.0.1 UH 0 0 lo0Смотрим логи ipfw:
Oct 23 21:36:17 kernel: ipfw: 200 Forward to 10.0.0.1 ICMP:0.0 10.0.0.2 192.168.0.2 out via em0Ищем ответы на vlan200 tcpdump'ом - не находим.
tcpdump -i vlan200 host 10.0.0.2
А вот на em0 они есть:
tcpdump -i em0 host 10.0.0.2
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on em0, link-type EN10MB (Ethernet), capture size 96 bytes
21:45:27.774342 IP 10.0.0.2 > 192.168.0.2: icmp 64: echo reply seq 0
21:45:28.780577 IP 10.0.0.2 > 192.168.0.2: icmp 64: echo reply seq 1
21:45:29.790563 IP 10.0.0.2 > 192.168.0.2: icmp 64: echo reply seq 2
^CВопрос - а зачем ответы идут через em0 и default 192.168.1.1, если мы их вроде как отфорвардили к 10.0.0.1 и путь к нему, согласно статическим таблицам, лежит через vlan200, т.е. на прямой видимости?
Т.е. очевидно, что я что-то делаю не так, но что - вот вопрос ? :-)
Спасибо за ответы, коллеги ! :-)
Проблема решена - нужно при компиляции ядра
добавить опцию IPFIREWALL_FORWARD_EXTENDEDhttp://groups.google.com/group/mailing.freebsd.ipfw/browse_t...
http://groups.google.com/group/mailing.freebsd.net/browse_th...
Теперь все работает именно так, как и задумано.